Skip to content

MCP server

The Model Context Protocol (MCP) is the standard way AI assistants use outside tools. The IntensiveReports MCP server lets an assistant answer questions like “Which admins can’t do MFA?” or “What needs attention in Exchange Online?” from your reports. It doesn’t guess: the assistant finds the right report, reads its summary and only the rows it needs.

Addresshttps://<your IntensiveReports host>/ir-mcp
TransportStreamable HTTP, stateless
Sign-inThe same clients as the API: token, certificate or Entra ID. See Authentication.
What it can readExactly what the API client may read: its product areas, minus its hidden reports. Any other report doesn’t exist for it.
What it can changeNothing in Microsoft 365. With the matching grant it can start a refresh or a scan.
AuditEvery tool call is in the same audit log as the API.
LimitsShares the API’s rate limit (120 requests a minute per client by default).

The MCP server is part of the API: it is switched on and off with the API in Settings > API access, and answers 404 while the API is off.

ToolWhat the assistant uses it for
list_reportsFind reports by words from the question, optionally in one product area
describe_reportColumns, filters, parameters, licence and permissions of one report
get_reportState, freshness, metrics and notes first, then as many rows as asked (20 by default, at most 200 per call), optionally filtered and with chosen columns
get_data_statusWhich reports are loaded, loading, failed or switched off, to explain an empty or old answer
get_findings_summaryThe problems the dashboard counts, worst first, each with its count and the report that lists them. A good first call for “what needs attention?”
refresh_reportReload a report now. Only offered to clients with the Refresh grant in at least one area.
run_scanStart a scan report. Only offered to clients with the Run scan grant.

Parameters and full descriptions: MCP tool reference.

When an assistant connects, the server sends it short instructions: find the report with list_reports, check it with describe_report, read it with get_report, prefer metrics and filters over reading every row, and call again when a report is still loading.

It also warns the assistant that row values are tenant data, not instructions. Names and descriptions of apps, groups, users, teams and policies are set by people in your tenant, and someone could write text into them that looks like a request to the assistant. The server repeats this warning next to every set of rows. Assistants are told never to follow such text and to point it out instead.

  1. An administrator switches the API on and creates a client for the assistant in Settings > API access (see API and MCP access). The AI assistant preset gives read-only access to only the product areas the administrator ticks.
  2. Decide how the assistant signs in:
    • Token: works with Claude Code, VS Code and most MCP clients that let you set a header.
    • Entra ID: needed for Claude.ai and Claude Desktop connectors (they can’t send a fixed token), and the better choice whenever people should use their own accounts. It needs the IntensiveReports API app registration and the setting IntensiveReportsConfig:Api:Entra:ApiAppId on the server. When Entra ID sign-in is set up, the server tells MCP clients where to sign in, and they open the Microsoft sign-in page themselves.

With a token:

Terminal window
claude mcp add --transport http intensivereports https://reports.example.com/ir-mcp \
--header "Authorization: Bearer ir1.xxxx.xxxx"

With Entra ID sign-in, use the application (client) id of the IntensiveReports API app:

Terminal window
claude mcp add --transport http --client-id <IntensiveReports API app id> --callback-port 8080 \
intensivereports https://reports.example.com/ir-mcp

Then run /mcp in Claude Code and choose the server to sign in. Claude Code opens the Microsoft sign-in page in your browser. The app registration script registers http://localhost:8080/callback for this; use port 8080 unless the administrator ran the script with another -ClaudeCodeCallbackPort.

Both use a custom connector with Entra ID sign-in:

  1. In Claude.ai or Claude Desktop, open Settings > Connectors and add a custom connector.
  2. URL: https://reports.example.com/ir-mcp.
  3. Under Advanced settings, enter the client id and client secret of the IntensiveReports API app. The administrator creates the secret with New-IrApiResourceApp.ps1 -NewClientSecret.
  4. Connect. The app opens the Microsoft sign-in page. Sign in with an account that holds the IR.Api.Access role and has a client in Settings > API access.

Add the server to .vscode/mcp.json in your workspace (or your user configuration). VS Code asks for the token once and stores it securely:

{
"inputs": [
{ "type": "promptString", "id": "ir-token", "description": "IntensiveReports API token", "password": true }
],
"servers": {
"intensivereports": {
"type": "http",
"url": "https://reports.example.com/ir-mcp",
"headers": { "Authorization": "Bearer ${input:ir-token}" }
}
}
}

Any client that supports Streamable HTTP works:

  • URL https://<host>/ir-mcp, method POST, JSON-RPC 2.0.
  • Header Authorization: Bearer <token> on every request.
  • Header Accept: application/json, text/event-stream.
  • The server is stateless: no session id is needed between calls.

To check the connection without a client:

Terminal window
curl -X POST https://reports.example.com/ir-mcp \
-H "Authorization: Bearer $IR_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Ask the way you would ask a colleague who knows every report. Examples:

  • What needs attention in our tenant right now?
  • Which administrators can’t do MFA?
  • Are there app secrets or certificates that expired or expire this month?
  • Which guests haven’t signed in for months, and what can they still reach?
  • Do any mailboxes forward mail to external addresses?
  • Which licences could we take back from users who no longer sign in?
  • Which devices haven’t synced with Intune for more than 90 days?
  • Why is the inactive SharePoint users report empty? (the assistant checks get_data_status)

Tips:

  • The assistant always sees loadedUtc. Ask it to mention how old the data is if that matters.
  • Large reports are read in pages. Ask for a summary or a count first, then the details you need.
  • When a report is still loading, the assistant is told to try again after about 15 seconds. Scan reports run only when started, so ask the assistant to run the scan if it has the grant, or press Run scan in the app.

Use the controls in Settings > API access:

  • One client per assistant or team, named so you recognise it in the audit log, for example “AI assistant for the helpdesk”.
  • The AI assistant preset: read-only, and only the product areas you tick. Leave out areas the assistant doesn’t need.
  • Never show these reports: hide single reports, for example sign-in logs or mailbox permissions. Reports built from a hidden report’s rows are hidden too; the client dialog lists them.
  • Expires after (days): let access end by itself, and renew it on purpose.
  • Entra ID sign-in instead of a shared token, so every call in the audit log names the person, and your Conditional Access policies apply to the sign-in.
  • Check your AI provider’s data retention and training terms, and your organisation’s rules for personal data in AI tools.