Skip to main content
Glama
JackInSightsV2

Microsoft 365 & Azure MCP Server

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.

Related MCP server: Microsoft Graph MCP Server

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.”

  • “Connect to the aks-prod cluster and list the pods that are not running.”

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

Before you start

You need:

  1. uv installed. The client starts the server with uvx, which fetches it and its Python dependencies on first use.

  2. A supported AI client: Claude Code, Claude Desktop, VS Code, Cursor, Antigravity, OpenCode, or Codex.

  3. An Azure or Microsoft 365 account with permission to view or manage the information you need.

  4. Optional: the Azure CLI. Without it, the Azure tools use the Azure Resource Manager REST API instead.

For the optional Kubernetes (AKS) tools, run the server on your desktop with uvx (the plugin and the installer do). Nothing else needs installing: the server includes the Azure CLI, and the first AKS use downloads kubectl and kubelogin with Microsoft's az aks install-cli.

Claude Code plugin

In Claude Code, add this repository as a plugin marketplace and install the plugin:

/plugin marketplace add JackInSightsV2/Azure-M365-MCP
/plugin install azure-m365@azure-m365-mcp

The plugin provides the azure-m365 server (started with uvx, so the machine needs uv) two skills, and an agent:

  • /azure-m365:setup completes an Interactive sign-in and checks the connection with a me read and az account show.

  • microsoft-cloud gives the assistant common Microsoft Graph and Azure paths so calls are right first time. It loads automatically when relevant.

  • tenant-verifier (the Verifier) has Read tools only. Before a write to Azure or to users, groups, or licences it runs a What-if (native ARM What-if for Azure deployments, otherwise a diff of the current state against the planned change) and gives a GO / CHECK verdict; afterwards it re-reads the target and confirms the change landed. The microsoft-cloud skill calls it around those writes, not around mail or other low-risk writes. Ask for it any time with @agent-azure-m365:tenant-verifier.

Other clients do not support plugins; use the installer below.

Install with one command

If you have uv installed, one command adds the server to your client's configuration. Nothing else needs installing first:

uvx --from git+https://github.com/JackInSightsV2/Azure-M365-MCP unified-microsoft-mcp install --client cursor

Replace cursor with your client. The entry is named azure-m365.

--client

Default file written

--scope user writes

claude-code

.mcp.json in the current directory

~/.claude.json

vscode

.vscode/mcp.json in the current directory

your VS Code user profile's mcp.json

cursor

.cursor/mcp.json in the current directory

~/.cursor/mcp.json

codex

~/.codex/config.toml

(default)

claude-desktop

claude_desktop_config.json in ~/Library/Application Support/Claude (macOS), %APPDATA%\Claude (Windows), or ~/.config/Claude (Linux)

(default)

  • The installer adds the entry to the existing file and leaves your other settings and MCP servers as they are. It is safe to run again: an up-to-date entry is left alone, and an older one is replaced.

  • --scope project|user picks between the current project and your whole user account. --dir <path> uses a different project or home folder.

  • By default the client starts the server with uvx, so the machine needs only uv. The server includes the Azure CLI (an az already on your PATH is used first); the first start downloads it with the server, about 350 MB, so it can take a minute.

  • If the file is not plain JSON (for example, it contains comments), the installer stops without changing it. Add the entry by hand in that case.

Restart your client afterwards, then continue from Sign in.

Quick start

1. Add the server to your AI client

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

~ 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.

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

{
  "mcpServers": {
    "unified-microsoft": {
      "command": "uvx",
      "args": ["--from", "git+https://github.com/JackInSightsV2/Azure-M365-MCP", "unified-microsoft-mcp"]
    }
  }
}

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

{
  "mcpServers": {
    "unified-microsoft": {
      "command": "uvx",
      "args": ["--from", "git+https://github.com/JackInSightsV2/Azure-M365-MCP", "unified-microsoft-mcp"]
    }
  }
}

Add to opencode.json:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "unified-microsoft": {
      "type": "local",
      "command": ["uvx", "--from", "git+https://github.com/JackInSightsV2/Azure-M365-MCP", "unified-microsoft-mcp"],
      "enabled": true
    }
  }
}

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

[mcp_servers.unified_microsoft]
command = "uvx"
args = ["--from", "git+https://github.com/JackInSightsV2/Azure-M365-MCP", "unified-microsoft-mcp"]

The configuration tells the client to run:

uvx --from git+https://github.com/JackInSightsV2/Azure-M365-MCP unified-microsoft-mcp

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 tools:

  • azure_read to look up Azure resources and azure_write to change them;

  • azure_find_resource to find which subscription and resource group an Azure resource is in (needs the opt-in Resource inventory);

  • microsoft365_read to read Microsoft 365 and Entra ID through Microsoft Graph (read-only);

  • microsoft365_write to change Microsoft 365 and Entra ID through Microsoft Graph (your client should ask before each call).

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.

A browser window opens for Microsoft sign-in, the same as az login or Connect-AzAccount. Complete sign-in, then retry your original request.

Microsoft Graph and Azure sign in separately, so a second browser window may open the first time you use the other. This is normal. On a machine without a browser (for example over SSH), the assistant returns a web address and device code instead; see Sign-in and permissions.

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?

Set it in the env block of the server entry in your MCP client configuration:

"env": {
  "EXECUTION_POLICY": "read-only"
}

OpenCode calls this block environment; Codex uses a [mcp_servers.<name>.env] table. See client setup for complete examples.

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 an MCP client configuration, put them in the server entry's env block:

"env": {
  "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"
}

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

Sign-in opens a browser window, like az login or Connect-AzAccount. No client secret is required. Microsoft Graph signs in as Microsoft Graph Command Line Tools (the app Connect-MgGraph uses) and Azure as Azure PowerShell (the app Connect-AzAccount uses).

Set SIGN_IN_FLOW=device_code on a host without a browser (for example SSH sessions); the server then returns a code and sign-in address instead.

Microsoft Graph permissions

By default the server asks Microsoft Graph only for the permissions your Tenant has already granted to Microsoft Graph Command Line Tools (https://graph.microsoft.com/.default), so no consent prompt appears. A request that needs a permission not yet granted returns 403 with a suggestion naming what to do.

To sign in with more permissions, set GRAPH_SCOPES to a comma-separated list, for example:

GRAPH_SCOPES=https://graph.microsoft.com/Mail.Read,https://graph.microsoft.com/Group.ReadWrite.All

A consent prompt then appears for any permission not yet granted. If your Tenant does not let users consent, an admin must approve it; the server never works around that.

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

Signing in only once

The sign-in is cached, so after the first sign-in the server refreshes access silently instead of prompting again. Tokens are stored in the operating system's credential store (Keychain on macOS, DPAPI on Windows, Secret Service on Linux) and fall back to a plaintext file only where none is available. The sign-in record lives in TOKEN_CACHE_DIR (default ~/.IdentityService). Set GRAPH_TOKEN_CACHE=false to disable caching and prompt every time.

When the Azure CLI is missing or cannot sign in

If the Azure CLI is not installed, or its sign-in fails, the Azure tools use the Azure Resource Manager REST API instead, signing in as Azure PowerShell (AZURE_ARM_CLIENT_ID), the same app Connect-AzAccount uses. Whether that sign-in is allowed is decided by your Tenant's policy. See Tools.

Resource inventory (opt-in)

azure_find_resource finds an Azure resource by name (its subscription, resource group, type, location, and ID) in one call. It uses a Resource inventory: a local file listing every Azure resource you can see, built from one Azure Resource Graph query and rebuilt when older than 24 hours or when a lookup finds nothing. It stores only name, type, subscription, resource group, location, and ID (no tags or properties), sits beside the token cache (TOKEN_CACHE_DIR, default ~/.IdentityService), and is readable only by your user account. Microsoft 365 objects are never included.

That file is a map of your whole Azure estate, so it is off by default. The setup skill explains the risk and turns it on only if you say yes. To do it yourself:

uvx --from git+https://github.com/JackInSightsV2/Azure-M365-MCP unified-microsoft-mcp resource-inventory on   # or: off, status

off withdraws consent and deletes the file. Setting RESOURCE_INVENTORY=true in the server environment also gives consent.

Kubernetes (AKS)

The Kubernetes tools run az, kubelogin, and kubectl with your own kubeconfig (KUBECONFIG is respected) and the same access you have in a terminal. They are for desktop use and need nothing installed beyond uv:

  • Tools already on your PATH are used first.

  • Otherwise az is the Azure CLI installed with the server.

  • Otherwise, on first use (kubernetes_connect, or kubernetes_read / kubernetes_write when kubectl is missing), the server downloads kubectl and kubelogin once with Microsoft's az aks install-cli --install-location <dir>/kubectl --kubelogin-install-location <dir>/kubelogin, where <dir> is ~/.IdentityService/bin (set TOOLS_DIR to change it). Later calls reuse them.

If the download is blocked (offline, proxy), the tool says so and gives the manual install commands, for example:

brew install kubectl Azure/kubelogin/kubelogin                                    # macOS
winget install -e --id Kubernetes.kubectl; winget install -e --id Microsoft.Azure.Kubelogin   # Windows
az aks install-cli                                                                # any OS with the Azure CLI

kubernetes_connect (subscription, resource group, cluster, optional namespace) does what you would do by hand, stopping at the first step that fails:

az account set --subscription <sub>
az aks get-credentials --resource-group <rg> --name <cluster> --overwrite-existing
kubelogin convert-kubeconfig -l azurecli
kubectl config set-context --current --namespace=<ns>

If the Azure CLI is not signed in, it starts az login first, following SIGN_IN_FLOW (a browser window by default; device code only with SIGN_IN_FLOW=device_code). Then use kubernetes_read for get, describe, logs, top, events, and other reads, and kubernetes_write for every other kubectl command. Interactive and long-running commands (-it, edit, attach, port-forward, proxy, --watch, logs -f) are rejected. Set ENABLE_KUBERNETES=false to hide the tools.

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.

To turn an interactive sign-in into a service principal, an administrator with rights to create app registrations and assign roles can run the bundled helper in a terminal:

unified-microsoft-mcp-bootstrap-spn --role Reader

It signs in (device code if needed), creates the app registration and role assignment, and prints the AZURE_APP_* environment variables to set. The generated secret is long-lived and bypasses MFA, so store it in a secret manager and scope the role tightly. This grants Azure Resource Manager access only; Microsoft Graph application permissions require separate admin consent.

Troubleshooting

The client says uvx was not found

Install uv, then confirm this works in a terminal:

uvx --version

Some clients do not inherit your shell's PATH. If uvx works in a terminal but not in the client, use the full path from which uvx as the command.

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.

A browser window opened, or I received a device code

Complete sign-in in the browser window, or open the supplied address and enter the code, then retry the request. Azure and Microsoft Graph may each request sign-in.

The server asked Microsoft Graph for a permission your Tenant has not granted, usually because GRAPH_SCOPES is set. Accept it only if you are allowed to; otherwise cancel and ask an admin. Remove GRAPH_SCOPES to use only the permissions already granted.

I received AuthorizationFailed, Forbidden, or Insufficient privileges

The signed-in account, or the Microsoft Graph permissions granted in your Tenant, do not allow that operation. For Graph, the result suggests which permission to request with GRAPH_SCOPES. Otherwise 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

uvx reuses its cached build. Clear it, then restart the AI client so it fetches the latest version:

uv cache clean unified-microsoft-mcp

Technical reference

Tools

azure_read (the Azure Read tool) and azure_write (the Azure Write tool) each accept either an Azure CLI command beginning with az or an Azure Resource Manager REST path with the api-version query parameter. azure_read runs only read-only CLI actions (list, show, get, query, what-if, ...), REST GET, and the read-only POST queries (Resource Graph, Cost Management query, deployment What-if); anything else is rejected with a pointer to azure_write. The client can therefore auto-allow azure_read and ask before each azure_write call.

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

command: subscriptions?api-version=2022-12-01
method: GET

command: subscriptions/{id}/resourceGroups/example-rg?api-version=2021-04-01
method: PUT
data: {"location": "eastus"}

The server picks the transport. It uses the Azure CLI when it is available and falls back to the Azure Resource Manager REST API (https://management.azure.com) when the CLI is missing or fails, including when its sign-in is blocked by Conditional Access. A CLI command with no direct REST equivalent cannot fall back; the error then suggests an ARM path to retry with.

Interactive sign-in for the REST fallback uses AZURE_ARM_CLIENT_ID (the Azure PowerShell public client by default), which a locked-down tenant may permit even when the Azure CLI is blocked. Disable the fallback with ENABLE_AZURE_REST=false.

microsoft365_read accepts a Microsoft Graph v1.0 path and only issues GET requests. microsoft365_write accepts a path, a POST, PUT, PATCH, or DELETE method, and an optional JSON body:

# microsoft365_read
command: users

# microsoft365_write

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

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

kubernetes_connect connects kubectl to an AKS cluster once; kubernetes_read (read-only kubectl commands) and kubernetes_write (every other kubectl command) take a command beginning with kubectl plus optional context and namespace. See Kubernetes (AKS).

# kubernetes_connect
subscription: Contoso Prod
resource_group: rg-aks
cluster: aks-prod
namespace: payments

# kubernetes_read
command: kubectl get pods -o wide

# kubernetes_write
command: kubectl rollout restart deployment/web

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

To run an HTTP transport, start the server yourself with the setting in its environment (or in a .env file in the working directory; see env.example):

MCP_TRANSPORT=openapi uvx --from git+https://github.com/JackInSightsV2/Azure-M365-MCP unified-microsoft-mcp
curl http://127.0.0.1:8001/health

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 an installed copy

Install Python 3.11–3.14, then install the package (it includes the Azure CLI):

python -m pip install .

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

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 --cov=unified_mcp

Security and licensing

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

Available Tools

2 tools
execute_azure_cli_commandB

Execute an Azure CLI command. Commands must begin with 'az' and are subject to the configured execution policy.

ParametersJSON Schema
NameRequiredDescriptionDefault
commandYesAzure CLI command, for example 'az account show'

TDQS

B3.3/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full burden. It lacks disclosure of side effects, permissions, error handling, return format, or synchronization behavior. Only mentions command prefix and policy, which is minimal.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded, no fluff. However, conciseness sacrifices completeness for a tool that executes arbitrary commands.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool that executes arbitrary CLI commands with no output schema, the description is notably incomplete. It omits details on success/error responses, timeouts, how the execution policy works, and comparisons with sibling tool graph_command.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents the parameter. The description adds the constraint that commands must begin with 'az', but this is partially redundant since the schema implies CLI commands. No significant additional semantics beyond schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'execute' and the resource 'Azure CLI command'. It distinguishes from the sibling tool 'graph_command' by specifying the command prefix 'az', indicating Azure CLI focus.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides some guidance ('commands must begin with az', 'subject to execution policy') but does not explicitly specify when to use this tool versus alternatives like graph_command, nor does it provide exclusion criteria.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

graph_commandA

Call a Microsoft Graph v1.0 endpoint with GET, POST, PUT, PATCH, or DELETE.

ParametersJSON Schema
NameRequiredDescriptionDefault
dataNoBody for write requests
methodNoGET
commandYesGraph path such as 'me', 'users', or 'groups'

TDQS

A3.5/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full responsibility for disclosing behavior, but it only states the action and methods. It fails to mention key aspects such as authentication requirements, rate limits, response format (likely raw JSON), idempotency of GET vs write methods, or error handling. This lack of behavioral context limits the agent's ability to anticipate tool effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, 14-word sentence that conveys the essential action without redundancy. Every word contributes meaning, and no extraneous information is present. It is well front-loaded with the core functionality.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's generic nature (calling arbitrary Graph endpoints with 3 parameters and no output schema), the description is adequate but incomplete. It does not explain what the response contains (e.g., JSON payload, status codes), how pagination works, or any constraints. However, for a straightforward interface, an agent familiar with Microsoft Graph might infer these details.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 67% (command and data have descriptions; method lacks one). The description adds value by specifying the Graph API version ('v1.0'), which is not in the schema. The schema's description of 'command' as 'Graph path such as 'me', 'users', or 'groups'' is clear and helpful. Together, they provide solid parameter context.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description 'Call a Microsoft Graph v1.0 endpoint with GET, POST, PUT, PATCH, or DELETE' clearly states the specific verb ('call'), resource ('Microsoft Graph v1.0 endpoint'), and supported HTTP methods. This distinguishes it from the sibling tool 'execute_azure_cli_command', which targets Azure CLI commands rather than Graph API calls.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. It does not mention prerequisites, context, or when not to use it (e.g., for non-Graph calls). The sibling tool 'execute_azure_cli_command' is not referenced, leaving the agent without clear decision logic.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 2 tool updatesv1.1.0
    • First observedexecute_azure_cli_command
    • First observedgraph_command

TDQS

B3.2/5.0

Scored across 2 tools

Disambiguation5/5

The two tools target completely different APIs: Azure CLI vs Microsoft Graph, with no overlap in functionality.

Naming Consistency3/5

One uses a verb_noun pattern ('execute_azure_cli_command') while the other is just noun ('graph_command'), lacking a consistent action prefix.

Tool Count2/5

Only 2 tools for a broad domain like Microsoft 365 & Azure is insufficient; the server feels skeletal and under-scoped.

Completeness1/5

The server lacks any domain-specific operations; generic command execution leaves massive gaps for any practical use.

Maintenance

ActivityNo data
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers