chore: archive legacy Identity, Workday, and Intune folders
- Move Identity/, Workday/, Intune/ to archive/ (superseded by nexus-mcp shards) - Move 'Local Setup.md' to archive/ (superseded by nexus-mcp/Local-Setup.md) - Add archive/README.md explaining migration and preserved content - Clean repository structure: only nexus-mcp, documentation, and .github remain active All legacy functionality migrated to nexus-mcp sharded architecture. Archived folders preserved for reference and historical context. Refs: SESSION_SNAPSHOT_2026-04-13.md
This commit is contained in:
@@ -0,0 +1,339 @@
|
||||
# Step‑by‑Step Guide: Building an Intune MCP Server (Phase 1 – Read‑Only)
|
||||
|
||||
***
|
||||
|
||||
## 0. What you are building (anchor this first)
|
||||
|
||||
From both documents, the **Intune MCP** is defined as:
|
||||
|
||||
> A read‑only MCP server that exposes **live Microsoft Intune device state** (inventory, compliance, ownership, last check‑in) 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):
|
||||
|
||||
* **Read‑only only** in Phase 1
|
||||
* **Microsoft Graph is the backend**
|
||||
* **Stable tool contracts** (no raw Graph payloads)
|
||||
* **STDIO MCP transport**
|
||||
* **Per‑tool 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 non‑production 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:
|
||||
* ✅ Certificate‑based 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 **environment‑based 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)
|
||||
|
||||
* **STDERR‑only logging**
|
||||
* **Per‑tool 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 **non‑production tenant**
|
||||
* Compare MCP output vs Intune portal for:
|
||||
* compliant device
|
||||
* non‑compliant 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 sign‑off 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 production‑defensible
|
||||
* 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)
|
||||
|
||||
***
|
||||
@@ -0,0 +1,214 @@
|
||||
# Intune / Device Management MCP — Deployment & Initial Guidance
|
||||
|
||||
## Purpose
|
||||
|
||||
This document provides initial guidance for deploying a **read‑only (and later controlled‑action) Intune MCP** that exposes **live device state** to AI-assisted IT workflows.
|
||||
|
||||
The Intune MCP is designed to:
|
||||
|
||||
* Improve **device lifecycle visibility**
|
||||
* Reduce reliance on **manual exports and static reports**
|
||||
* Enable **cross-system reasoning** with Identity, Inventory, and Service Desk systems
|
||||
|
||||
It does **not** replace Microsoft Intune, Autopilot, or existing device management processes.
|
||||
|
||||
***
|
||||
|
||||
## Why this matters in our environment
|
||||
|
||||
Your team already manages the following via Microsoft Intune:
|
||||
|
||||
* Device enrollment and compliance
|
||||
* Device refresh and replacement cycles
|
||||
* Device wipes, retirements, and repurposing
|
||||
* Devices that stop checking in or fail to refresh
|
||||
|
||||
These activities are explicitly documented and actively discussed in your Intune and device review materials, including Autopilot deployment and device check‑in workflows. [\[LEARN Auto...It's Hot) | Loop\]](https://loop.cloud.microsoft/p/eyJ1IjoiaHR0cHM6Ly93aGVlbHNpbmMtbXkuc2hhcmVwb2ludC5jb20vcGVyc29uYWwvY2FzdG4xX3doZWVsc19jb20%2FbmF2PWN6MGxNa1p3WlhKemIyNWhiQ1V5Um1OaGMzUnVNU1UxUm5kb1pXVnNjeVUxUm1OdmJTWmtQV0lsTWpGdFFrZ3lWekZSYUVaVlQwUlBibU5GVFd4NlowSlBWMVZCVWpCdVVERkNRWFZXVVVNM1UyTm9NSFZ0UkdFM1NqaEtSRFExVkRWM2FrMTViRU5WVW10aEptWTlNREUzUnpNMFJ6SXlUMDVYTjBSQlRVWkxRbFpCU2tWRFVVVk9OVGRWVEZoSVF5WmpQU1V5UmcifQ%3D%3D), [\[Intune | Word\]](https://wheelsinc-my.sharepoint.com/personal/nkicchan_wheels_com/_layouts/15/Doc.aspx?sourcedoc=%7B5E3AC388-A887-4AA7-AD62-219F56B9B96E%7D\&file=Intune.docx\&action=default\&mobileredirect=true\&DefaultItemOpen=1)
|
||||
|
||||
The problem today is **visibility friction**, not capability.
|
||||
|
||||
***
|
||||
|
||||
## What MCP enables for Intune
|
||||
|
||||
With an Intune MCP, AI clients can ask **live, contextual questions** such as:
|
||||
|
||||
* “Which laptops are enrolled but haven’t checked in for 30 days?”
|
||||
* “Show devices that are compliant in Intune but missing from inventory.”
|
||||
* “Which devices belong to disabled users?”
|
||||
* “Retire this device and flag it as eligible for repurpose.” *(future, controlled action)*
|
||||
|
||||
Unlike CSV exports or copied portal views, MCP queries **current Intune state** at the time of the request.
|
||||
|
||||
***
|
||||
|
||||
## Scope and guardrails
|
||||
|
||||
### In scope
|
||||
|
||||
* Read access to device state, compliance, and activity metadata
|
||||
* Correlation with Identity MCP and Inventory MCP
|
||||
* Human-approved device lifecycle actions (future phase)
|
||||
|
||||
### Explicitly out of scope (initially)
|
||||
|
||||
* Autonomous device wipes
|
||||
* Policy creation or modification
|
||||
* Bulk or unattended actions
|
||||
* Replacement of Autopilot or Intune portal workflows
|
||||
|
||||
***
|
||||
|
||||
## Definitions
|
||||
|
||||
| Term | Definition |
|
||||
| ------------------- | ------------------------------------------------------------------------------- |
|
||||
| **Intune MCP** | An MCP server that exposes Microsoft Intune device context and approved actions |
|
||||
| **Enrollment** | Device registration into Intune (Autopilot or manual) |
|
||||
| **Compliance** | Device posture relative to Intune policy |
|
||||
| **Check‑in** | Last successful device contact with Intune |
|
||||
| **Lifecycle state** | Active, stale, retired, or eligible-for-repurpose |
|
||||
|
||||
***
|
||||
|
||||
## Deployment phases (high level)
|
||||
|
||||
|
||||
|
||||
***
|
||||
|
||||
## Phase 0 — Governance and alignment
|
||||
|
||||
**Objective:** Define what the Intune MCP is allowed to observe and do before any build work begins.
|
||||
|
||||
### Steps
|
||||
|
||||
1. Identify stakeholders:
|
||||
* Endpoint / Intune owners
|
||||
* IAM / Identity MCP owners
|
||||
* Security
|
||||
* Deskside / IT Ops
|
||||
|
||||
2. Agree on non-negotiables:
|
||||
* Intune remains the authoritative device management system
|
||||
* MCP is an **interface**, not a policy engine
|
||||
* Initial access is **read-only**
|
||||
* Any device action requires human approval
|
||||
|
||||
✅ **Exit criteria:** Written agreement on read vs write boundaries.
|
||||
|
||||
***
|
||||
|
||||
## Phase 1 — Read‑only Intune MCP
|
||||
|
||||
**Objective:** Expose live device state safely.
|
||||
|
||||
### Example read-only tools
|
||||
|
||||
The Intune MCP should initially expose tools equivalent to what your team already checks manually in the Intune portal:
|
||||
|
||||
* `intune.getDevice(deviceId)`
|
||||
* `intune.listDevicesByUser(userId)`
|
||||
* `intune.getDeviceCompliance(deviceId)`
|
||||
* `intune.getLastCheckIn(deviceId)`
|
||||
* `intune.listStaleDevices(days)`
|
||||
|
||||
These map directly to enrollment, compliance, and check‑in data already used during Autopilot demos and device investigations. [\[LEARN Auto...It's Hot) | Loop\]](https://loop.cloud.microsoft/p/eyJ1IjoiaHR0cHM6Ly93aGVlbHNpbmMtbXkuc2hhcmVwb2ludC5jb20vcGVyc29uYWwvY2FzdG4xX3doZWVsc19jb20%2FbmF2PWN6MGxNa1p3WlhKemIyNWhiQ1V5Um1OaGMzUnVNU1UxUm5kb1pXVnNjeVUxUm1OdmJTWmtQV0lsTWpGdFFrZ3lWekZSYUVaVlQwUlBibU5GVFd4NlowSlBWMVZCVWpCdVVERkNRWFZXVVVNM1UyTm9NSFZ0UkdFM1NqaEtSRFExVkRWM2FrMTViRU5WVW10aEptWTlNREUzUnpNMFJ6SXlUMDVYTjBSQlRVWkxRbFpCU2tWRFVVVk9OVGRWVEZoSVF5WmpQU1V5UmcifQ%3D%3D), [\[Intune | Word\]](https://wheelsinc-my.sharepoint.com/personal/nkicchan_wheels_com/_layouts/15/Doc.aspx?sourcedoc=%7B5E3AC388-A887-4AA7-AD62-219F56B9B96E%7D\&file=Intune.docx\&action=default\&mobileredirect=true\&DefaultItemOpen=1)
|
||||
|
||||
### Validation
|
||||
|
||||
* Compare MCP output to Intune portal views for known devices
|
||||
* Confirm no write operations are exposed
|
||||
|
||||
✅ **Exit criteria:** MCP answers device-state questions without altering Intune data.
|
||||
|
||||
***
|
||||
|
||||
## Phase 2 — Cross-system correlation
|
||||
|
||||
**Objective:** Combine Intune context with Identity and Inventory MCPs.
|
||||
|
||||
### Example correlated questions
|
||||
|
||||
* Devices active in Intune but owned by disabled users (Identity MCP)
|
||||
* Devices compliant in Intune but missing from inventory records
|
||||
* Devices enrolled but not assigned to a user
|
||||
* Devices enrolled but never completed Autopilot setup
|
||||
|
||||
This phase directly addresses the “devices not checking in / not refreshing” issues discussed in device review meetings and documentation. [\[LEARN Auto...It's Hot) | Loop\]](https://loop.cloud.microsoft/p/eyJ1IjoiaHR0cHM6Ly93aGVlbHNpbmMtbXkuc2hhcmVwb2ludC5jb20vcGVyc29uYWwvY2FzdG4xX3doZWVsc19jb20%2FbmF2PWN6MGxNa1p3WlhKemIyNWhiQ1V5Um1OaGMzUnVNU1UxUm5kb1pXVnNjeVUxUm1OdmJTWmtQV0lsTWpGdFFrZ3lWekZSYUVaVlQwUlBibU5GVFd4NlowSlBWMVZCVWpCdVVERkNRWFZXVVVNM1UyTm9NSFZ0UkdFM1NqaEtSRFExVkRWM2FrMTViRU5WVW10aEptWTlNREUzUnpNMFJ6SXlUMDVYTjBSQlRVWkxRbFpCU2tWRFVVVk9OVGRWVEZoSVF5WmpQU1V5UmcifQ%3D%3D)
|
||||
|
||||
✅ **Exit criteria:** Cross-system insights are accurate and explainable.
|
||||
|
||||
***
|
||||
|
||||
## Phase 3 — Controlled lifecycle actions (future)
|
||||
|
||||
**Objective:** Introduce **human-approved** device actions.
|
||||
|
||||
### Allowed actions (initial)
|
||||
|
||||
* Retire device
|
||||
* Mark device as eligible for repurpose
|
||||
* Trigger a reset *only with explicit approval*
|
||||
|
||||
### Guardrail model
|
||||
|
||||
AI identifies device issue
|
||||
→ AI explains current state (Intune data)
|
||||
→ Human approves action
|
||||
→ MCP executes single action
|
||||
→ Ticket and audit log updated
|
||||
|
||||
No unattended execution.
|
||||
|
||||
✅ **Exit criteria:** Every action is approved, logged, and traceable.
|
||||
|
||||
***
|
||||
|
||||
## Phase 4 — Audit and steady state
|
||||
|
||||
### Controls
|
||||
|
||||
* Request-level logging for all MCP calls
|
||||
* Tool definitions version-controlled
|
||||
* Quarterly review of exposed fields and actions
|
||||
* Re-validation after Intune / Autopilot process changes
|
||||
|
||||
***
|
||||
|
||||
## Why this is powerful
|
||||
|
||||
Traditional workflows rely on:
|
||||
|
||||
* Exported device lists
|
||||
* Static reports
|
||||
* Manual portal navigation
|
||||
|
||||
An Intune MCP enables:
|
||||
|
||||
* **Live device state**
|
||||
* **Contextual reasoning**
|
||||
* **Faster, more accurate lifecycle decisions**
|
||||
|
||||
✅ This directly improves device lifecycle accuracy without increasing operational risk.
|
||||
|
||||
***
|
||||
|
||||
## Relationship to other MCPs
|
||||
|
||||
| MCP | Role |
|
||||
| -------------- | ------------------------------------ |
|
||||
| Workday MCP | Who *should* have a device |
|
||||
| Identity MCP | Who *does* have access |
|
||||
| **Intune MCP** | What the device is actually doing |
|
||||
| Inventory MCP | Where the device is in its lifecycle |
|
||||
|
||||
The Intune MCP is the **ground truth for device reality**.
|
||||
|
||||
***
|
||||
|
||||
## One‑sentence takeaway
|
||||
|
||||
> The Intune MCP gives AI real‑time visibility into device state, turning enrollment, compliance, and refresh decisions from guesswork into facts.
|
||||
|
||||
***
|
||||
@@ -0,0 +1,217 @@
|
||||
---
|
||||
title: "Intune MCP - prerequisites and implementation checklists"
|
||||
description: "Practical prerequisites and phase checklists to build an Intune MCP server using the proven Identity MCP pattern."
|
||||
type: "Implementation Guide"
|
||||
version: "v1"
|
||||
author: "N. Castaldi"
|
||||
date: "2026-03-11"
|
||||
---
|
||||
|
||||
## Purpose
|
||||
|
||||
This guide defines exactly what is needed to build an Intune MCP server using the same
|
||||
delivery pattern that worked for Identity MCP:
|
||||
|
||||
- Phased rollout
|
||||
- Read-only first
|
||||
- Least privilege and explicit approvals
|
||||
- Contract-first tool design
|
||||
- Unit + integration test gates before production
|
||||
|
||||
## What to replicate from Identity MCP
|
||||
|
||||
Use these proven patterns from the Identity MCP implementation as non-negotiables:
|
||||
|
||||
- Backend abstraction with a safe default backend for local contract testing
|
||||
- Environment-based backend selection
|
||||
- Tool-level input validation and friendly error messages
|
||||
- STDERR-only logging for MCP STDIO safety
|
||||
- Per-tool audit logging (tool, params, result type, result size)
|
||||
- Separate unit tests and integration smoke tests
|
||||
- Read-only phase before any write/action capability
|
||||
|
||||
## Scope for Intune MCP (Phase 1)
|
||||
|
||||
Phase 1 should be read-only device context only.
|
||||
|
||||
- Allowed: device inventory, compliance state, ownership, last check-in, management state
|
||||
- Not allowed: wipe, retire, sync, policy changes, enrollment profile changes
|
||||
|
||||
## Prerequisites checklist
|
||||
|
||||
Complete all prerequisites before implementation starts.
|
||||
|
||||
### A. Governance and ownership
|
||||
|
||||
- [ ] Product owner assigned (Endpoint/Intune)
|
||||
- [ ] Security owner assigned
|
||||
- [ ] Operational owner assigned (Service Desk or Endpoint Ops)
|
||||
- [ ] Approved operation list created (read operations only for Phase 1)
|
||||
- [ ] Read vs write boundary documented and signed off
|
||||
- [ ] Audit and retention requirements documented
|
||||
|
||||
### B. Microsoft tenant and licensing
|
||||
|
||||
- [ ] Intune tenant active and healthy
|
||||
- [ ] Microsoft Graph access for Intune data approved
|
||||
- [ ] Required roles identified for app consent and validation
|
||||
- [ ] Non-production tenant or pilot group available for testing
|
||||
|
||||
### C. Identity and authentication model
|
||||
|
||||
- [ ] App registration created for Intune MCP
|
||||
- [ ] Authentication method selected:
|
||||
- [ ] Certificate-based auth (preferred)
|
||||
- [ ] Client secret (temporary/non-production only)
|
||||
- [ ] Service principal created and documented
|
||||
- [ ] Token lifetime and credential rotation policy defined
|
||||
|
||||
### D. Graph API permissions (least privilege)
|
||||
|
||||
Start with read-only permissions, then add only what is required.
|
||||
|
||||
- [ ] `DeviceManagementManagedDevices.Read.All`
|
||||
- [ ] `DeviceManagementConfiguration.Read.All` (only if config/policy context is needed)
|
||||
- [ ] `Directory.Read.All` (only if user/device directory joins are needed)
|
||||
- [ ] Admin consent granted by approved role holder
|
||||
- [ ] Permission justification recorded for each scope
|
||||
|
||||
### E. Platform and runtime
|
||||
|
||||
- [ ] Python 3.10+ runtime available
|
||||
- [ ] Project scaffold created (same pattern as Identity MCP)
|
||||
- [ ] Dependency management chosen and documented (`uv` + `pyproject.toml` recommended)
|
||||
- [ ] Logging destination defined (file/central sink)
|
||||
- [ ] Secrets stored in approved secret store (never in code or plain env files)
|
||||
|
||||
### F. Data contract and tool design
|
||||
|
||||
- [ ] Tool names and response schemas drafted
|
||||
- [ ] Field-level data minimization applied
|
||||
- [ ] Error contract defined (`not found`, `access denied`, `timeout`, `throttled`)
|
||||
- [ ] PII handling and redaction behavior documented
|
||||
|
||||
### G. Testing prerequisites
|
||||
|
||||
- [ ] Known test devices identified (compliant, non-compliant, stale, retired)
|
||||
- [ ] Known test users identified (active, disabled, missing owner)
|
||||
- [ ] Integration test credentials configured securely
|
||||
- [ ] Expected results captured from Intune portal for baseline comparison
|
||||
|
||||
## Recommended Intune MCP tool set (Phase 1)
|
||||
|
||||
Keep the same contract style used in Identity MCP.
|
||||
|
||||
```text
|
||||
intune.get_device(device_id)
|
||||
intune.get_device_by_name(device_name)
|
||||
intune.list_devices_by_user(user_principal_name)
|
||||
intune.get_device_compliance(device_id)
|
||||
intune.get_device_last_check_in(device_id)
|
||||
intune.list_stale_devices(days)
|
||||
intune.search_devices(query, limit)
|
||||
```
|
||||
|
||||
## Build checklist (implementation)
|
||||
|
||||
### Phase 0 - Kickoff and design
|
||||
|
||||
- [ ] Create approved operations list and sign-offs
|
||||
- [ ] Confirm Graph permission set and admin consent
|
||||
- [ ] Finalize tool contracts (input/output examples)
|
||||
- [ ] Define production and non-production configuration values
|
||||
|
||||
### Phase 1 - Project scaffold
|
||||
|
||||
- [ ] Create files:
|
||||
- [ ] `intune_mcp_server.py`
|
||||
- [ ] `intune_backend.py`
|
||||
- [ ] `intune_graph_adapter.py`
|
||||
- [ ] `tests/test_intune_adapter.py`
|
||||
- [ ] `tests/test_integration.py`
|
||||
- [ ] `pyproject.toml`
|
||||
- [ ] Add MCP server entrypoint script
|
||||
- [ ] Add in-memory backend for local safe mode
|
||||
- [ ] Add environment-based backend switch (`INTUNE_BACKEND=memory|graph`)
|
||||
|
||||
### Phase 2 - Graph adapter and contracts
|
||||
|
||||
- [ ] Implement token acquisition and refresh logic
|
||||
- [ ] Implement retry with backoff for Graph throttling (429)
|
||||
- [ ] Implement timeout handling with clear user-safe messages
|
||||
- [ ] Map Graph fields to stable MCP response schemas
|
||||
- [ ] Ensure null-safe handling for missing owner/primary user values
|
||||
|
||||
### Phase 3 - Observability and safety
|
||||
|
||||
- [ ] Implement STDERR-only logging for STDIO transport safety
|
||||
- [ ] Add audit log record per tool invocation
|
||||
- [ ] Redact sensitive fields in logs
|
||||
- [ ] Add correlation/request IDs to logs
|
||||
|
||||
### Phase 4 - Test gates
|
||||
|
||||
- [ ] Unit tests pass for parser/mapper/error-handling behavior
|
||||
- [ ] Integration smoke tests pass against non-production tenant
|
||||
- [ ] MCP output compared to Intune portal for sampled devices
|
||||
- [ ] Negative tests pass (`not found`, no permission, timeout, throttling)
|
||||
|
||||
### Phase 5 - Pilot rollout
|
||||
|
||||
- [ ] Enable read-only tools for pilot users only
|
||||
- [ ] Validate top 10 service desk queries using Intune MCP responses
|
||||
- [ ] Collect accuracy and latency metrics
|
||||
- [ ] Run rollback test (disable graph backend, return to safe mode)
|
||||
|
||||
## Definition of done checklist (Phase 1 release)
|
||||
|
||||
All items must be true before declaring Intune MCP Phase 1 complete.
|
||||
|
||||
- [ ] No write/action tools are exposed
|
||||
- [ ] All Phase 1 tools return stable schemas
|
||||
- [ ] Error messages are friendly and non-leaky
|
||||
- [ ] Audit logs are complete and searchable
|
||||
- [ ] Unit + integration tests are green
|
||||
- [ ] Security sign-off is recorded
|
||||
- [ ] Operational runbook and escalation path are published
|
||||
|
||||
## Phase 2 preview (cross-system correlation)
|
||||
|
||||
After Phase 1 is stable, add correlation with Identity MCP and Inventory MCP.
|
||||
|
||||
- [ ] Devices assigned to disabled users
|
||||
- [ ] Devices compliant in Intune but missing in inventory
|
||||
- [ ] Devices stale in Intune and still tied to active users
|
||||
|
||||
No automated remediation in this phase.
|
||||
|
||||
## Phase 3 preview (controlled actions)
|
||||
|
||||
Only after explicit approval and SOP mapping:
|
||||
|
||||
- [ ] `intune.retire_device(device_id)` (human approval gate required)
|
||||
- [ ] `intune.sync_device(device_id)` (rate-limited and logged)
|
||||
- [ ] Additional actions only with Security + Endpoint sign-off
|
||||
|
||||
Guardrail sequence must always be:
|
||||
|
||||
1. AI recommends action
|
||||
2. Human approves action
|
||||
3. MCP executes one action
|
||||
4. Result is written to audit trail (and ticket when integrated)
|
||||
|
||||
## Common failure points to prevent early
|
||||
|
||||
- Over-scoped Graph permissions in initial release
|
||||
- No throttling strategy for Graph API calls
|
||||
- Returning raw Graph payloads instead of stable response contracts
|
||||
- Missing comparison tests against Intune portal values
|
||||
- Logging secrets or full token payloads
|
||||
- Introducing write actions before read-only maturity
|
||||
|
||||
## Suggested next artifact set
|
||||
|
||||
Create these two follow-on docs next:
|
||||
|
||||
- `intune-mcp-install-guide.md` (step-by-step deployment)
|
||||
- `intune-mcp-test-plan.md` (test matrix and evidence checklist)
|
||||
Reference in New Issue
Block a user