MDI MCP Server
by TigerToker
README.md
# MDI MCP Server
A [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server that integrates with **Microsoft Defender for Identity (MDI)** via the Microsoft Graph API. Use it with VS Code + GitHub Copilot to query MDI data and generate styled HTML reports — all from natural language.
## Features
| Category | Tools |
|----------|-------|
| **Alerts & Incidents** | Query MDI alerts by severity, fetch security incidents |
| **Secure Score** | Get latest score, identity-related control recommendations |
| **Risky Users** | List risky users, view risk detections from Identity Protection |
| **Sensor Health** | Check MDI sensor status, surface health issues |
| **Activity Timeline** | Suspicious logon events, directory changes (password resets, group changes) |
| **Advanced Hunting** | Run arbitrary KQL queries against Defender tables |
| **HTML Reports** | Generate dark-themed, print-friendly reports for any of the above |
## Prerequisites
1. **Python 3.10+**
2. **Azure AD App Registration** with the following **Application** permissions:
- `SecurityAlert.Read.All`
- `SecurityIncident.Read.All`
- `SecurityEvents.Read.All`
- `IdentityRiskyUser.Read.All`
- `IdentityRiskEvent.Read.All`
- `ThreatHunting.Read.All`
> Grant admin consent after adding the permissions.
3. **VS Code** with [GitHub Copilot](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot) extension installed.
## Quick Start
### 1. Clone and install
```bash
git clone https://github.com/TigerToker/mdi-mcp-server.git
cd mdi-mcp-server
pip install -e .
```
### 2. Configure credentials
Copy `.env.example` to `.env` and fill in your Azure AD app registration details:
```bash
cp .env.example .env
# Edit .env with your AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET
```
### 3. Connect to VS Code + Copilot
The repo includes `.vscode/mcp.json` which auto-registers the server. Open the project folder in VS Code and Copilot will detect the MCP server.
Alternatively, add this to your **User** `settings.json` for global access:
```json
"mcp": {
"servers": {
"mdi-mcp-server": {
"type": "stdio",
"command": "python",
"args": ["-m", "mdi_mcp_server.server"],
"cwd": "/path/to/mdi-mcp-server/src",
"env": {
"AZURE_TENANT_ID": "your-tenant-id",
"AZURE_CLIENT_ID": "your-client-id",
"AZURE_CLIENT_SECRET": "your-client-secret"
}
}
}
}
```
### 4. Start asking questions
In Copilot Chat, try:
- *"Show me all high-severity MDI alerts from the last week"*
- *"Generate a comprehensive MDI report for the past 30 days"*
- *"Are there any risky users in my tenant?"*
- *"What's the health status of our MDI sensors?"*
- *"Run an Advanced Hunting query for failed logon attempts"*
## Project Structure
```
mdi-mcp-server/
├── src/mdi_mcp_server/
│ ├── server.py # MCP server entry point & tool definitions
│ ├── graph_client.py # Microsoft Graph API client
│ ├── report_generator.py # Jinja2-based HTML report builder
│ └── templates/
│ └── report.html # Dark-themed HTML report template
├── .vscode/mcp.json # VS Code MCP server configuration
├── .github/copilot-instructions.md
├── pyproject.toml
├── requirements.txt
└── .env.example
```
## Available MCP Tools
### Query Tools
| Tool | Description |
|------|-------------|
| `get_mdi_alerts` | Fetch MDI alerts with optional severity filter |
| `get_mdi_incidents` | Fetch security incidents |
| `get_secure_score` | Latest Secure Score snapshots |
| `get_secure_score_controls` | All Secure Score control profiles |
| `get_risky_users` | Risky users from Identity Protection |
| `get_risk_detections` | Individual risk detection events |
| `get_mdi_sensor_info` | MDI sensor & domain controller status |
| `get_mdi_health_issues` | MDI health alerts |
| `get_suspicious_activity_timeline` | Suspicious logon events |
| `get_identity_directory_events` | Directory change events |
| `run_custom_hunting_query` | Ad-hoc KQL via Advanced Hunting |
### Report Generation Tools
| Tool | Description |
|------|-------------|
| `generate_alerts_report` | HTML report of MDI alerts |
| `generate_incidents_report` | HTML report of security incidents |
| `generate_risky_users_report` | HTML report of risky users |
| `generate_secure_score_report` | HTML report of Secure Score |
| `generate_sensor_health_report` | HTML report of sensor health |
| `generate_full_mdi_report` | Comprehensive report with all data |
## Required Graph API Permissions
| Permission | Type | Purpose |
|------------|------|---------|
| `SecurityAlert.Read.All` | Application | Read security alerts (MDI alerts) |
| `SecurityIncident.Read.All` | Application | Read security incidents |
| `SecurityEvents.Read.All` | Application | Read security events |
| `IdentityRiskyUser.Read.All` | Application | Read risky user data |
| `IdentityRiskEvent.Read.All` | Application | Read risk detection events |
| `ThreatHunting.Read.All` | Application | Run Advanced Hunting queries |
## GitHub Copilot Extension
This project also ships as a **GitHub Copilot Extension** — a standalone agent that responds to natural-language queries about MDI directly inside GitHub Copilot Chat.
### How It Works
The extension runs a FastAPI server that implements the [GitHub Copilot Extensions agent protocol](https://docs.github.com/en/copilot/building-copilot-extensions). When you `@mention` the extension in Copilot Chat, your message is routed to the `/agent` endpoint, which parses your intent, queries the Graph API, and streams back a markdown response.
### Running Locally
```bash
# Install dependencies
pip install -e .
# Set environment variables
export AZURE_TENANT_ID="your-tenant-id"
export AZURE_CLIENT_ID="your-client-id"
export AZURE_CLIENT_SECRET="your-client-secret"
export GITHUB_WEBHOOK_SECRET="your-webhook-secret"
# Start the server
uvicorn mdi_mcp_server.copilot_extension:app --host 0.0.0.0 --port 8080 --app-dir src
```
### Docker
```bash
docker build -t mdi-copilot-extension .
docker run -p 8080:8080 \
-e AZURE_TENANT_ID="..." \
-e AZURE_CLIENT_ID="..." \
-e AZURE_CLIENT_SECRET="..." \
-e GITHUB_WEBHOOK_SECRET="..." \
mdi-copilot-extension
```
### Deploy to Azure Container Apps
Use the provided deployment script:
```powershell
.\deploy.ps1 -ResourceGroup "mdi-copilot-rg" -AcrName "myacr"
```
Or deploy manually via Bicep:
```bash
az deployment group create \
--resource-group mdi-copilot-rg \
--template-file infra/main.bicep \
--parameters containerImage="myacr.azurecr.io/mdi-copilot-extension:latest" \
azureTenantId="..." azureClientId="..." \
azureClientSecret="..." githubWebhookSecret="..."
```
### Register the Extension
1. Go to **GitHub Settings → Developer Settings → GitHub Apps → Copilot Extensions**
2. Create a new Copilot Extension (or GitHub App with Copilot agent)
3. Set the **Agent URL** to your deployed endpoint: `https://<your-app>.azurecontainerapps.io/agent`
4. Set the **Webhook Secret** to match `GITHUB_WEBHOOK_SECRET`
5. Install the app on your organization or account
### Extension Commands
Once installed, use `@mdi` (or your extension name) in Copilot Chat:
- `@mdi show me high severity alerts from the last 7 days`
- `@mdi generate a full MDI report for the past 30 days`
- `@mdi are there any risky users?`
- `@mdi what's our secure score?`
- `@mdi check MDI sensor health`
## License
MIT
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues