> For the complete documentation index, see [llms.txt](https://docs.openiam.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.openiam.com/administration-guide/federation/mcp-server/mcp-server-reference.md).

# MCP tools, errors, properties and limits

The 17 tools of the OpenIAM MCP server with their scopes, arguments and results, the catalog document, the HTTP and tool error codes including the agent admission reasons, every org.openiam.mcp proper

## What this covers

The values behind [Connect AI assistants through the MCP server](/administration-guide/federation/mcp-server.md): what each tool of the Model Context Protocol (MCP) server takes and returns, how the server refuses a request, the properties that tune it, what it writes to the audit log and to Prometheus, and the limits it enforces. Look things up here; the procedure is on the how-to page.

## The endpoints the server answers

| Path                                                                                    | Method          | Answer                                                                                                                                                                                                                                                                                 |
| --------------------------------------------------------------------------------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `/mcp`                                                                                  | `POST`          | JSON-RPC 2.0 messages of the MCP protocol: `initialize`, `tools/list`, `tools/call`. Every request needs a bearer token in the `Authorization` header. Responses are single `application/json` bodies; the server keeps no session and streams nothing                                 |
| `/mcp`                                                                                  | `GET`, `DELETE` | `405`, because the server has no event stream and no session to end                                                                                                                                                                                                                    |
| `/.well-known/oauth-protected-resource` and `/.well-known/oauth-protected-resource/mcp` | `GET`           | The protected-resource metadata (RFC 9728): `resource`, `authorization_servers`, the three read scopes as `scopes_supported`, `bearer_methods_supported: ["header"]` and `resource_documentation`                                                                                      |
| `/.well-known/mcp-catalog`                                                              | `GET`           | The tool catalog: every tool with its group, read-only flag, target kind and result fields, generated from the server's registry. Public, cacheable for 600 seconds, and read by the policy service to build the tool action groups; see [The catalog document](#the-catalog-document) |
| `/actuator/health`                                                                      | `GET`           | `UP` when the RabbitMQ virtual hosts and Redis answer. Readiness and liveness groups are under `/actuator/health/readiness` and `/actuator/health/liveness`                                                                                                                            |
| `/actuator/prometheus`                                                                  | `GET`           | The metrics below, for the pod's own scraper; no gateway pattern publishes it                                                                                                                                                                                                          |

Every other path answers `403`.

## The tools

Each tool belongs to exactly one scope. The scope column uses the group name: `identity` stands for `openiam:mcp:identity:read`, and so on. An argument marked *optional* may be left out; the others are required. Every tool is read-only, idempotent and closed-world, and says so in its MCP annotations.

| Tool                     | Scope      | Arguments                                                                                                                                                                               | Returns                                                                                                                       |
| ------------------------ | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `whoami`                 | `identity` | none                                                                                                                                                                                    | The signed-in user, as a user summary                                                                                         |
| `get_user`               | `identity` | exactly one of `id`, `login`, `email`                                                                                                                                                   | `user`, `manager` and `organization`: two user summaries and an organization summary. Another user needs a `VIEW_USER` permit |
| `search_users`           | `identity` | `query` (matches first name, last name, login and email; at most 200 characters), `organizationId`, `status` (for example `ACTIVE`), `limit`, `offset` — all optional                   | A page of user summaries, within the organizations the signed-in user may see                                                 |
| `list_direct_reports`    | `identity` | `userId` (the signed-in user when absent), `limit`, `offset` — all optional                                                                                                             | A page of user summaries. Another manager needs a `VIEW_USER` permit                                                          |
| `get_organization`       | `identity` | `id`                                                                                                                                                                                    | An organization summary                                                                                                       |
| `search_organizations`   | `identity` | `query`, `limit`, `offset` — all optional                                                                                                                                               | A page of organization summaries, within the organizations the signed-in user may see                                         |
| `list_access`            | `access`   | `userId` (the signed-in user when absent), `kinds` (any of `ROLE`, `GROUP`, `RESOURCE`) — both optional                                                                                 | `userId` and the `roles`, `groups` and `resources` the user holds, as access entries. Another user needs a `VIEW_USER` permit |
| `check_access`           | `access`   | `kind` (`ROLE`, `GROUP` or `RESOURCE`), `idOrName`, optional `userId`                                                                                                                   | An access check. Another user needs a `VIEW_USER` permit                                                                      |
| `describe_entitlement`   | `access`   | `kind`, `idOrName`                                                                                                                                                                      | An entitlement summary; it does not say who holds the entitlement                                                             |
| `search_entitlements`    | `access`   | `kind`, optional `query`, `limit`, `offset`                                                                                                                                             | A page of entitlement summaries; a blank query lists every entitlement of the kind                                            |
| `list_requestable_items` | `access`   | `query`, `limit`, `offset` — all optional                                                                                                                                               | A page of catalog items: the applications the signed-in user may request through the request catalog                          |
| `list_my_requests`       | `workflow` | `status` (`OPEN` or `COMPLETED`), `limit`, `offset` — all optional                                                                                                                      | A page of request summaries for requests the signed-in user made                                                              |
| `get_request`            | `workflow` | `id`                                                                                                                                                                                    | A request summary. A request somebody else made is reported as `NOT_FOUND`                                                    |
| `list_pending_approvals` | `workflow` | `limit`, `offset` — both optional                                                                                                                                                       | A page of task summaries: tasks assigned to the signed-in user or offered to them as a candidate                              |
| `get_approval_task`      | `workflow` | `id`                                                                                                                                                                                    | A task summary. A task the signed-in user is neither assignee nor candidate of is reported as `NOT_FOUND`                     |
| `list_my_certifications` | `workflow` | `status` (`STARTED`, `IN_PROGRESS`, `AWAITING_SIGN_OFF`, `COMPLETED`, `EXPIRED`, `PARTIALLY_EXPIRED` or `CANCELLED`), `limit`, `offset` — all optional                                  | A page of campaign summaries for the certification campaigns the signed-in user reviews in                                    |
| `search_audit_events`    | `audit`    | `userId`, `action`, `from`, `to` (ISO-8601 dates or timestamps; the window is the last 24 hours when both are absent, and `from` must be before `to`), `limit`, `offset` — all optional | A page of audit event summaries                                                                                               |

A `VIEW_USER` permit is the policy-based access control (PBAC) decision Webconsole makes for its user screen: action `VIEW_USER` of the user-management actions on the other user, with the signed-in user as the principal and `mcp` as the invoking system. No applicable policy, a failed decision and any answer other than allow all refuse the call with `NOT_PERMITTED`, exactly as the Webconsole screen is refused. See [Grant access to user administration](/administration-guide/identities/grant-user-administration.md).

Two more things apply to every tool from 2026.10.2. When `org.openiam.mcp.pbac.mode` is `shadow` or `enforce`, the call is first a tool-level PBAC decision on the tool, the caller and the target, with the caller's agent record as context; the vocabulary is in [Decide MCP tool calls with policies](/administration-guide/federation/mcp-server/mcp-policies.md). And "the signed-in user" is the agent's service user when an agent acts alone, so `whoami` returns the service user and `list_my_requests` lists the requests it made; see [Govern AI agents as non-human identities](/administration-guide/federation/mcp-server/mcp-agents.md).

Tool names and argument names are part of the contract: an assistant project that refers to a tool by name breaks when the name changes, so they do not change within a release line.

## Result shapes

Every successful call returns the result twice: as `structuredContent`, which follows the tool's `outputSchema`, and as one text item that starts with a headline such as `search_users: 20 of 134 item(s)` followed by the same JSON, cut at 4000 characters.

A page has five members:

| Member       | Meaning                                                                             |
| ------------ | ----------------------------------------------------------------------------------- |
| `items`      | The rows of this page                                                               |
| `total`      | How many rows match in all, so the assistant can narrow the query instead of paging |
| `offset`     | Where this page starts                                                              |
| `nextOffset` | The offset of the next page; absent on the last page                                |
| `truncated`  | `true` when the row cap or the payload cap withheld rows                            |

The records hold these fields and nothing else. Date of birth, national identifiers, phone numbers and postal addresses are not fields of any record, so no tool can return them.

| Record               | Fields                                                                                                                                                     |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| User summary         | `id`, `login`, `firstName`, `lastName`, `email`, `status`, `title`, `organizationId`, `organizationName` (the primary organization), `managerId`           |
| Organization summary | `id`, `name`, `abbreviation`, `description`, `status`, `organizationTypeId`, `organizationTypeName`                                                        |
| Access entry         | `id`, `kind`, `name`, `description`, `status`, `typeId`, `direct` (held directly rather than inherited), `rights` (the access rights of the membership)    |
| Access check         | `userId`, `kind`, `id`, `name`, `entitled` (held directly or through another entitlement)                                                                  |
| Entitlement summary  | `id`, `kind`, `name`, `description`, `status`, `managedSystemId`, `managedSystemName` (roles and groups), `resourceTypeId` (resources)                     |
| Catalog item         | `id`, `name`, `description`, `categoryId`, `categoryName`, `matchedOn` (the application's own name or one of its entitlements), `matchingEntitlementCount` |
| Request summary      | `requestId`, `taskId`, `name`, `description`, `workflowName`, `status`, `requesterName`, `targetUserId`, `createdOn`, `dueOn`, `completedOn`               |
| Task summary         | `taskId`, `requestId`, `name`, `description`, `workflowName`, `assigneeId`, `requesterName`, `targetUserId`, `createdOn`, `dueOn`                          |
| Campaign summary     | `id`, `name`, `description`, `status`, `startedOn`, `expectedCompletionOn`, `totalItems`, `completedItems`, `notStartedItems`                              |
| Audit event summary  | `id`, `timestamp`, `action`, `result`, `source`, `principal`, `userId`, `clientIp`, `correlationId`                                                        |

## The catalog document

`GET /.well-known/mcp-catalog` answers with the tool catalog, generated from the server's tool registry at start-up and never from a file. It is public and carries `Cache-Control: max-age=600`. The policy service reads it, at the URL in `org.openiam.pbac.mcp.catalog.url`, to make each scope an action group and each tool a resource; the policy editor and the agent tool picker in Webconsole list the same document. No gateway pattern publishes the path, so it is reachable inside the deployment only, on the server's port 8080.

{% code overflow="wrap" expandable="true" %}

```json
{
  "version": "<server version>",
  "generatedAt": "<ISO-8601 timestamp>",
  "umbrella": "openiam:mcp",
  "groups": [
    { "id": "openiam:mcp:identity:read", "tools": ["whoami", "get_user", "search_users", "list_direct_reports", "get_organization", "search_organizations"] },
    { "id": "openiam:mcp:access:read", "tools": ["list_access", "check_access", "describe_entitlement", "search_entitlements", "list_requestable_items"] },
    { "id": "openiam:mcp:workflow:read", "tools": ["list_my_requests", "get_request", "list_pending_approvals", "get_approval_task", "list_my_certifications"] },
    { "id": "openiam:mcp:audit:read", "tools": ["search_audit_events"] }
  ],
  "tools": [
    { "name": "search_users", "group": "openiam:mcp:identity:read", "readOnly": true, "target": null, "description": "…", "resultFields": ["id", "login", "firstName", "lastName", "email", "status", "title", "organizationId", "organizationName", "managerId"] }
  ]
}
```

{% endcode %}

| Member                   | Meaning                                                                                                                                                                                            |
| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `version`, `generatedAt` | The server's version and when it built the document                                                                                                                                                |
| `umbrella`               | `openiam:mcp`, the action group that contains the four scope groups                                                                                                                                |
| `groups`                 | One entry per scope, with the tools in it                                                                                                                                                          |
| `tools[].group`          | The scope the tool belongs to                                                                                                                                                                      |
| `tools[].readOnly`       | The tool's read-only annotation; `true` for every tool in 2026.10.2                                                                                                                                |
| `tools[].target`         | The kind of entity the tool resolves as the resource of its policy decision: `HUMAN` or `ORGANIZATION`, or `null` when the tool itself is the resource or the kind depends on the call's arguments |
| `tools[].resultFields`   | The field names an obligation may `MINIMIZE` or `MASK`: the result's own components, then those of the records nested in it and of a page's rows, in declaration order and without repeats         |

`resultFields` is built from the records in [Result shapes](#result-shapes) the tool returns:

| Tool                                          | `target`                                     | `resultFields` lists                                                                                |
| --------------------------------------------- | -------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| `whoami`, `search_users`                      | `null`                                       | The user summary's fields                                                                           |
| `get_user`                                    | `HUMAN`                                      | `user`, `manager` and `organization`, then the user summary's and the organization summary's fields |
| `list_direct_reports`                         | `HUMAN`                                      | The user summary's fields                                                                           |
| `get_organization`                            | `ORGANIZATION`                               | The organization summary's fields                                                                   |
| `search_organizations`                        | `null`                                       | The organization summary's fields                                                                   |
| `list_access`                                 | `HUMAN`                                      | `userId`, `roles`, `groups` and `resources`, then the access entry's fields                         |
| `check_access`                                | `HUMAN`                                      | The access check's fields                                                                           |
| `describe_entitlement`                        | `null`: the kind follows the `kind` argument | The entitlement summary's fields                                                                    |
| `search_entitlements`                         | `null`                                       | The entitlement summary's fields                                                                    |
| `list_requestable_items`                      | `null`                                       | The catalog item's fields                                                                           |
| `list_my_requests`, `get_request`             | `null`                                       | The request summary's fields                                                                        |
| `list_pending_approvals`, `get_approval_task` | `null`                                       | The task summary's fields                                                                           |
| `list_my_certifications`                      | `null`                                       | The campaign summary's fields                                                                       |
| `search_audit_events`                         | `null`                                       | The audit event summary's fields                                                                    |

## Errors

### Refusals answered over HTTP

Claude starts a sign-in only on an HTTP 401 and asks for more scope only on an HTTP 403 `insufficient_scope`, so those two, and the limits, are answered at the HTTP level. The body is JSON with `error` and `error_description`, and `Cache-Control: no-store`.

| Status | `error`                             | When                                                                                                                                                                                              |
| ------ | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `401`  | `invalid_token`                     | The token is missing or refused; see the reasons below. The `WWW-Authenticate` header carries `resource_metadata` with the protected-resource metadata URL and `scope` with the three read scopes |
| `403`  | `insufficient_scope`                | The token lacks the scope of the tool being called. `WWW-Authenticate` names that one scope                                                                                                       |
| `403`  | JSON-RPC error `Origin not allowed` | The request carries an `Origin` that is neither the server's own nor in `org.openiam.mcp.allowed.origins`                                                                                         |
| `400`  | JSON-RPC error                      | The `Mcp-Name` header names a different tool from the request body                                                                                                                                |
| `413`  | none                                | The request body is larger than `org.openiam.mcp.request.max.bytes`                                                                                                                               |
| `429`  | `rate_limited`                      | A rate limit is exhausted; `Retry-After` gives the seconds to wait                                                                                                                                |
| `503`  | `temporarily_unavailable`           | The backend could not check the token; `Retry-After: 5`                                                                                                                                           |

The `error_description` of a 401 says which rule refused the token. The same reason, in capitals, is the `reason` label of the auth-failure meter.

| Reason                   | `error_description`                                                                                                                                                                                                                                                                                                                                                                                     |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `MISSING`                | `A bearer token is required`                                                                                                                                                                                                                                                                                                                                                                            |
| `QUERY_PARAMETER`        | `Bearer tokens are accepted in the Authorization header only` — the request carries a `token` query parameter. Any other query parameter is ignored, so a token passed as `access_token` is answered as `MISSING`                                                                                                                                                                                       |
| `JWT`                    | `JWT access tokens are not accepted by this resource` — the server accepts only the opaque access tokens of the OpenIAM identity provider (IdP), never a JSON Web Token (JWT) such as an ID token                                                                                                                                                                                                       |
| `UNKNOWN`                | `The access token is not valid`                                                                                                                                                                                                                                                                                                                                                                         |
| `EXPIRED`                | `The access token has expired`                                                                                                                                                                                                                                                                                                                                                                          |
| `CLIENT_UNKNOWN`         | `The access token was not issued by a known client`                                                                                                                                                                                                                                                                                                                                                     |
| `CLIENT_NOT_OAUTH`       | `The access token was not issued by an OAuth client`                                                                                                                                                                                                                                                                                                                                                    |
| `GRANT_FLOW`             | `The access token was not obtained through a user authorization` — the client's flow is not `AUTHORIZATION_CODE`, `AUTHORIZATION_CODE_PKCE` or `CLIENT_CREDENTIALS`, or the token was not minted by the grant that flow allows; or the flow is `CLIENT_CREDENTIALS` and the client is not bound to an AI Agent identity, the identity owns no service user, or the token was minted for another subject |
| `NO_MCP_SCOPE`           | `The access token was not issued for this resource` — the token holds no `openiam:mcp:*` scope                                                                                                                                                                                                                                                                                                          |
| `AGENT_REQUIRED`         | `The client is not registered as an agent` — `org.openiam.mcp.agent.required` is `true` and no AI Agent identity is bound to the client                                                                                                                                                                                                                                                                 |
| `AGENT_PENDING_APPROVAL` | `The client's agent is pending approval` — the client's identity is a Draft or Pending Approval                                                                                                                                                                                                                                                                                                         |
| `AGENT_SUSPENDED`        | `The client's agent is suspended` — the client's identity is Suspended or Decommissioned. A suspension or decommission revokes the client's tokens first, so a client usually meets `UNKNOWN` instead; this reason refuses a token the revocation missed                                                                                                                                                |
| `AGENT_EXPIRED`          | `The client's agent has expired` — the identity's expiry date has passed                                                                                                                                                                                                                                                                                                                                |

The four `AGENT_*` reasons are the ones a client cannot repair by signing in again; the agents page explains each in [When it goes wrong](/administration-guide/federation/mcp-server/mcp-agents.md#when-it-goes-wrong).

### Tool errors

Everything else is a tool result with `isError: true`, so the assistant can explain it instead of stopping. Its `structuredContent` is `{code, message, correlationId}`; the message never contains a token, a stack trace or data the caller was refused, and the correlation ID matches the audit event.

| `code`             | When                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `NOT_PERMITTED`    | A `VIEW_USER` decision refused, or no policy applied; or, in enforce mode, the tool gate refused. The message says why, never the policy text: `forbidden by policy` with the policy ID when a forbid matched, `no policy permits the call` when the applied policies permitted nothing, `NO_POLICY: no policy permits this agent to call the tool` for an agent acting alone that no policy governs, and `OBLIGATION_UNSUPPORTED: …` when the permitting policy carries a mandatory obligation of a type other than `MINIMIZE`, `MASK` or `LOG` |
| `NOT_FOUND`        | The object does not exist, or is not the signed-in user's own (requests and approval tasks)                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `INVALID_ARGUMENT` | An argument is missing, malformed or out of range; the message names the field                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `UNAVAILABLE`      | A backend call failed; or, in enforce mode, the policy service did not answer within `org.openiam.mcp.pbac.timeout.ms`, answered with a failure, or its breaker is open, in which case the message starts with `The access decision could not be obtained`                                                                                                                                                                                                                                                                                       |
| `TIMEOUT`          | The tool ran longer than `org.openiam.mcp.tool.timeout.ms`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |

## Properties

Values in `mcp.ui.properties` under the deployment's `conf/properties` directory override the defaults built into the server. In Kubernetes each property can also be set under `openiam.mcp.properties` in the `mcp` chart's values, which passes it as a Java system property. Restart the server after a change.

| Property                                          | Default                    | What it does                                                                                                                                                                                                           |
| ------------------------------------------------- | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `org.openiam.mcp.enabled`                         | `true`                     | `false` leaves `/mcp` unregistered; the metadata and health endpoints keep answering                                                                                                                                   |
| `org.openiam.mcp.resource.url`                    | empty                      | The `resource` the protected-resource metadata advertises, exactly the URL users enter in their client. Empty derives `https://<host>/mcp` from each request's forwarded host                                          |
| `org.openiam.mcp.issuer.url`                      | empty                      | The authorization server the metadata names. Empty derives `https://<host>/idp/oauth2`                                                                                                                                 |
| `org.openiam.mcp.allowed.origins`                 | empty                      | Comma-separated browser origins allowed to call `/mcp`. The server's own origin is always allowed, and requests without an `Origin` header are never affected                                                          |
| `org.openiam.mcp.content.provider.id`             | empty                      | The content provider every backend request is attributed to                                                                                                                                                            |
| `org.openiam.mcp.tokeninfo.cache.seconds`         | `30`                       | How long a checked token is reused before the backend is asked again; revocation takes effect within this time                                                                                                         |
| `org.openiam.mcp.provider.cache.seconds`          | `60`                       | How long an OAuth client definition is reused                                                                                                                                                                          |
| `org.openiam.mcp.tool.timeout.ms`                 | `10000`                    | The time budget of one tool call                                                                                                                                                                                       |
| `org.openiam.mcp.tool.executor.size`              | `32`                       | Threads that run tool calls                                                                                                                                                                                            |
| `org.openiam.mcp.result.limit.default`            | `50`                       | Rows per page when the call gives no `limit`                                                                                                                                                                           |
| `org.openiam.mcp.result.limit.max`                | `200`                      | The most rows a page may hold, whatever `limit` asks for                                                                                                                                                               |
| `org.openiam.mcp.result.payload.max.bytes`        | `262144`                   | The largest serialized page; rows beyond it are withheld and `truncated` is set                                                                                                                                        |
| `org.openiam.mcp.request.max.bytes`               | `1048576`                  | The largest request body                                                                                                                                                                                               |
| `org.openiam.mcp.ratelimit.per.minute`            | `60`                       | Requests per client and user per minute; `0` disables the limit                                                                                                                                                        |
| `org.openiam.mcp.ratelimit.per.hour`              | `1000`                     | Requests per client and user per hour; `0` disables the limit                                                                                                                                                          |
| `org.openiam.mcp.ratelimit.search.per.minute`     | `30`                       | Calls per minute of each `search_*` tool, per client and user, on top of the two limits above                                                                                                                          |
| `org.openiam.mcp.documentation.url`               | `https://docs.openiam.com` | The `resource_documentation` the metadata advertises                                                                                                                                                                   |
| `org.openiam.mcp.agent.required`                  | `false`                    | `true` refuses an authorization-code client that has no agent record with `AGENT_REQUIRED`. Leave it `false` until every client has one                                                                                |
| `org.openiam.mcp.agent.cache.seconds`             | `60`                       | How long an agent record is reused before the NHI service is asked again; a suspension takes effect within this time                                                                                                   |
| `org.openiam.mcp.agent.lastused.throttle.seconds` | `300`                      | How often, at most, a successful call updates the agent's last-used time                                                                                                                                               |
| `org.openiam.mcp.pbac.mode`                       | `off`                      | The tool gate: `off`, `shadow` (ask and record, always allow) or `enforce` (refuse on deny, apply obligations); see [Decide MCP tool calls with policies](/administration-guide/federation/mcp-server/mcp-policies.md) |
| `org.openiam.mcp.pbac.timeout.ms`                 | `500`                      | How long the gate waits for the policy service                                                                                                                                                                         |
| `org.openiam.mcp.pbac.breaker.failures`           | `5`                        | Consecutive failures to reach the policy service after which the gate stops asking                                                                                                                                     |
| `org.openiam.mcp.pbac.breaker.open.seconds`       | `30`                       | How long the gate reports `UNAVAILABLE` without asking after the breaker opened                                                                                                                                        |
| `org.openiam.mcp.pbac.guard.enabled`              | `true`                     | Whether the `VIEW_USER` object guard inside the tools that read another person still runs; switch it off once tool policies are enforced                                                                               |

Settings in other components:

| Property                                                                                                                      | Component                              | What it does                                                                                                                                                                                                                                                                                                                                                                                    |
| ----------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `org.openiam.content.provider.mcp.pattern`                                                                                    | Enterprise service bus (ESB)           | The prefix of the MCP patterns, `/mcp`                                                                                                                                                                                                                                                                                                                                                          |
| `org.openiam.oauth.resources`, `org.openiam.oauth.resource.mcp.*`, `org.openiam.oauth.cimd.*`                                 | IdP                                    | The `resource` the IdP accepts for the server and which clients may register themselves — listed under "Properties added in 2026.10.2" in [OAuth endpoints, grants, scopes and signing](/administration-guide/federation/oauth-and-oidc/oauth-and-oidc-reference.md)                                                                                                                            |
| `org.openiam.oauth.cimd.agent.owner`                                                                                          | IdP                                    | The user ID that owns and sponsors the agent record of every client that registers itself. Ships empty, which makes the IdP refuse to register such a client                                                                                                                                                                                                                                    |
| `org.openiam.oauth.cimd.agent.approval`                                                                                       | IdP                                    | `auto` (shipped) creates the record Active; `required` creates it Pending Approval                                                                                                                                                                                                                                                                                                              |
| `org.openiam.oauth.cimd.agent.expiry.days`                                                                                    | IdP                                    | The record's expiry, `365` days from registration                                                                                                                                                                                                                                                                                                                                               |
| `org.openiam.oauth.cimd.agent.environment`, `org.openiam.oauth.cimd.agent.risk`                                               | IdP                                    | The record's environment and risk classification, `PROD` and `MEDIUM`                                                                                                                                                                                                                                                                                                                           |
| `org.openiam.oauth.client_credentials.legacy.subject`                                                                         | IdP                                    | `true` (shipped) lets a client-credentials client with no agent record keep the `0001` subject; the next release ships `false`                                                                                                                                                                                                                                                                  |
| `org.openiam.pbac.mcp.catalog.url`                                                                                            | Policy service (`pbac-manager`)        | Where to read the catalog document. Ships empty: no catalog, so no tool action groups                                                                                                                                                                                                                                                                                                           |
| `org.openiam.pbac.mcp.catalog.refresh.seconds`                                                                                | Policy service                         | How often the catalog is re-read, `600`                                                                                                                                                                                                                                                                                                                                                         |
| `org.openiam.pbac.log.nopolicy.invokingsystems`                                                                               | Policy service                         | Invoking systems whose decisions are logged even when no policy governs them; ships as `mcp`                                                                                                                                                                                                                                                                                                    |
| `org.openiam.mcp.catalog.url`                                                                                                 | Webconsole, `webconsole.ui.properties` | Where the policy editor's autocomplete and the declared-tools picker read the catalog document, kept for ten minutes. Ships empty: no MCP vocabulary in Webconsole                                                                                                                                                                                                                              |
| `org.openiam.nhi.drift.window.days`, `org.openiam.nhi.drift.unused.days`                                                      | NHI service                            | The window over which an agent's tool usage is compared with its declared tools, `30` days, and how long a declared tool may go unused before it is reported, `90`                                                                                                                                                                                                                              |
| `org.openiam.nhi.drift.audit.page.size`, `org.openiam.nhi.drift.audit.max.pages`, `org.openiam.nhi.drift.usage.cache.seconds` | NHI service                            | How the tool-drift job reads the audit log: pages of `500` events, at most `40` pages, and how long the usage it found is reused, `600` seconds                                                                                                                                                                                                                                                 |
| `org.openiam.nhi.binding.threadsweep`                                                                                         | NHI service                            | How often, in milliseconds, the client-to-agent bindings are republished to the cache the ESB reads at the token endpoint, `30000`; a bind or a status change republishes at once. The IdP keeps its own copy of an agent record for 60 seconds, a fixed value, so a bind, an approval, a status change or a new expiry date reaches the token and authorization endpoints up to a minute later |

## The audit event

Every tool call writes one audit event, success or failure, with action `MCP_TOOL_CALL` and source `MCP`. The requestor and the target user are the signed-in user, or the service user of an agent acting alone; the authentication provider is the client the token belongs to, and the event name is the tool name. Find the events under **Administration → Log Viewer**. Refusals answered over HTTP are not audited; they are counted by the auth-failure meter.

| Attribute                 | Value                                                                                                                                                                                                                                                                                                                                                                                                           |
| ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `MCP_TOOL`                | The tool name                                                                                                                                                                                                                                                                                                                                                                                                   |
| `MCP_CLIENT_ID`           | The OAuth client ID, for Claude the URL of its metadata document                                                                                                                                                                                                                                                                                                                                                |
| `MCP_OUTCOME`             | `SUCCESS`, or the tool error code                                                                                                                                                                                                                                                                                                                                                                               |
| `MCP_ARGUMENT_DIGEST`     | The lower-case hexadecimal SHA-256 of the arguments as canonical JSON. The arguments themselves are never stored                                                                                                                                                                                                                                                                                                |
| `MCP_RESULT_COUNT`        | The rows returned for a page, `1` for any other result; success only                                                                                                                                                                                                                                                                                                                                            |
| `MCP_DURATION_MS`         | The call's duration in milliseconds                                                                                                                                                                                                                                                                                                                                                                             |
| `MCP_TOKEN_ID`            | The ID of the access token used                                                                                                                                                                                                                                                                                                                                                                                 |
| `MCP_CORRELATION_ID`      | The ID that also appears in the tool's error result and in the server log                                                                                                                                                                                                                                                                                                                                       |
| `MCP_PRINCIPAL_KIND`      | `HUMAN` when a person consented to the client, `NHI` when an agent acts alone                                                                                                                                                                                                                                                                                                                                   |
| `MCP_AGENT_NHI_ID`        | The ID of the client's AI Agent identity; absent when the client has none                                                                                                                                                                                                                                                                                                                                       |
| `MCP_POLICY_MODE`         | `OFF`, `SHADOW` or `ENFORCE`, the tool gate's mode at the time of the call                                                                                                                                                                                                                                                                                                                                      |
| `MCP_POLICY_DECISION`     | `ALLOW`, `DENY`, `NO_POLICY_ALLOW`, `NO_POLICY_DENY` or `UNAVAILABLE`: what the policies decided, or would have decided in shadow mode. Absent when the gate is off                                                                                                                                                                                                                                             |
| `MCP_POLICY_IDS`          | The IDs of the policies that applied to the call, comma-separated: every policy whose enforcement mode governs the call, not only the one that decided it, and none observed in shadow. A refusal by Cedar's default deny lists the applied policies although none of them forbade the call; the tool error's message names a forbid that did. Absent for `NO_POLICY_ALLOW`, `NO_POLICY_DENY` and `UNAVAILABLE` |
| `MCP_OBLIGATIONS_APPLIED` | The obligations applied to the result in enforce mode, as `MASK(fields=email;pattern=INITIALS),LOG(note=…)`                                                                                                                                                                                                                                                                                                     |

The tool, the principal kind, the agent, the mode, the decision and each policy ID are also written as indexed target attributes of the event, so the Log Viewer and the decision log can filter on them.

A failed call also carries the failure reason. Audit events the backend writes while it serves the call are linked to this one as its children.

## Prometheus meters

| Meter                                                                    | Labels                                                                            | What it counts                                                                                                  |
| ------------------------------------------------------------------------ | --------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| `openiam_mcp_tool_calls_seconds` (summary: `_count`, `_sum`, `_max`)     | `tool`, `outcome` (`SUCCESS` or the error code), `client` (the client ID)         | Tool calls and their duration                                                                                   |
| `openiam_mcp_auth_failures_total`                                        | `reason`: a 401 reason above, `INSUFFICIENT_SCOPE`, `RATE_LIMITED` or `ORIGIN`    | Requests refused before a tool ran                                                                              |
| `openiam_mcp_policy_decisions_total`                                     | `decision` (an `MCP_POLICY_DECISION` value above), `mode` (`SHADOW` or `ENFORCE`) | Tool-gate decisions                                                                                             |
| `openiam_mcp_policy_latency_seconds` (summary: `_count`, `_sum`, `_max`) | `mode`                                                                            | How long the policy service took to answer the gate; the number that decides whether a decision cache is needed |
| `openiam_mcp_policy_obligation_unknown_fields_total`                     | none                                                                              | Field names an obligation named that no record of the result carried                                            |

## Limits

| Limit                        | Value                                                                        | Set by                                                                                             |
| ---------------------------- | ---------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| Rows per page                | 50 by default, at most 200                                                   | `org.openiam.mcp.result.limit.default`, `.max`                                                     |
| Serialized page              | 256 KB                                                                       | `org.openiam.mcp.result.payload.max.bytes`                                                         |
| Request body                 | 1 MB                                                                         | `org.openiam.mcp.request.max.bytes`                                                                |
| Requests per client and user | 60 per minute and 1000 per hour, plus 30 per minute for each `search_*` tool | `org.openiam.mcp.ratelimit.*`; counted in Redis, and admitted unlimited while Redis is unreachable |
| Tool call                    | 10 seconds                                                                   | `org.openiam.mcp.tool.timeout.ms`                                                                  |
| Token check reused           | 30 seconds                                                                   | `org.openiam.mcp.tokeninfo.cache.seconds`                                                          |
| Agent record reused          | 60 seconds                                                                   | `org.openiam.mcp.agent.cache.seconds`                                                              |
| Policy decision              | 500 ms, then `UNAVAILABLE` in enforce mode                                   | `org.openiam.mcp.pbac.timeout.ms`                                                                  |
| `search_users` query         | 200 characters                                                               | fixed                                                                                              |
| `search_audit_events` window | the last 24 hours when no bound is given                                     | fixed                                                                                              |

## What 2026.10.2 does not do

* **No write tools.** Every tool reads; requests, approvals and certification decisions are made in SelfService.
* **Agent-alone access needs a record.** A client-credentials token is admitted only when its client is bound to an AI Agent identity that owns a service user; a password-grant token is never admitted. A declared tool carries the `READ` access right only; `WRITE` is reserved.
* **No decision cache.** In shadow and enforce mode every call asks the policy service; the policy latency meter is what decides whether a cache is needed.
* **The gateway does not check the token on `/mcp`.** The patterns are public and the MCP server is the resource server: it checks every token itself and emits the challenges MCP clients act on.
* **The server admits by scope, not by audience.** The IdP records the `resource` a client asked for on the authorization code and on the token, as its audience, and refuses a code exchange that names a different resource; but the server does not compare that audience with its own URL. A token is kept away from Webconsole and SelfService by its scopes.
* **Revocation lags by up to 30 seconds**, the time a checked token is reused, and a suspended agent's calls by up to 60, the time its record is reused.
* **Responses are single JSON bodies.** The server sends no progress notifications and keeps no session.
* **RPM installations do not include the server.** It ships as the `mcp` container image and Helm chart.

## Related

* [Connect AI assistants through the MCP server](/administration-guide/federation/mcp-server.md) — deploying, publishing and connecting
* [Govern AI agents as non-human identities](/administration-guide/federation/mcp-server/mcp-agents.md) — the agent record behind the admission reasons and the agent attributes
* [Decide MCP tool calls with policies](/administration-guide/federation/mcp-server/mcp-policies.md) — the decision behind the policy attributes, the obligations and the catalog
* [OAuth endpoints, grants, scopes and signing](/administration-guide/federation/oauth-and-oidc/oauth-and-oidc-reference.md) — the IdP side: the tenant metadata document, Client ID Metadata Documents and the `resource` parameter
* [Audit actions and retention](/administration-guide/reference/audit-actions-and-retention.md) — how long audit events are kept

*Applies to OpenIAM 2026.10.2. Last reviewed 22 October 2026.*


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.openiam.com/administration-guide/federation/mcp-server/mcp-server-reference.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
