MCP contract
The experimental MCP gateway exposes every x-owner business operation in the
assembled Go API OpenAPI specification. The reviewed
manifest gives each operation one stable tool name, scope and
effect classification. It currently contains 54 operations, including writes,
deletions and the two operator-only Support routes.
The manifest is deliberately explicit. Generation fails when an API operation is added or removed without a parity decision, a scope crosses its owner, a write is classified as a read, or an input admits an authentication header. Authentication/session endpoints, internal relays, diagnostics and realtime connections do not become tools.
Run pnpm generate:contracts after editing sources or generators.
pnpm check:http checks the bundled specification, generated tool schemas,
Go DTOs, HTTP client and closed typed dispatcher. Generated files live in
services/api/adaptors/{mcpcontract,mcpclient}/generated.
Inputs and outcomes
Inputs retain the OpenAPI names in three optional groups:
This is the input to create_support_ticket. Tools retain required command
headers, canonical identifiers, expected revisions, filters and pagination.
Path values are encoded by the generated client; they cannot select an arbitrary
origin or operation. Read-only annotations include SSH key validation, which the
HTTP API models as a POST.
Each result has operation_id, HTTP status, and either the generated result
or a bounded error containing code, message and optional outcome_unknown.
Structured and text results contain the same envelope. The HPC projection keeps
its Protobuf representation as {media_type, base64}.
Declared, schema-valid shared, Run and Pipeline command outcomes retain their
aggregateId, version, status and rejection in result, including HTTP 404,
409 and 422 where that operation declares the corresponding outcome schema.
These non-success replies set the MCP error flag while preserving the recorded
outcome for recovery. Ordinary and unrecognised error bodies keep the sanitised
error envelope.
Arguments are limited to 64 KiB. API replies are read with a 1 MiB bound; the gateway also bounds the duplicated MCP envelope. Large results require narrower queries or the ordinary API. Unknown provider error details are omitted. Malformed successful replies fail contract validation.
The gateway makes one HTTP attempt, refuses redirects and never manufactures idempotency keys or revisions. After an uncertain write, preserve the exact input and command identity for a user-authorised replay or current-state query. Tool annotations and instructions ask clients to obtain approval before writes. The platform enforces identity, scopes and owner permissions; the client owns per-action human approval.
Authority
Scopes use <owner-with-hyphens>:read, :write or :admin. Tokens contain only
resource scopes actually granted through OAuth. Discovery is scoped to each
request. The API rechecks permissions for each invocation.
An ordinary Party can request member scopes and use the operations allowed by the existing API and owners. The two Support administration operations also require API-side operator enrolment, checked at each call. The broker captures that enrolment at login and checks it on refresh; an old grant cannot silently gain newly enrolled operator rights.
The protocol uses three distinct JWT families:
All carry exact iss, aud, sub, iat, exp, jti,
identity_issuer, identity_subject and identity_voperson_id.
Access tokens additionally require client_id, party_id, auth_version and
scope. Gateway assertions retain Party authority and scopes, replace
client_id with an exact operation_id, and receive a fresh identity and expiry.
Login assertions contain neither a Party nor an operation or scope.
The private POST /internal/mcp/identity endpoint accepts only a broker login
assertion. Its response contains party_id, auth_version and operator.
It resolves an existing exact identity through Party Governance, checks current
AUP through its established binding and rechecks the Party generation. Missing
registration, pending setup or required AUP asks the user to complete ordinary
platform login. No account is created by the MCP login query.
JWT parsing rejects duplicates, unknown fields, incorrect casing, nulls, missing identity, wrong token families, wrong audiences and invalid lifetimes. Broker and gateway verification keys are explicitly enrolled and must be different. The API's ordinary browser and CLI paths retain their existing credentials. A failed delegated bearer never falls back to a browser cookie.
See ADR 0071 and the runtime guide.
Page source
Source snapshot ยท Revision f928834c8.