nexus-mcp/Intune/CoPilot Generated Deployment Plan v2.md

339 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# StepbyStep Guide: Building an Intune MCP Server (Phase 1 ReadOnly)
***
## 0. What you are building (anchor this first)
From both documents, the **Intune MCP** is defined as:
> A readonly MCP server that exposes **live Microsoft Intune device state** (inventory, compliance, ownership, last checkin) to AI clients, using the same delivery pattern as Identity MCP. [\[wheelsinc-...epoint.com\]](https://wheelsinc-my.sharepoint.com/personal/castn1_wheels_com/Documents/Microsoft%20Copilot%20Chat%20Files/intune-mcp-prerequisites-and-checklists.md), [\[wheelsinc-...epoint.com\]](https://wheelsinc-my.sharepoint.com/personal/castn1_wheels_com/Documents/Microsoft%20Copilot%20Chat%20Files/CoPilot%20Generated%20Deployment%20Plan.md)
Key constraints (do **not** skip these):
* **Readonly only** in Phase 1
* **Microsoft Graph is the backend**
* **Stable tool contracts** (no raw Graph payloads)
* **STDIO MCP transport**
* **Pertool audit logging**
* **No device actions yet**
***
## 1. Complete prerequisites (must be done first)
Everything in this section is taken directly from [intune-mcp-prerequisites-and-checklists.md](https://wheelsinc-my.sharepoint.com/personal/castn1_wheels_com/Documents/Microsoft%20Copilot%20Chat%20Files/intune-mcp-prerequisites-and-checklists.md?EntityRepresentationId=aab065d3-d6ce-46e8-8e59-4a042ed7b2f5). [\[wheelsinc-...epoint.com\]](https://wheelsinc-my.sharepoint.com/personal/castn1_wheels_com/Documents/Microsoft%20Copilot%20Chat%20Files/intune-mcp-prerequisites-and-checklists.md)
### 1.1 Governance & ownership
Confirm and document:
* Product owner: Endpoint / Intune
* Security owner
* Operational owner (Service Desk / Endpoint Ops)
* Approved operation list (read operations only)
* Signed read vs write boundary
**Output:** Approved Phase 1 scope document
***
### 1.2 Microsoft tenant preparation
Verify:
* Intune tenant is healthy
* Microsoft Graph access is approved
* A nonproduction tenant or pilot scope exists
**Output:** Tenant readiness confirmation
***
### 1.3 App registration (authentication model)
Create an **Azure App Registration** for the Intune MCP:
* Authentication:
* ✅ Certificatebased auth (preferred)
* ⛔ Client secret (temporary only)
* Create a **service principal**
* Define token lifetime & rotation policy
**Output:** App ID, Tenant ID, auth method documented
***
### 1.4 Microsoft Graph permissions (least privilege)
Grant **only** the following for Phase 1:
* `DeviceManagementManagedDevices.Read.All`
* `DeviceManagementConfiguration.Read.All` *(only if policy context is needed)*
* `Directory.Read.All` *(only if joining user/device info)*
Admin consent must be explicitly granted and justified. [\[wheelsinc-...epoint.com\]](https://wheelsinc-my.sharepoint.com/personal/castn1_wheels_com/Documents/Microsoft%20Copilot%20Chat%20Files/intune-mcp-prerequisites-and-checklists.md)
**Output:** Permission justification record
***
### 1.5 Runtime & platform
Prepare:
* Python 3.10+
* Dependency manager (`uv` recommended)
* Secure secret storage (no tokens in code)
* Logging destination (file or central sink)
**Output:** Runtime ready
***
## 2. Create the MCP project scaffold
This follows the **Identity MCP replication pattern** explicitly required in the prerequisites file. [\[wheelsinc-...epoint.com\]](https://wheelsinc-my.sharepoint.com/personal/castn1_wheels_com/Documents/Microsoft%20Copilot%20Chat%20Files/intune-mcp-prerequisites-and-checklists.md)
### 2.1 Create project
```bash
mkdir intune-mcp
cd intune-mcp
uv init
uv venv
uv add "mcp[cli]" httpx
```
***
### 2.2 Create file structure
From the **Build checklist (implementation)** section: [\[wheelsinc-...epoint.com\]](https://wheelsinc-my.sharepoint.com/personal/castn1_wheels_com/Documents/Microsoft%20Copilot%20Chat%20Files/intune-mcp-prerequisites-and-checklists.md)
intune_mcp_server.py
intune_backend.py
intune_graph_adapter.py
tests/
test_intune_adapter.py
test_integration.py
pyproject.toml
***
## 3. Implement the MCP server entrypoint
### 3.1 MCP server (STDIO only)
`intune_mcp_server.py`
```python
from mcp.server.fastmcp import FastMCP
from intune_backend import IntuneBackend
mcp = FastMCP("intune-mcp")
backend = IntuneBackend()
@mcp.tool()
async def intune_get_device(device_id: str):
"""Return core device metadata."""
return await backend.get_device(device_id)
@mcp.tool()
async def intune_get_device_last_check_in(device_id: str):
"""Return last Intune check-in timestamp."""
return await backend.get_last_check_in(device_id)
@mcp.tool()
async def intune_list_stale_devices(days: int):
"""List devices that have not checked in for N days."""
return await backend.list_stale_devices(days)
if __name__ == "__main__":
# STDIO transport is mandatory for safety
mcp.run(transport="stdio")
```
This aligns with the **recommended Phase 1 tool set**. [\[wheelsinc-...epoint.com\]](https://wheelsinc-my.sharepoint.com/personal/castn1_wheels_com/Documents/Microsoft%20Copilot%20Chat%20Files/intune-mcp-prerequisites-and-checklists.md)
***
## 4. Implement backend abstraction (safe by default)
### 4.1 Backend selector
`intune_backend.py`
```python
import os
from intune_graph_adapter import GraphIntuneAdapter
class IntuneBackend:
def __init__(self):
backend = os.getenv("INTUNE_BACKEND", "graph")
if backend == "graph":
self.adapter = GraphIntuneAdapter()
else:
raise ValueError("Unsupported backend")
async def get_device(self, device_id):
return await self.adapter.get_device(device_id)
async def get_last_check_in(self, device_id):
return await self.adapter.get_last_check_in(device_id)
async def list_stale_devices(self, days):
return await self.adapter.list_stale_devices(days)
```
This matches the **environmentbased backend selection** requirement. [\[wheelsinc-...epoint.com\]](https://wheelsinc-my.sharepoint.com/personal/castn1_wheels_com/Documents/Microsoft%20Copilot%20Chat%20Files/intune-mcp-prerequisites-and-checklists.md)
***
## 5. Implement the Microsoft Graph adapter
### 5.1 Graph adapter responsibilities
From the checklist, the adapter **must**: [\[wheelsinc-...epoint.com\]](https://wheelsinc-my.sharepoint.com/personal/castn1_wheels_com/Documents/Microsoft%20Copilot%20Chat%20Files/intune-mcp-prerequisites-and-checklists.md)
* Handle token acquisition
* Handle throttling (429)
* Map Graph fields → stable schemas
* Never return raw Graph payloads
***
### 5.2 Example adapter
`intune_graph_adapter.py`
```python
import httpx
import datetime
class GraphIntuneAdapter:
def __init__(self):
self.base_url = "https://graph.microsoft.com/v1.0"
async def get_device(self, device_id):
data = await self._get(f"/deviceManagement/managedDevices/{device_id}")
return {
"device_id": data["id"],
"device_name": data["deviceName"],
"os": data["operatingSystem"],
"owner": data.get("userPrincipalName"),
"compliance_state": data["complianceState"],
}
async def get_last_check_in(self, device_id):
data = await self._get(f"/deviceManagement/managedDevices/{device_id}")
return {
"device_id": data["id"],
"last_check_in": data["lastSyncDateTime"],
}
async def list_stale_devices(self, days):
cutoff = datetime.datetime.utcnow() - datetime.timedelta(days=days)
devices = await self._get("/deviceManagement/managedDevices")
return [
{
"device_id": d["id"],
"device_name": d["deviceName"],
"last_check_in": d["lastSyncDateTime"],
}
for d in devices["value"]
if datetime.datetime.fromisoformat(
d["lastSyncDateTime"].replace("Z", "")
) < cutoff
]
async def _get(self, path):
# token acquisition omitted here by design (handled securely)
async with httpx.AsyncClient(timeout=10) as client:
r = await client.get(self.base_url + path, headers=self._headers())
if r.status_code == 429:
raise Exception("Graph throttling encountered")
r.raise_for_status()
return r.json()
def _headers(self):
return {"Authorization": "Bearer <token>"}
```
***
## 6. Logging and audit controls (mandatory)
From the prerequisites: [\[wheelsinc-...epoint.com\]](https://wheelsinc-my.sharepoint.com/personal/castn1_wheels_com/Documents/Microsoft%20Copilot%20Chat%20Files/intune-mcp-prerequisites-and-checklists.md)
* **STDERRonly logging**
* **Pertool audit record**
* **No secrets logged**
Implement:
* tool name
* parameters (redacted)
* result size
* correlation ID
**Failure to do this blocks Phase 1 completion**
***
## 7. Testing gates
### 7.1 Unit tests
From the checklist: [\[wheelsinc-...epoint.com\]](https://wheelsinc-my.sharepoint.com/personal/castn1_wheels_com/Documents/Microsoft%20Copilot%20Chat%20Files/intune-mcp-prerequisites-and-checklists.md)
* Parser behavior
* Field mapping
* Error handling
### 7.2 Integration tests
* Run against **nonproduction tenant**
* Compare MCP output vs Intune portal for:
* compliant device
* noncompliant device
* stale device
**Output:** Test evidence retained
***
## 8. Pilot rollout
From Phase 5 checklist: [\[wheelsinc-...epoint.com\]](https://wheelsinc-my.sharepoint.com/personal/castn1_wheels_com/Documents/Microsoft%20Copilot%20Chat%20Files/intune-mcp-prerequisites-and-checklists.md)
* Enable MCP for pilot users only
* Validate top service desk questions:
* “Devices not checking in”
* “Devices assigned to disabled users”
* Test rollback by disabling Graph backend
***
## 9. Definition of Done (Phase 1)
All must be true: [\[wheelsinc-...epoint.com\]](https://wheelsinc-my.sharepoint.com/personal/castn1_wheels_com/Documents/Microsoft%20Copilot%20Chat%20Files/intune-mcp-prerequisites-and-checklists.md)
* No write tools exist
* Stable response schemas
* Friendly errors
* Complete audit logs
* Tests passing
* Security signoff recorded
* Runbook published
***
## What you have when this is finished
* A **real MCP server**
* Backed by **Microsoft Graph**
* Answering **live Intune questions**
* Safe, auditable, and productiondefensible
* Ready for Phase 2 correlation with Identity + Inventory MCPs [\[wheelsinc-...epoint.com\]](https://wheelsinc-my.sharepoint.com/personal/castn1_wheels_com/Documents/Microsoft%20Copilot%20Chat%20Files/CoPilot%20Generated%20Deployment%20Plan.md)
***