Skip to content

Report API and MCP

IntensiveReports can serve its reports to scripts and other tools (the report API, /ir-api/v1) and to AI assistants (the MCP server, /ir-mcp). Both read the same data as the pages, through the same checks. This page is the administrator’s side. How clients call the API is in API and MCP.

Everything here is on Settings > API access and needs an IntensiveReports administrator.

The API is off after installation. While it is off, every API, MCP and API sign-in address answers 404, as if it did not exist.

Turn on Report API at the top of the tab. The tab also shows the MCP server’s address for AI assistants.

Every script, tool or assistant gets its own client. Press Add client and fill in:

FieldMeaning
Namewho or what uses it, for example Monitoring script or AI assistant for the helpdesk
Sign-inToken, Certificate or Entra ID (user, group or app); see below
PresetReader: read everything. Operator: read and refresh everything. AI assistant: read only the areas you tick. Custom: set each area yourself.
Access per product areafor each area (Entra ID, Security, Intune, Exchange Online, SharePoint Online, OneDrive, Teams and collaboration, Licensing, Compliance, Tenant): No access, Read, Read and refresh or Read, refresh and run scans. Run scan includes refresh, refresh includes read.
Never show these reportsreports this client never sees, whatever its access, for example reports you do not want an AI assistant to read. Reports built from a hidden report’s rows are hidden too; the tab lists them.
Expires after (days)365 by default; 0 means never. A client past its expiry is refused.

A client sees only the reports of the areas it may read. Any other report answers 404, exactly like a report that does not exist. An action above its access (for example a refresh with read access) answers 403. Which report belongs to which area is shown on each report’s page in the report reference.

IntensiveReports generates a token of the form ir1.<client id>.<secret> and shows it once, when you save the client. Copy it then; IntensiveReports keeps only a hash of it. The client sends it as Authorization: Bearer <token>.

For automation without a stored secret. Upload the client’s public certificate (.cer, .crt or .pem). The client signs its own short-lived token (at most one hour) with the private key and sends it as Authorization: Bearer <JWT>. The token’s audience must be the site’s address, so set IntensiveReportsConfig:Api:PublicUrl (or pin AllowedHosts); otherwise certificate clients are refused.

setup\New-IrApiClientAssertion.ps1 creates such a token, for testing or for scripts:

Terminal window
.\setup\New-IrApiClientAssertion.ps1 -ClientId <client id> -BaseUrl https://reports.example.com -Thumbprint <thumbprint>

It reads the certificate from the user’s store (-StoreLocation LocalMachine for the machine store) or from a file (-PfxPath), and makes a token valid for 30 minutes (-LifetimeMinutes, 1 to 60).

People, groups or apps sign in with Entra ID instead of a token. This is how AI assistants such as Claude.ai, Claude Desktop or Claude Code connect with each user’s own account. It needs a second app registration, IntensiveReports API, which holds no Microsoft Graph permissions; it only identifies the API.

  1. Create it, as a Global Administrator or Application Administrator:

    Terminal window
    .\setup\New-IrApiResourceApp.ps1 -AssignUser admin@example.com
    ParameterMeaning
    -AssignUser, -AssignGroup, -AssignAppgive users (sign-in name), groups (object ID) or apps (app ID) the role IR.Api.Access. Only assigned identities get a token at all.
    -NewClientSecretcreates a client secret for the Claude.ai or Claude Desktop custom connector (shown once; valid 6 months, -SecretMonths to change)
    -ClaudeCodeCallbackPortthe local callback port for Claude Code (default 8080)
    -DisplayNamename of the app registration (default IntensiveReports API)

    The script is safe to run again, for example to assign more users.

  2. Put the printed application ID into appsettings.json and restart the app:

    "IntensiveReportsConfig": { "Api": { "Entra": { "ApiAppId": "<printed app id>" } } }
  3. On Settings > API access, add a client with sign-in Entra ID (user, group or app) for each user, group or app, and give it its access. Entra ID proves who calls; the client’s access and hidden reports decide what it reads.

The tab shows how each AI assistant connects. Details for users: API and MCP.

The client list shows each client’s name, access, sign-in type, expiry and Last used.

ToDo
stop a client for a whileswitch off Enabled
replace a lost or leaked tokenNew token: the old token stops working at once
change access or expiryEdit
remove a clientDelete: its token stops working at once

Every API and MCP call is written to App_Data\api-audit\<yyyy-MM-dd>.jsonl, one line per call: time, client, address, method, path, report, action, status, number of rows and details. Refusals (401, 403, 404, 429) are logged too. Files are kept for 90 days. Back them up with the rest of App_Data if you need them longer.

KeyDefaultMeaning
IntensiveReportsConfig:Api:PublicUrlemptythe site’s public address; needed for certificate clients and MCP sign-in with Entra ID
IntensiveReportsConfig:Api:RequestsPerMinute120requests a minute per client
IntensiveReportsConfig:Api:AnonymousRequestsPerMinute20requests a minute per address without a valid token
IntensiveReportsConfig:Api:Entra:ApiAppIdemptythe IntensiveReports API app; turns on Entra sign-in for clients
IntensiveReportsConfig:Api:Entra:TenantIdthe data tenantthe tenant of that app
IntensiveReportsConfig:Api:Entra:AccessRoleIR.Api.Accessthe app role callers need

Above the limits, the API answers 429 with Retry-After.