MCP server for Microsoft 365 and Azure administration — Graph, ARM, Search, and the PowerShell cmdlets Graph does not expose (Exchange, SharePoint, Teams, Purview)
git clone https://github.com/HoussemMak/minerva-mcp{
"mcpServers": {
"minerva-mcp": {
"command": "node",
"args": ["/path/to/minerva-mcp/dist/index.js"]
}
}
}MCP Servers overview
# Minerva MCP
**Microsoft 365 and Azure administration for AI assistants — including the parts Microsoft Graph cannot reach.**
[](https://github.com/HoussemMak/minerva-mcp/actions/workflows/ci.yml)
[](LICENSE)
[](https://modelcontextprotocol.io/specification/2026-07-28)
An [MCP](https://modelcontextprotocol.io) server that lets Claude, Copilot, VS Code
or any MCP client query and administer a Microsoft 365 tenant in plain language.
---
## Why another Microsoft 365 MCP server?
There are already good ones, and this is not trying to replace them.
| | [Lokka](https://github.com/merill/lokka) | [ms-365-mcp-server](https://github.com/softeria/ms-365-mcp-server) | **Minerva MCP** |
|---|:---:|:---:|:---:|
| Microsoft Graph | ✅ | ✅ 300+ tools | ✅ generic call |
| Azure Resource Manager | ✅ | — | ✅ |
| **Exchange Online cmdlets** | — | — | ✅ |
| **SharePoint / PnP cmdlets** | — | — | ✅ |
| **Teams Admin cmdlets** | — | — | ✅ |
| **Purview / compliance cmdlets** | — | — | ✅ |
| Risk classification per action | — | — | ✅ |
| Human approval before writes | — | read-only switch | ✅ native to the protocol |
| MCP 2026-07-28 (stateless) | — | — | ✅ |
**If you only need Graph, use Lokka or ms-365-mcp-server.** They are excellent,
more mature, and more widely used. Lokka in particular is written by a Microsoft
Entra product manager.
Reach for this one when you hit the wall everyone hits eventually: **a large part
of Microsoft 365 administration has no Graph API.** Mailbox permissions,
transport rules, message trace, retention policies, sensitivity labels, Teams
calling policies, SharePoint term stores, tenant-wide Exchange settings — those
live in PowerShell and nowhere else. This server exposes them, with a
risk classification and a confirmation step in front of anything that writes.
---
## How it fits together
```mermaid
flowchart LR
A["AI client<br/>Claude · VS Code · Copilot Studio"]
B["minerva-mcp"]
C{"Risk<br/>classifier"}
D["Human<br/>confirmation"]
G["Microsoft Graph<br/>Azure ARM · Search"]
P["PowerShell 7<br/>Exchange · PnP · Teams · Purview"]
M["Microsoft<br/>authorizes the token"]
A -->|"stdio or HTTP"| B
B --> C
C -->|"read"| G
C -->|"write"| D
D -->|"signed mandate"| G
D -->|"signed mandate"| P
C -->|"read"| P
G --> M
P --> M
```
Reads go straight through. Writes stop at a classifier, come back to you as an
`input_required` describing the action and its consequences, and only run once
you confirm. Microsoft still has the final word: the server forwards a token, it
never grants access.
## Install
Nothing to clone. Add it to your client and sign in on first use.
### Claude Desktop
`claude_desktop_config.json`:
```json
{
"mcpServers": {
"minerva": {
"command": "npx",
"args": ["-y", "minerva-mcp", "--stdio"]
}
}
}
```
### VS Code
`.vscode/mcp.json`:
```json
{
"servers": {
"minerva": {
"type": "stdio",
"command": "npx",
"args": ["-y", "minerva-mcp", "--stdio"]
}
}
}
```
More, including read-only and app-only setups, in [`examples/`](examples/).
On the first tool call the server prints a device-code prompt **on stderr**:
open the link, enter the code, done. No app registration needed to try it — it
uses the public Microsoft Graph PowerShell client by default.
**Requirements:** Node.js 20+. For the PowerShell tools, [PowerShell 7+](https://aka.ms/powershell)
and the modules you intend to use (`ExchangeOnlineManagement`, `PnP.PowerShell`,
`MicrosoftTeams`).
---
## What you can ask
> *"Which mailboxes have full access delegated to someone outside their department?"*
> → `execute_exchange_online` with `Get-MailboxPermission`, no Graph equivalent exists.
> *"Show me every conditional access policy that does not require MFA, and our Secure Score."*
> → `generate_security_report` + `microsoft_graph_call`.
> *"Create a shared mailbox for invoicing and give the finance team access."*
> → classified as a write: the server describes the action and its consequences,
> and waits for your confirmation before doing anything.
---
## Tools
| Tool | What it does | Graph equivalent? |
|---|---|:---:|
| `microsoft_graph_call` | Any Microsoft Graph call (v1.0 or beta) | — |
| `azure_arm_call` | Any Azure Resource Manager call | — |
| `microsoft_search` | Unified Microsoft Search | — |
| `get_tenant_context` | Organisation, licences, Secure Score | — |
| `generate_security_report` | Tenant security posture | — |
| `execute_exchange_online` | Exchange Online cmdlets | ❌ none |
| `execute_pnp_sharepoint` | PnP PowerShell (SharePoint) cmdlets | ❌ none |
| `execute_teams_admin` | Teams Admin cmdlets | ❌ none |
| `execute_purview_compliance` | Purview / compliance cmdlets | ❌ none |
Restrict the surface with `--tools=microsoft_graph_call,get_tenant_context`, or
forbid every write with `--read-only`.
---
## Approval, and why it is not optional
A model reads untrusted content — an email subject, a site name, a document —
and decides which tool to call. Prompt injection is not hypothetical, and the
tools here can delete mailboxes.
So writes do not simply execute. Every action is classified `auto`, `confirmed`
or `critical` from the HTTP verb and path (or the PowerShell verb). Anything
above `auto` makes the server answer `input_required` under
[MCP's Multi Round-Trip Requests](https://modelcontextprotocol.io/specification/2026-07-28/basic/patterns/mrtr):
your client shows what is about to happen and its consequences, you confirm, and
only then does it run.
The confirmation is a signed mandate (HMAC) bound to the caller, the method, and
a digest of the arguments, valid five minutes. A mandate obtained to delete
`/users/1` cannot be replayed on `/users/999`, and cannot be presented by anyone
else.
If your client does not support elicitation, nothing is silently executed: the
server returns an error saying the action needs confirmation.
---
## Options
Every flag has an environment variable equivalent.
### Transport
| Flag | Env | Default | |
|---|---|---|---|
| `--stdio` | `MINERVA_TRANSPORT=stdio` | HTTP | JSON-RPC over stdin/stdout |
| `--port=<n>` | `MCP_SERVER_PORT` | `3001` | HTTP listen port |
In stdio mode **all logs go to stderr** — stdout belongs to the protocol.
### Authentication
| Flag | Env | |
|---|---|---|
| `--auth=<mode>` | `MINERVA_AUTH_MODE` | `bearer`, `device-code`, `client-secret` |
| `--tenant=<id>` | `MINERVA_TENANT_ID`, `AZURE_TENANT_ID` | Entra tenant |
| `--client-id=<id>` | `MINERVA_CLIENT_ID`, `AZURE_CLIENT_ID` | Application |
| `--client-secret=<s>` | `AZURE_CLIENT_SECRET` | App-only secret |
Defaults: `bearer` over HTTP (the caller supplies the token), `device-code` over
stdio, `client-secret` as soon as a secret is present. Each resource gets its own
token: Graph, ARM, Exchange, Purview, SharePoint and Teams do not share an
audience.
### Scope
| Flag | Env | |
|---|---|---|
| `--read-only` | `MINERVA_READ_ONLY` | Refuse every write |
| `--tools=<a,b,c>` | `MINERVA_TOOLS` | Register only these tools |
| `--ps=<mode>` | `MINERVA_PS_EXECUTOR` | `auto`, `redis`, `local`, `none` |
| `--sharepoint-url=<url>` | `MINERVA_SHAREPOINT_URL` | Required by the PnP tool locally |
| `--allowed-origins=<a,b>` | `MINERVA_ALLOWED_ORIGINS` | Browser origins allowed on `/mcp` |
| `--redis-url=<url>` | `REDIS_URL` | Queue for an external PowerShell runner |
| — | `MINERVA_MRTR_SECRET` | Signing key for approval mandates |
| — | `MINERVA_PWSH_PATH` | Path to `pwsh` |
| — | `MINERVA_REQUIRE_VERIFIED_TOKENS` | Refuse tokens whose signature cannot be verified |
`--read-only` reuses the same risk classifier as the approval gate, so it covers
PowerShell cmdlets too, not just HTTP verbs.
---
## Protocol support
Speaks **MCP 2026-07-28**, and still serves handshake-era clients until
**2027-07-28**.
| | |
|---|---|
| Stateless core (per-request `_meta`, no `initialize`, no `Mcp-Session-Id`) | ✅ |
| `server/discover` | ✅ |
| Multi Round-Trip Requests (`input_required`) | ✅ — this is the approval mechanism |
| `MCP-Protocol-Version` / `Mcp-Method` / `Mcp-Name` headers, base64 sentinel | ✅ validated against the body |
| `ttlMs` / `cacheScope` on lists | ✅ always `private` |
| Version negotiation (`-32022` listing supported versions) | ✅ |
| `Origin` validation (anti DNS-rebinding) | ✅ |
| GET/DELETE on the MCP endpoint | ✅ `405`, removed by this revision |
| Handshake era (`initialize`) | ✅ until 2027-07-28 |
One endpoint serves both generations; the request body decides which. Both read
the **same tool registry**, and a test compares them against a frozen contract so
they cannot drift.
---
## Security
Read [SECURITY.md](SECURITY.md) before deploying. The three things that matter:
1. **This server grants nothing.** It forwards a Microsoft token; Microsoft
authorizes. A restricted token gives a restricted server.
2. **Graph tokens cannot be verified by a third party** — they carry a `nonce`
header that only Graph can check. Their `tid`/`oid` claims are therefore
self-reported. The server validates them structurally, flags them
`verified: false`, and binds approval mandates to a **fingerprint of the token
itself** rather than to the claims alone. A token that *should* have verified
and did not is rejected.
3. **Local PowerShell mode isolates nothing.** Cmdlets run with the current
user's rights. Do not expose it to a caller you do not trust.
Cmdlet names and parameters never reach the script as code: they travel through
environment variables, the name is validated against a strict `Verb-Noun`
pattern, and the call goes through `Get-Command` plus the call operator.
Report a vulnerability privately — see [SECURITY.md](SECURITY.md).
---
What people ask about minerva-mcp
What is HoussemMak/minerva-mcp?
+
HoussemMak/minerva-mcp is mcp servers for the Claude AI ecosystem. MCP server for Microsoft 365 and Azure administration — Graph, ARM, Search, and the PowerShell cmdlets Graph does not expose (Exchange, SharePoint, Teams, Purview) It has 0 GitHub stars and was last updated today.
How do I install minerva-mcp?
+
You can install minerva-mcp by cloning the repository (https://github.com/HoussemMak/minerva-mcp) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.
Is HoussemMak/minerva-mcp safe to use?
+
HoussemMak/minerva-mcp has not been audited yet by our security agent. Review the original repository on GitHub before using it in production.
Who maintains HoussemMak/minerva-mcp?
+
HoussemMak/minerva-mcp is maintained by HoussemMak. The last recorded GitHub activity is from today, with 0 open issues.
Are there alternatives to minerva-mcp?
+
Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.
Deploy minerva-mcp to your cloud
Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.
Maintain this repo? Add a badge to your README
Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.
[](https://claudewave.com/repo/houssemmak-minerva-mcp)<a href="https://claudewave.com/repo/houssemmak-minerva-mcp"><img src="https://claudewave.com/api/badge/houssemmak-minerva-mcp" alt="Featured on ClaudeWave: HoussemMak/minerva-mcp" width="320" height="64" /></a>More MCP Servers
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
An open-source AI agent that brings the power of Gemini directly into your terminal.
The fastest path to AI-powered full stack observability, even for lean teams.
Real-time global intelligence dashboard. AI-powered news aggregation, geopolitical monitoring, and infrastructure tracking in a unified situational awareness interface
🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl!