Microsoft 365 & Azure MCP Server
This server gives an AI assistant two broad tools: run Azure CLI commands and call Microsoft Graph, subject to your sign-in and any execution policy.
Query Azure — e.g.
az account show,az group list,az vm list --resource-group Finance, to see subscriptions, resource groups, regions, and resources.Change Azure — any other
azcommand (create, update, delete), if the account's RBAC role and the execution policy allow it.Read Microsoft 365 / Entra ID — Graph
GETcalls for users, groups, profiles, licences, Intune-managed devices (me,users,groups).Change Microsoft 365 / Entra ID — Graph
POST,PUT,PATCH,DELETEwith an optional JSON body (e.g. rename a group), needing the matching Graph permissions.Stay within your permissions — Microsoft still enforces your account's Azure roles and Graph permissions; an
EXECUTION_POLICYofread-onlyorallowlistcan further restrict what runs.Note vs. the README — the schema exposes just these two commands, with no read/write split, no
azure_find_resource, and no Kubernetes tools, so the client cannot auto-approve reads only or use those features.
Provides tools for connecting to Azure Kubernetes Service (AKS) clusters, enabling operations such as listing pods that are not running.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Microsoft 365 & Azure MCP ServerList my Azure subscriptions"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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:
uv installed. The client starts the server with
uvx, which fetches it and its Python dependencies on first use.A supported AI client: Claude Code, Claude Desktop, VS Code, Cursor, Antigravity, OpenCode, or Codex.
An Azure or Microsoft 365 account with permission to view or manage the information you need.
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-mcpThe plugin provides the azure-m365 server (started with uvx, so the machine needs uv) two skills, and an agent:
/azure-m365:setupcompletes an Interactive sign-in and checks the connection with ameread andaz account show.microsoft-cloudgives 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. Themicrosoft-cloudskill 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 cursorReplace cursor with your client. The entry is named azure-m365.
| Default file written |
|
|
|
|
|
| your VS Code user profile's |
|
|
|
|
| (default) |
|
| (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|userpicks 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 onlyuv. The server includes the Azure CLI (anazalready on yourPATHis 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:
Client | Where to put the configuration |
Cursor | |
Google Antigravity | |
OpenCode | |
OpenAI Codex |
~ 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-mcpYou 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_readto look up Azure resources andazure_writeto change them;azure_find_resourceto find which subscription and resource group an Azure resource is in (needs the opt-in Resource inventory);microsoft365_readto read Microsoft 365 and Entra ID through Microsoft Graph (read-only);microsoft365_writeto 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 |
| Allows all supported commands. This is the default. |
You only investigate incidents or collect information |
| Allows recognised Azure read commands and Graph |
A shared workflow should run only a few approved commands |
| 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-mcpHow 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 /groupsIn 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.AllA 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, statusoff 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
PATHare used first.Otherwise
azis the Azure CLI installed with the server.Otherwise, on first use (
kubernetes_connect, orkubernetes_read/kubernetes_writewhenkubectlis missing), the server downloadskubectlandkubeloginonce with Microsoft'saz aks install-cli --install-location <dir>/kubectl --kubelogin-install-location <dir>/kubelogin, where<dir>is~/.IdentityService/bin(setTOOLS_DIRto 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 CLIkubernetes_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 ReaderIt 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 --versionSome 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.
I see a "Permissions requested" consent screen
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-mcpTechnical 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/webTransport options
Transport | Setting | Endpoint | Use |
stdio |
| process input/output | Normal local IDE use; default |
Streamable HTTP |
|
| Shared or remote MCP server |
SSE |
|
| Compatibility with older clients |
OpenAPI |
|
| 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/healthFor 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_mcpSecurity and licensing
See SECURITY.md for vulnerability reporting and deployment guidance. This project is licensed under the MIT License.
Available Tools
2 toolsexecute_azure_cli_commandB
Execute an Azure CLI command. Commands must begin with 'az' and are subject to the configured execution policy.
| Name | Required | Description | Default |
|---|---|---|---|
| command | Yes | Azure CLI command, for example 'az account show' |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| data | No | Body for write requests | |
| method | No | GET | |
| command | Yes | Graph path such as 'me', 'users', or 'groups' |
TDQS
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.
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.
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.
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.
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.
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.
2 tool updates
v1.1.0- First observed
execute_azure_cli_command - First observed
graph_command
TDQS
Scored across 2 tools
The two tools target completely different APIs: Azure CLI vs Microsoft Graph, with no overlap in functionality.
One uses a verb_noun pattern ('execute_azure_cli_command') while the other is just noun ('graph_command'), lacking a consistent action prefix.
Only 2 tools for a broad domain like Microsoft 365 & Azure is insufficient; the server feels skeletal and under-scoped.
The server lacks any domain-specific operations; generic command execution leaves massive gaps for any practical use.
Maintenance
Related MCP Connectors
MCP server unifying ERPs, CRMs, APIs and knowledge base for Claude, ChatGPT and Gemini.
Unified MCP Server is a remote MCP connector for AI agents and vertical AI products that provides access to 22,000+ authorized SaaS tools across 400+ integrations and 24 categories directly inside LLMs (Claude, GPT, Gemini, Cohere). Tools operate only on explicitly authorized customer connections, enabling agents to safely read and write against live third-party systems.
MCP server connecting AI agents to 100+ apps (Gmail, Slack, Notion, GitHub) via one-click OAuth.
- ZapierOAuthcom.zapier
Hosted MCP server connecting AI assistants to 9,000+ apps and 40,000+ actions via Zapier.
Related MCP Servers
- FlicenseCqualityFmaintenanceA powerful MCP server that enables AI assistants to interact with Microsoft Graph API for managing Outlook emails, Calendar events, OneDrive files, and Contacts through natural language commands.3556-
- AlicenseNot gradedqualityDmaintenanceA comprehensive server that enables AI applications to interact with Microsoft 365 and Azure AD services through standardized Model Context Protocol interfaces.3MIT
- AlicenseBqualityCmaintenanceAn MCP server for managing Azure infrastructure from AI assistants, supporting subscriptions, VMs, storage, networking, identity, and more through natural language commands.992MIT
- AlicenseNot gradedqualityDmaintenanceA secure remote MCP server that integrates Microsoft 365 services with AI assistants, enabling email, calendar, Teams, and contact operations via the Microsoft Graph API.2MIT