Featured

Deploy OpenClaw in 60 seconds — 20% off logoDeploy OpenClaw in 60 seconds — 20% off

Launch OpenClaw on Hostinger in about 60 seconds and keep your agent live 24/7. Our referral link gives you 20% off, no coupon code needed.

Launch on Hostinger
Run your Hermes agent on Hostinger, fully managed logoRun your Hermes agent on Hostinger, fully managed

Launch Hermes on Hostinger in one click, fully managed, no VPS knowledge needed. Use code ZACAARON10 for 10% off.

Launch on Hostinger
Crawl and scrape any site into clean data, 10% off logoCrawl and scrape any site into clean data, 10% off

Firecrawl crawls and scrapes any site into clean markdown for your agent. Get 1,000 free credits, and new users get 10% off their first purchase.

Try Firecrawl free
6,000+ web scrapers for your AI agent, start free logo6,000+ web scrapers for your AI agent, start free

Apify gives your agent live web data: 6,000+ prebuilt scrapers and actors, MCP-ready. Sign up free with $5 in usage credits.

Try Apify free
One API to scrape, enrich, and extract the internet. logoOne API to scrape, enrich, and extract the internet.

Context.dev gives your agents a single API to scrape, enrich, and extract live web data — no proxies, no parsers, no maintenance.

Start building free
SetupClaw: done-for-you OpenClaw for founders & exec teams logoSetupClaw: done-for-you OpenClaw for founders & exec teams

White-glove OpenClaw for founders and exec teams (4–50+ employees): we install, harden, integrate your tools, and maintain it — secured from day one.

Get it set up for you
SEO data APIs for your agent, $1 free credit logoSEO data APIs for your agent, $1 free credit

DataForSEO gives your agent live access to SERP results, keyword data, backlinks, and on-page SEO data through one API. New accounts get a $1 credit, good for up to 20,000 keyword or backlink lookups.

Try DataForSEO free
Reach 48,000+ AI builders

A flat monthly placement in front of developers actively installing AI tools. No lock-in, cancel anytime.

Advertise here

Works with

Claude CodeClaude DesktopCursorVS CodeClineCodex CLIOpenClaw+ any MCP client

Install to Claude Code

This server doesn't publish a one-line install command. Follow the setup in the source repository.

Summary

A unified MCP server that enables AI assistants to interact with Microsoft 365 and Azure resources through Azure CLI and Microsoft Graph API, running in a single Docker container.

README.md

Unified Microsoft MCP Server

Connect an AI assistant such as Cursor, Google Antigravity, OpenCode, or OpenAI Codex to Microsoft Azure and Microsoft 365.

The assistant can use your existing access to investigate issues, collect information, and—if you allow it—make changes. It cannot grant itself extra permissions.

What problem does this solve?

Support engineers often need to move between the Azure portal, Microsoft 365 admin centres, Microsoft Graph, and command-line tools to answer one ticket. That takes time and requires knowing where Microsoft has placed each setting.

This server gives a supported AI client two controlled tools—one for Azure and one for Microsoft 365. You can describe the task in plain English, and the assistant uses those tools to gather the information available to your signed-in account.

For example, instead of finding and combining several portal pages, you can ask:

Show me the user account, group memberships, assigned licences, and managed devices for user@example.com.

The AI client decides which tool calls are needed, the MCP server validates and runs them, and Microsoft still enforces your normal permissions. You remain responsible for checking the result before acting on it.

Who is this for?

This project is designed for people such as:

  • first- and second-line helpdesk engineers;
  • Microsoft 365 and Azure support teams;
  • system administrators;
  • developers and automation engineers.

You do not need to know Python or run the server manually. Your AI client starts and stops it automatically.

You should be comfortable copying a configuration block into the file used by your AI client. The steps below show the exact file and content.

What can I ask it?

Examples include:

  • “Which Azure subscription am I connected to?”
  • “List the resource groups and show me which region each uses.”
  • “Show the virtual machines in the Finance resource group.”
  • “List Microsoft 365 users with their job titles.”
  • “Find the details for user@example.com.”
  • “List Entra ID groups.”
  • “Show the managed devices in Intune.”

The available results depend on the permissions of the account that signs in.

Before you start

You need:

  1. Docker Desktop installed and running.
  2. A supported AI client: Cursor, Antigravity, OpenCode, or Codex.
  3. An Azure or Microsoft 365 account with permission to view or manage the information you need.

The Docker image already contains the server, Python, and Azure CLI.

Quick start

1. Add the server to your AI client

Choose your client below. The examples are complete configurations for a new file:

| Client | Where to put the configuration | | --- | --- | | Cursor | .cursor/mcp.json or ~/.cursor/mcp.json | | Google Antigravity | .agents/mcp_config.json or ~/.gemini/config/mcp_config.json | | OpenCode | opencode.json | | OpenAI Codex | ~/.codex/config.toml or .codex/config.toml |

~ means your user home folder—for example, C:\Users\your-name on Windows. A project file enables the server only in that project; a file in your home folder makes it available globally.

If the file already contains other settings or MCP servers, do not overwrite it. Add the unified-microsoft entry alongside the existing content, or make a backup before editing.

<details> <summary><strong>Cursor configuration</strong></summary>

Save as .cursor/mcp.json in a project or ~/.cursor/mcp.json globally:

{
  "mcpServers": {
    "unified-microsoft": {
      "command": "docker",
      "args": [
        "run", "--rm", "-i",
        "-v", "unified-microsoft-mcp-azure:/home/app/.azure",
        "ghcr.io/jackinsightsv2/azure-m365-mcp:latest"
      ]
    }
  }
}

</details>

<details> <summary><strong>Google Antigravity configuration</strong></summary>

Save as .agents/mcp_config.json in a workspace or ~/.gemini/config/mcp_config.json globally:

{
  "mcpServers": {
    "unified-microsoft": {
      "command": "docker",
      "args": [
        "run", "--rm", "-i",
        "-v", "unified-microsoft-mcp-azure:/home/app/.azure",
        "ghcr.io/jackinsightsv2/azure-m365-mcp:latest"
      ]
    }
  }
}

</details>

<details> <summary><strong>OpenCode configuration</strong></summary>

Add to opencode.json:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "unified-microsoft": {
      "type": "local",
      "command": [
        "docker", "run", "--rm", "-i",
        "-v", "unified-microsoft-mcp-azure:/home/app/.azure",
        "ghcr.io/jackinsightsv2/azure-m365-mcp:latest"
      ],
      "enabled": true
    }
  }
}

</details>

<details> <summary><strong>OpenAI Codex configuration</strong></summary>

Add to ~/.codex/config.toml or .codex/config.toml in a trusted project:

[mcp_servers.unified_microsoft]
command = "docker"
args = [
  "run", "--rm", "-i",
  "-v", "unified-microsoft-mcp-azure:/home/app/.azure",
  "ghcr.io/jackinsightsv2/azure-m365-mcp:latest"
]

</details>

The configuration tells the client to run:

docker run --rm -i -v unified-microsoft-mcp-azure:/home/app/.azure ghcr.io/jackinsightsv2/azure-m365-mcp:latest

You do not run that command separately. The AI client runs it when required.

2. Restart your AI client

Restart the client after saving its configuration. It should discover these two tools:

  • execute_azure_cli_command for Azure;
  • graph_command for Microsoft 365 and Microsoft Graph.

Your client may ask you to approve a tool before it runs. That approval prompt is controlled by the client, not this server.

3. Sign in

Ask the assistant:

Sign me in to Azure using the Azure CLI tool.

The assistant will return a web address and device code. Open the address, enter the code, and complete sign-in. Then retry your original request.

Microsoft Graph may request a separate device-code sign-in the first time it is used. This is normal.

The Docker configuration uses a named volume so Azure CLI sign-in survives restarts.

4. Try a read-only request

Ask:

Show my current Azure account and subscription.

or:

Use Microsoft Graph to show my profile.

Execution policy: an optional safety switch

Execution policy controls what the MCP server will let the assistant attempt. It is an extra safety layer on top of Azure roles and Microsoft Graph permissions.

You do not need to configure it just to use the server. Most desktop AI clients can already ask you to approve individual tool calls. Use an execution policy when you also want a fixed server-side rule—for example, when a support role must never make changes even if someone approves the wrong tool call.

Which policy should I use?

| Your situation | Recommended policy | What it means | | --- | --- | --- | | You need the assistant to investigate and make changes | unrestricted | Allows all supported commands. This is the default. | | You only investigate incidents or collect information | read-only | Allows recognised Azure read commands and Graph GET requests. Blocks changes. | | A shared workflow should run only a few approved commands | allowlist | Blocks everything except the command prefixes you specify. |

If you do not set anything, the server uses unrestricted so existing functionality continues to work.

For a first-line support role that only gathers information, read-only is the safer choice. A second-line engineer who is expected to restart, create, update, or delete resources will need unrestricted or a suitable allowlist.

Where do I set it?

For the recommended Docker-based IDE setup, put it inside the Docker args or command list in your MCP client configuration.

Add these two entries after "-i":

"-e", "EXECUTION_POLICY=read-only",

For example:

"args": [
  "run", "--rm", "-i",
  "-e", "EXECUTION_POLICY=read-only",
  "-v", "unified-microsoft-mcp-azure:/home/app/.azure",
  "ghcr.io/jackinsightsv2/azure-m365-mcp:latest"
]

This placement works in the Cursor and Antigravity args arrays, the OpenCode command array, and the Codex args array. See client setup for complete examples.

If you start the server with Docker Compose, copy env.example to .env and set:

EXECUTION_POLICY=read-only

If you run the installed executable directly, set the variable in the MCP client’s environment section or before starting the server:

export EXECUTION_POLICY=read-only
unified-microsoft-mcp

How do I use an allowlist?

Use an allowlist only when you know the exact operations a role or workflow requires. Set all three variables:

EXECUTION_POLICY=allowlist
AZURE_COMMAND_ALLOWLIST=az login,az account show,az group list,az vm list
GRAPH_REQUEST_ALLOWLIST=GET /me,GET /users,GET /groups

In a Docker-based client configuration, pass them as Docker environment arguments:

"-e", "EXECUTION_POLICY=allowlist",
"-e", "AZURE_COMMAND_ALLOWLIST=az login,az account show,az group list,az vm list",
"-e", "GRAPH_REQUEST_ALLOWLIST=GET /me,GET /users,GET /groups",

GET /users also permits a specific user path such as GET /users/{id}. It does not permit a different path such as /users-internal.

Include az login when allowlisted desktop users need to sign in interactively. Azure entries match the beginning of the parsed command, so az vm list also permits options such as az vm list --resource-group Finance.

Execution policy can only reduce access. Azure RBAC and Microsoft Graph permissions still decide what the signed-in account can actually do.

Sign-in and permissions

Normal desktop use

Use device-code sign-in. No client secret is required. The server provides a code and Microsoft sign-in address when authentication is needed.

Never paste passwords, client secrets, API keys, or access tokens into an AI chat or tool command.

Unattended or shared server

Administrators can configure managed identity or a service principal through environment variables. See env.example. These options are intended for managed deployments, not normal desktop setup.

The server stops an Azure command if the configured managed identity or service-principal sign-in fails. It will not silently use a different cached identity.

Troubleshooting

The client says docker was not found

Install Docker Desktop, start it, and confirm this works in a terminal:

docker version

The tools do not appear

Check that the configuration file is in the correct location and contains valid JSON or TOML. Restart the AI client after changing it.

I received a device code

Open the supplied Microsoft sign-in address, enter the code, finish sign-in, and retry the request. Azure and Microsoft Graph may each request sign-in.

I received AuthorizationFailed, Forbidden, or Insufficient privileges

The signed-in account does not have permission for that operation. Ask an Azure or Microsoft 365 administrator to confirm the account’s role or Graph permissions. Changing execution policy cannot add permission.

I received Execution policy denied...

The server’s safety policy blocked the operation. Use a read-only command, add the required command to the allowlist, or—only when the role is expected to make changes—use unrestricted.

I am seeing an older version

Pull the latest image and restart the AI client:

docker pull ghcr.io/jackinsightsv2/azure-m365-mcp:latest

Technical reference

Tools

execute_azure_cli_command accepts an Azure CLI command beginning with az, for example:

az account show
az group list
az vm list --resource-group example-rg

graph_command accepts a Microsoft Graph v1.0 path, an HTTP method, and an optional JSON body:

command: users
method: GET

command: groups/{id}
method: PATCH
data: {"displayName": "New name"}

Graph writes require an application or managed identity with the necessary Microsoft Graph application permissions.

Transport options

| Transport | Setting | Endpoint | Use | | --- | --- | --- | --- | | stdio | MCP_TRANSPORT=stdio | process input/output | Normal local IDE use; default | | Streamable HTTP | MCP_TRANSPORT=streamable-http | /mcp | Shared or remote MCP server | | SSE | MCP_TRANSPORT=sse | /sse | Compatibility with older clients | | OpenAPI | MCP_TRANSPORT=openapi | /docs | Direct REST integrations |

For HTTP deployments, set MCP_API_KEY, use TLS, and place the server behind network access controls. The built-in server binds to 127.0.0.1 by default.

Run without Docker

Install Python 3.11–3.14 and Azure CLI, then install the package:

python -m pip install .

Configure the MCP client to launch unified-microsoft-mcp directly.

Docker Compose

cp env.example .env
docker compose up --build -d
curl http://127.0.0.1:8001/health

Development

python -m venv .venv
source .venv/bin/activate
python -m pip install -e ".[dev]"
black --check unified_mcp tests
ruff check unified_mcp tests
mypy unified_mcp
pytest -m "not docker" --cov=unified_mcp

Docker integration tests use mock mode and do not require Azure credentials:

pytest -m docker

Security and licensing

See SECURITY.md for vulnerability reporting and deployment guidance. This project is licensed under the MIT License.

See related servers & alternatives →

Related MCP servers

Browse all →

Related guides

Hand-picked reading to help you choose and use Cloud & DevOps servers.