Azure CLI — Powering the Enterprise Assistant

Research Brief · Prepared by Chief · March 12, 2026

Topics: Azure CLI · Microsoft Graph CLI · Container Apps · M365 Automation · Enterprise Assistant Architecture

There are actually two separate CLI tools that matter here, and they cover completely different layers of our stack. Understanding both is what unlocks the full picture.

az Azure CLI

Layer: Infrastructure

Manages the Azure platform itself — Container Apps, Key Vault, App Registrations, ACR, networking, AI services. This is how we deploy, update, monitor, and scale the enterprise assistant.

brew install azure-cli

mgc Microsoft Graph CLI

Layer: M365 Data

Manages Microsoft 365 services — mail, calendar, OneDrive, Teams, users, contacts. This is the assistant's actual capabilities layer — how it reads email, checks calendars, and manages files.

dotnet tool install --global Microsoft.Graph.Cli

The big picture: az controls what the assistant runs on. mgc controls what the assistant can do. Wire them together and you have a self-managing, fully agentic enterprise bot.

Layer 1: Azure CLI (az) — Infrastructure Control

Container Apps — Managing the Bot Itself

Our enterprise assistant runs as an Azure Container App (one per user). The az containerapp command group is how we manage it programmatically.

What You Want to Do Command
Deploy a new user's assistant from scratch az containerapp up --name assistant-dave --resource-group rg-enterprise --image myacr.azurecr.io/assistant:latest
Push a new version (zero-downtime) az containerapp update --name assistant-dave --image myacr.azurecr.io/assistant:v2.1
Set/update environment variables az containerapp update --name assistant-dave --set-env-vars "ANTHROPIC_KEY=secretref:anthropic-key"
Tail live logs az containerapp logs show --name assistant-dave --follow
Check revision/deployment status az containerapp revision list --name assistant-dave --output table
Scale replicas up/down az containerapp update --name assistant-dave --min-replicas 1 --max-replicas 3
Restart (force new revision) az containerapp revision restart --name assistant-dave --revision <rev-name>
List all user assistants az containerapp list --resource-group rg-enterprise --output table

Secrets Management — Key Vault Integration

The right pattern for our multi-tenant deployment: store all secrets in Azure Key Vault (one per client org, or one shared vault), reference them from Container Apps. The assistant never sees raw credentials — it gets secret refs only.

# Store a secret in Key Vault
az keyvault secret set \
  --vault-name kv-enterprise-prod \
  --name "dave-graph-token" \
  --value "eyJ0eXAiOiJKV1Q..."

# Reference it in the Container App (no raw value in config)
az containerapp secret set \
  --name assistant-dave \
  --secrets "graph-token=keyvaultref:https://kv-enterprise-prod.vault.azure.net/secrets/dave-graph-token"

# Surface it as an env var inside the container
az containerapp update \
  --name assistant-dave \
  --set-env-vars "GRAPH_TOKEN=secretref:graph-token"
Healthcare compliance angle: Key Vault with RBAC means the user's Graph token (access to their M365 data) is stored in their own Azure tenant, controlled by their own admins, and the assistant only receives it at runtime. This is your answer to "how do you handle our PHI?" — you don't touch it; it never leaves their environment.

App Registration — Permissions Management

Each user's assistant needs an App Registration in their Azure tenant (or ours, delegated) to call Graph API. The CLI manages the whole lifecycle:

# Create the app registration for a new client deployment
az ad app create \
  --display-name "Enterprise Assistant - Dave Devries" \
  --sign-in-audience AzureADMyOrg

# Grant Graph API permissions (mail, calendar, files)
az ad app permission add \
  --id <app-id> \
  --api 00000003-0000-0000-c000-000000000000 \
  --api-permissions \
    e1fe6dd8-ba31-4d61-89e7-88639da4683d=Scope \  # Mail.Read
    Calendars.ReadWrite=Scope \
    Files.ReadWrite=Scope

# Create a client secret (rotate periodically)
az ad app credential reset --id <app-id> --years 1

Azure Container Registry — Image Management

# Build and push new assistant image
az acr build \
  --registry myenterpriseacr \
  --image assistant:v2.1 \
  --file Dockerfile .

# List available images/tags
az acr repository show-tags \
  --name myenterpriseacr \
  --repository assistant

# All users auto-pull new image on next restart
# (or use revision-mode=multiple for gradual rollout)

Layer 2: Microsoft Graph CLI (mgc) — The Assistant's Capabilities

This is what makes the assistant actually useful. Graph CLI wraps every Microsoft Graph API endpoint in a scriptable CLI — mail, calendar, OneDrive, Teams, users, tasks, contacts. The assistant calls these as tools.

Mail

# List recent inbox messages
mgc users messages list --user-id dave@ash.com \
  --filter "isRead eq false" \
  --select "subject,from,receivedDateTime,bodyPreview" \
  --top 20

# Read a specific message
mgc users messages get --user-id dave@ash.com --message-id <id>

# Send a reply
mgc users messages reply --user-id dave@ash.com --message-id <id> \
  --body '{"comment": "Thanks for sending this over..."}'

# Move to folder / mark read
mgc users messages update --user-id dave@ash.com --message-id <id> \
  --body '{"isRead": true}'

Calendar

# Check upcoming events
mgc users calendar-view list --user-id dave@ash.com \
  --start-date-time "2026-03-13T00:00:00Z" \
  --end-date-time "2026-03-14T23:59:59Z"

# Create a meeting
mgc users events create --user-id dave@ash.com \
  --body '{
    "subject": "Provider Network Review",
    "start": {"dateTime": "2026-03-15T10:00:00", "timeZone": "America/Los_Angeles"},
    "end": {"dateTime": "2026-03-15T11:00:00", "timeZone": "America/Los_Angeles"},
    "attendees": [{"emailAddress": {"address": "colleague@ash.com"}}]
  }'

# Find free/busy slots
mgc users get-mail-tips --user-ids '["dave@ash.com", "colleague@ash.com"]' \
  --mail-tips-options "automaticReplies"

OneDrive & Files

# List files in a folder
mgc users drive root children list --user-id dave@ash.com

# Get a specific file's content
mgc users drive items content get \
  --user-id dave@ash.com --drive-item-id <id>

# Upload / update a file
mgc users drive items content put \
  --user-id dave@ash.com --drive-item-id <id> \
  --body @report.pdf

Teams

# Send a Teams message (bot-style)
mgc users chats messages create \
  --user-id dave@ash.com --chat-id <chat-id> \
  --body '{"body": {"content": "Here is your morning briefing..."}}'

# List Teams the user is in
mgc users joined-teams list --user-id dave@ash.com

The Agentic Pattern: Wiring It Together

The Architecture

The enterprise assistant is a FastAPI container. Each skill is a Python function that shells out to az or mgc CLI commands (or calls the SDK equivalents directly). The LLM (Claude) decides which tools to call. The CLI is the execution layer.

# How a "skill" looks inside the assistant container
# skills/email_skill.py

import subprocess, json

def get_unread_emails(user_id: str, top: int = 10) -> list:
    """Fetch unread emails for a user via Graph CLI."""
    result = subprocess.run([
        "mgc", "users", "messages", "list",
        "--user-id", user_id,
        "--filter", "isRead eq false",
        "--select", "subject,from,receivedDateTime,bodyPreview",
        "--top", str(top),
        "--output", "json"
    ], capture_output=True, text=True)
    return json.loads(result.stdout)["value"]

def deploy_new_revision(app_name: str, image_tag: str, resource_group: str):
    """Update the assistant's Container App to a new image (self-update)."""
    subprocess.run([
        "az", "containerapp", "update",
        "--name", app_name,
        "--resource-group", resource_group,
        "--image", f"myacr.azurecr.io/assistant:{image_tag}"
    ])

Self-Management: The Killer Feature

Here's the angle that makes this genuinely powerful for the demo: the assistant can manage itself via az CLI.

Demo story for Dave / ASH: "Your AI assistant lives in your Azure environment. It reads your email, manages your calendar, and can check on its own health. If something goes wrong, it tells you. If a new version is available, it updates itself with your permission. You never have to touch the Azure portal."

What's Also There: mogcli

Found a newer open-source tool worth knowing about: mogcli (github.com/jaredpalmer/mogcli) — described as "agent-friendly CLI for M365." Built by Jared Palmer (creator of Formik, Turborepo). Covers Mail, Calendar, Contacts, Groups, Tasks, OneDrive — same as mgc but lighter, designed specifically for agent use cases (piping JSON output into LLMs).

Worth watching. If the Microsoft Graph CLI (mgc) feels heavy for our container deployments, mogcli might be a cleaner fit.


Immediate Next Steps

Action Why Effort
Install az CLI + authenticate to our Azure subscription Prerequisite for everything else. az login → pick subscription 5 min
Run az containerapp list -g rg-enterprise --output table See our live Container Apps in one shot; confirm they're healthy 5 min
Install mgc and connect to Dave's M365 (delegated auth) Test a real mail fetch against his inbox — proves the stack works end to end 1-2 hrs
Build a thin Python skill wrapper around mgc mail + calendar commands This becomes the Email Claw and Calendar Claw in the assistant Half day
Add a az containerapp logs show --follow tool to the assistant Self-monitoring capability — assistant can report on its own health 2 hrs
Key Vault setup for Dave's Graph token Production-ready secrets handling; healthcare compliance story Half day

The Sequence

1. Get az managing our existing Container Apps → admin confidence
2. Get mgc reading Dave's email + calendar → assistant's first real capability
3. Wrap both in Python skills → plug into the FastAPI assistant
4. Add self-monitoring (logs, health, restart) → demo wow moment
5. Key Vault for secrets → healthcare-compliant production deployment


Sources: learn.microsoft.com/en-us/cli/azure (Azure CLI official docs, March 2026) · github.com/microsoftgraph/msgraph-cli (Microsoft Graph CLI) · github.com/jaredpalmer/mogcli (agent-friendly M365 CLI) · learn.microsoft.com/en-us/azure/container-apps (Container Apps documentation) · devblogs.microsoft.com/microsoft365dev (Graph CLI v1.0 GA announcement)

Report prepared by Chief · March 12, 2026 · Internal use only