MCP server
The Mutual Trust MCP server lets an AI assistant read your services, grants and receipts and, with your consent and roles, invite partners and suspend, resume or withdraw access.
Endpoint
| URL | https://mcp.mutualtrust.io/mcp |
|---|---|
| Transport | Streamable HTTP |
| Authorization | OAuth 2.1 (authorization code with PKCE), provided by the Cloudflare Workers OAuth provider, with consent in the Mutual Trust portal |
How authorization works
- Your MCP client discovers the server’s OAuth metadata and registers itself, then opens the authorization page in your browser.
- You sign in to
app.mutualtrust.ioand see a consent screen naming the client. Choose one organization and the roles to delegate. Only roles you hold in that organization are offered. - On approval the portal mints a dedicated API credential (
purpose: "mcp", named “MCP: <client>”, valid 30 days) and hands it once to the MCP server through a single-use code that expires after 2 minutes. If the handoff is not completed in time, the credential is revoked automatically. - The MCP server completes the OAuth flow with your client. The client only ever holds OAuth tokens for the MCP server; the MCP server calls the Mutual Trust API with the scoped credential.
Every action is therefore limited to that organization and to the delegated roles intersected with your current roles, and is recorded in the audit log as you (via the credential). Removing a role from you removes it from the MCP connection too.
Tools
| Tool | What it does | API | Needs |
|---|---|---|---|
get_overview | Summary of organizations, services, relationships and alerts. | GET /v1/overview | Any role |
list_services | Services in the organization with gateway and grant counts. | GET /v1/overview | Any role |
get_service | One service: gateways, current policy revision, readiness. | GET /v1/services/{id} | Any role |
list_grants | Grants on a service (sponsor) or held by the organization (partner). | GET /v1/grants | grant.read |
get_grant | Grant detail, workload principal and certificates. | GET /v1/grants/{id} | grant.read |
list_receipts | Recent verification receipts for a service. | GET /v1/services/{id}/receipts | grant.read |
create_invitation | Invite a partner to a scope within the service’s templates. Returns the one-time accept link. | POST /v1/services/{id}/invitations | service_owner or trust_admin |
suspend_grant | Suspend a grant with a reason code. | POST /v1/grants/{id}/suspend | service_owner or trust_admin |
resume_grant | Resume a suspended grant. | POST /v1/grants/{id}/resume | service_owner or trust_admin |
revoke_grant | Withdraw a grant permanently with a reason code. | POST /v1/grants/{id}/revoke | service_owner or trust_admin |
get_operation | Per-gateway progress of a change. | GET /v1/operations/{id} | Any role |
list_integrations | Adapter integrations of an organization. | GET /v1/integrations | integration.read |
list_integration_plans | Plans submitted by mt-adapt, with state and redacted diff. | GET /v1/integrations/{id}/plans | integration.read |
get_integration_plan | One plan: changes, diff, test vectors, decision. Approving stays in the portal. | GET /v1/integrations/{id}/plans/{plan_hash} | integration.read |
list_integration_runs | Run timeline with outcomes and verification categories. | GET /v1/integrations/{id}/runs | integration.read |
get_integration_evidence | Latest result for each of the eight acceptance categories. | GET /v1/integrations/{id}/evidence | integration.read |
Destructive tools
API data is returned as untrusted data
Each tool maps to one API operation; the underlying behaviour is documented in the API reference, and tool changes are listed in the changelog.
Migration tools and agent runs
An agent can work on a connection workspace only inside an agent run that a person creates in the portal for one MCP connection. The run fixes the workspace, the side the agent acts for, the mode, the tools, and an expiry. The server checks every call against the run; nothing an agent reads (evidence, plans, earlier tool output) can widen what it may do. Without a run, the connection reaches no workspace (agent_run_required). The agent finds its runs with agent_runs.list.
| Mode | The agent may | Longest run |
|---|---|---|
| Observe | Read, explain and preview (assessment and plan drafts that store nothing). Every write is refused. | 30 days |
| Supervised (default) | Record evidence, plans, approval requests and test results; start, cut over and roll back only with approvals that name its run. It waits at each approval gate it raises. | 7 days |
| Delegated | As supervised, and use a standing organization approval for the actions the person preauthorized: execution.start, rollback. Trust anchors, resource authorization and cutover always need an approval naming the run. | 24 hours |
- Agents never approve. People with the permission kind approve with a passkey or identity-provider sign-in (step-up). The person who delegated a run cannot approve what it asks for.
- Approvals are bound to plan hash, action, target, actor (
agent_run:<id>), expiry and environment, and checked again when used. A replayed single-use approval, another plan hash or another actor is refused. - Retries are safe. Every mutating tool sends an
Idempotency-Key. When the agent does not passidempotency_key, one is derived from the call, so repeating the same call returns the first result. - Pause, resume, cancel. The delegator, the side’s requesters or the resource owner pause a run immediately; a person resumes it (with step-up). Cancelling can also revoke the MCP credential. Neither reverses changes that already committed: use rollback.
- Every call is recorded in the run’s action log (allowed, refused or failed), and every change carries the run, the agent identity and you in the audit log. Calls are limited to 120 per minute per run (30 that change something).
| Tool | What it does | API | Run mode |
|---|---|---|---|
connections.inspect | The workspace of the run in your side’s view: status, plan, execution, approvals, approval requests, certificates, telemetry coverage. | GET /v1/workspaces/{id} | Every mode |
connections.assess | Assess discovery evidence for the workspace endpoint. Preview by default (stores nothing); store: true records it. | POST /v1/workspaces/{id}/assessments[/preview] | Preview: every mode. Store: supervised, delegated |
connections.diagnostics.read | Evidence your side may see, newest first, paginated with cursor. | GET /v1/workspaces/{id}/diagnostics | Every mode |
migrations.plan.create | Draft the next immutable plan version. Preview by default; store: true records it and invalidates approvals of earlier versions. | POST /v1/workspaces/{id}/plans[/preview] | Preview: every mode. Store: supervised, delegated |
migrations.plan.get | One plan version: plain-language summary, technical changes per party, steps, tests, rollback, plan_hash, approvals. | GET /v1/plans/{id} | Every mode |
migrations.approvals.request | Ask people for the approvals the next action needs. Grants nothing; a supervised run waits until they are decided. | POST /v1/plans/{id}/approval-requests | Supervised, delegated |
migrations.tasks.delegate | Create a discovery task for an engineer. The claim link goes to the person who delegated the run, never to the agent. | POST /v1/workspaces/{id}/tasks | Supervised, delegated |
migrations.execute.prepare | Check every required approval exactly as starting, cutover and rollback would check it for this run, and the next step. Changes nothing. | GET /v1/plans/{id}/readiness | Every mode |
migrations.execute.apply | Start the durable execution of the approved plan version. | POST /v1/plans/{id}/executions | Supervised, delegated; approvals |
migrations.validate | Read the validation state, or record positive and negative test results for the step the execution waits on. | GET /v1/executions/{id}, POST /v1/executions/{id}/evidence | Read: every mode. Record: supervised, delegated |
migrations.cutover.request | Request cutover after validation passed. | POST /v1/executions/{id}/cutover | Supervised, delegated; approval naming the run |
migrations.rollback.request | Request rollback; irreversible steps are reported, never undone. | POST /v1/executions/{id}/rollback | Supervised, delegated; approval |
migrations.handover.export | The signed, immutable handover report for your side. | GET /v1/workspaces/{id}/handover | Supervised, delegated |
agent_runs.list, agent_runs.get | The runs people created for this connection, and the state of one (works in every state). | GET /v1/agent-runs[/{id}] | Any run |
agent_runs.pause, agent_runs.complete | Stop yourself (only a person resumes), or end the run when done. | POST /v1/agent-runs/{id}/pause|complete | Any live run |
Each migration tool takes agent_run_id, declares an output schema (data_trust, tool, tool_version, data) and, on failure, returns error.code with a category (authentication, authorization, agent_policy, agent_run_state, approval_required, not_found, conflict, invalid_request, rate_limited, unavailable) and retryable. The role checks of the API still apply: the run narrows what the connection’s roles allow, never widens it.
Add to Claude
Claude (web and desktop)
Open Settings → Connectors, choose Add custom connector, enter https://mcp.mutualtrust.io/mcp and connect. Claude opens the Mutual Trust consent page; pick the organization and roles.
Claude Code
claude mcp add --transport http mutualtrust https://mcp.mutualtrust.io/mcpThen run /mcp in Claude Code and choose Authenticate for mutualtrust.
Other MCP clients
Any client that supports remote MCP servers over Streamable HTTP with OAuth can connect. Many clients accept a JSON entry like this (check your client’s documentation for the exact file and keys):
{
"mcpServers": {
"mutualtrust": {
"type": "http",
"url": "https://mcp.mutualtrust.io/mcp"
}
}
}Review and revoke access
- In the portal, Organization → API credentials lists MCP connections as “MCP: <client>” with
purpose: mcp, creator, expiry and last use. - Revoke one there, or with
POST /v1/organizations/{id}/api-credentials/{cid}/revoke. The next tool call fails with401. - Connections expire after 30 days; reconnect from the client to approve a new one.