skip to content

MCP tools

All nine broker MCP tools with inputs, results, side effects, retry rules, errors, and the one-call identity_signup flow.

awaiting reviewupdated view markdown ->

The broker exposes nine tools over the Model Context Protocol (MCP) at https://agentregistrar.dev/mcp. Four manage the agent identity, four manage its inbox, and one is the one-call signup tool. This page is the lookup table: inputs, result keys, side effects, retry rules, error codes, and one example per tool.

The normative contracts are elsewhere. Inputs and the structured results are defined in the broker's shared MCP tool schema; the behavior is in the broker's tool modules. The error reference holds the code list, and the broker HTTP reference holds the transport and OAuth endpoints.

Endpoint and discovery

  • URL: https://agentregistrar.dev/mcp (Streamable HTTP, JSON-RPC 2.0).
  • Auth: OAuth 2.1 bearer access token (mca_...), sent as Authorization: Bearer. The token is bound to one verified human owner.
  • Transport: one stateless handler per request. There is no session id to keep, and POST is the only method the tool flow needs.
  • initialize reports serverInfo.name agentregistrar, version 1.0.0, capabilities tools and resources, and the system instructions that describe the workflow.
  • tools/list returns exactly nine tools.
  • resources/list returns four static text/markdown resources. They repeat documented material for clients that cannot follow links; the pages they point at stay canonical.
export MCP_TOKEN="<the mca_ access token from your client's OAuth flow>"
curl -sS -X POST https://agentregistrar.dev/mcp \
  -H "Authorization: Bearer $MCP_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

The handler also accepts a POST with only Accept: application/json and defaults a missing Content-Type to application/json, so plain curl calls work. A request without a bearer token gets 401 with a JSON-RPC error code -32001 and a WWW-Authenticate challenge; see the transport errors.

MCP resources

URI Title Material also published at
agentregistrar://docs/quickstart Agent Registrar quickstart Agent quickstart
agentregistrar://docs/assertion-claims Agent assertion claims (Contract A) Assertion claims
agentregistrar://docs/error-recovery Tool error recovery Error codes
agentregistrar://docs/spec Agent Identity specification Specification

Resources are read-only and carry no per-request state. The tool result is the reliable surface; a resource is supporting depth.

Before you call

The transport gate runs before any tool:

  1. The bearer token must resolve to an mca_... token row that is not revoked and not expired. Otherwise 401, code -32001.
  2. The token's human owner must be active and must have signed the Master Agent Delegation agreement. Otherwise 403, code -32003.
  3. The agent sub-identity must exist and be active. identity_register creates it; identity_whoami, identity_signup, identity_prove, and the inbox tools resolve it and auto-provision a default one when the session has none.

A revoked or operator-suspended agent fails at the tool layer with agent_revoked, not at the transport. A suspended agent is not human-restorable. Scope checks are per tool: identity_signup/identity_prove need tos:accept, the inbox tools need inbox:read or inbox:send.

How to read each entry

  • Inputs: the exact JSON Schema properties from tools/list.
  • Result: the keys the agent sees. identity_signup, identity_prove, and identity_record_signup register structured outputSchemas; the others return a text JSON payload.
  • Side effects: what changes in the broker, including mail.
  • Retry: whether repeating the same call is safe.
  • Errors: stable codes, linked to Error codes.

A tool failure is not an HTTP error. It returns a normal JSON-RPC result with isError: true and the error envelope as text content:

{
  "content": [
    {
      "type": "text",
      "text": "{\"error\":{\"code\":\"wait_timeout\",\"message\":\"...\",\"retryable\":true,\"side_effects\":{},\"next_step\":\"...\",\"docs\":\"agentregistrar://docs/error-recovery\"}}"
    }
  ],
  "isError": true
}

The text value is a JSON string: parse it before reading code. message is human-readable and may change; code, retryable, side_effects and next_step are stable.

Tools at a glance

Tool Group Purpose readOnlyHint idempotentHint
identity_register Identity Create or resume the agent sub-identity for this session no yes
identity_whoami Identity Show the agent, human owner, scopes, recent signups and acceptances yes yes
identity_signup Identity One call: fetch discovery, apply policy, mint, return a prepared signup request no yes
identity_prove Identity Advanced: accept terms and mint with claim inspection no yes
identity_record_signup Identity Record an RP-signed receipt or a weaker self-report no yes
inbox_list Inbox List recent messages, newest first yes yes
inbox_read Inbox Read one message body, headers and detected OTP yes yes
inbox_wait_for_email Inbox Wait for a matching inbound message yes yes
inbox_send Inbox Send mail from the agent address no no

identity_signup

Title: "One-call brokered service signup". This is the default path. It does the identity half of signup in one call.

Inputs

Field Type Required Rule
service string yes RP origin or the exact /.well-known/agent-signup.json URL. The broker fetches it. Do not pass a discovery object, discovery URL as a separate field, or an attestation.
accepted_tos_text string yes The complete terms.text the human accepted, verbatim. Its hash must equal the fetched terms.sha256; no trim or summary.
requested_scopes string[] no Defaults to discovery required_scopes in document order. Supplied: deduped, must include every required scope and hold every listed scope. [] is invalid.
force_new boolean no Create a new consent event even if an acceptance exists. Default false; it does not bypass gates or policy.

The schema is passthrough, but the executor rejects rp_discovery, rp_discovery_url, and rp_attestation with discovery_source_not_allowed. There is no manual discovery, JWT decode, or attestation handling.

Result

  • service: origin, audience, provider name/URL, terms URL/hash/version, endpoints.agent_signup, required scopes, and the attestation summary (status, issuer, jti, level, expires_at, checked_at).
  • rp_verification: the required verification summary (status, policy, allowed, source, issuer, jti, level, expiry, checked_at, reason).
  • rp_verification_warning: present only when a warn policy proceeds. Surface it to the human; it is advisory, not a safety rating or a block.
  • assertion: jwt, jti, kid, typ, expiry. The JWT has no claims block in the result; send it verbatim.
  • acceptance, reuse, side_effects, agent_id, agent_email, audience, tos_ledger_email.
  • signup_request: POST the exact url with the exact headers (Authorization: Bearer <jwt>, Content-Type: application/json) and raw body {}. No extra fields, no JWT in the URL or body, no broker POST.
  • next_steps: the fixed follow-up list.

Policy behavior

  • allow is silent.
  • warn proceeds with rp_verification_warning.
  • require proceeds only for a verified RP and rejects agent_supplied_discovery (this tool never supplies one).
  • block always refuses with rp_blocked.
  • An unverified RP under require is rp_unverified; an untrusted broker is rp_broker_untrusted; invalid/expired are rp_attestation_invalid / rp_attestation_expired; unavailable is rp_broker_unavailable.
  • warn is not a security control. Verification is identity, not safety.

Side effects and retry

The call records a delegated acceptance (durable), a mint-time rp_verifications row when verification ran, a ledger email to the agent inbox, and a forward to the human. Identical calls while the assertion is unexpired reuse it but re-run every gate and policy. force_new creates a new consent event. Retry after ledger_email_failed only re-sends mail; the acceptance is recorded. Read side_effects before retrying anything else.

Example

{
  "service": "https://example.com",
  "accepted_tos_text": "<the complete terms.text>"
}

The response's signup_request is the only request to send. After the RP responds, call identity_record_signup with any signup_token. The broker never proxies the signup or sees the response or a provider credential.

identity_register

Title: "Create or resume agent sub-identity". Registers the agent sub-identity for the authenticated session, or returns the one already bound to it.

Inputs

Field Type Required Rule
name string no Display name. Defaults to opencode-agent; reused when the name/harness already exists for the human owner.
harness string no Harness identifier. Defaults to opencode-v2.

Result: the agent id, name, harness, inbox address, status and human owner. Side effects: may create an agent row; no mail. Errors: agent_revoked, internal_error.

identity_whoami

Title: "Show agent identity & signup state". Returns the active agent profile, verified human owner, recent signups, and the latest acceptance per service, plus documentation links. Auto-provisions a default agent if none exists.

Inputs: none. Result: agent, human, scopes, recent signups, latest acceptances, links. Side effects: may auto-provision; otherwise read-only. Errors: agent_revoked, internal_error.

Use it to check "already signed up?" before calling a side-effecting tool.

identity_prove

Title: "Accept ToS & mint identity assertion". Advanced path. Prefer identity_signup unless you need the raw assertion claims or an explicit agent-supplied discovery object.

Inputs

Field Type Required Rule
audience string yes Exact discovery audience; becomes the assertion aud.
accept_tos_url URL yes terms.url.
accept_tos_hash string yes sha256: over terms.text. Recompute it yourself.
accepted_tos_text string yes Complete terms.text, verbatim.
rp_discovery_url string no Origin or exact discovery URL; the broker fetches it (broker_fetch).
rp_discovery object no Complete discovery document as received (agent_supplied_discovery); requires rp_origin.
rp_origin string no Required with rp_discovery; forbidden with rp_discovery_url. Never inferred from terms.url or provider_url.
requested_scopes string[] no Defaults to ["tos:accept","signup:free_tier"]; every entry must be granted.
force_new boolean no New acceptance even if one exists.

Supplying both discovery sources, neither origin with rp_discovery, an origin with rp_discovery_url, or a raw rp_attestation is discovery_source_not_allowed. A require policy rejects agent_supplied_discovery.

Result: assertion (jwt, jti, kid, typ, hash, timestamps, claims for inspection only), verification instructions, scopes, acceptance, reuse, optional rp_verification, optional rp_verification_warning, side_effects, agent/audience, ledger email. The assertion gains no RP claim; verification lives in rp_verifications.

Side effects: acceptance, ledger email/forward, mint-time verification row, assertion. Retry: identical calls reuse the assertion while unexpired; all gates and policy re-run. ledger_email_failed is retryable after the acceptance is recorded.

identity_record_signup

Title: "Record signed-up service proof". Records (or confirms) a signup proof for this agent. Supply exactly one source.

Inputs

Field Type Required Rule
signup_token string one source The RP-signed v1.2 receipt (agent-signup-receipt+jwt).
rp_attestation string no The exact attestation that contained the receipt key. Omit to fetch discovery at the receipt origin; the broker then requires the exact service.attestation_jti.
self_report object one source {service_audience, provider_name, provider_account_id, signed_up_at, provider_url?} for an RP that issued no receipt. Mutually exclusive with signup_token.

The receipt is verified against the historical attestation named by service.attestation_jti; there is no broker-key fallback and no substitution of the current attestation. A legacy broker-signed receipt is rejected.

A self-report is weaker and unsigned: no proof token, assertion, origin, or verification row; agent_self_reported; it cannot overwrite a stronger proof and still requires a real recorded acceptance.

Result: signup_id, nullable signup_token_jti/assertion_jti, service_audience, provider name/account, human_email_shared, agent_email_used, accepted_tos_hash, context_url/context_sha256, proof_source, deduplicated, nullable rp_verification_id, and the handoff reminder.

Side effects: writes one signup proof row; a Tier-1 or stronger row wins. Retry: idempotent on jti/assertion. Same jti/different body, a different account for the same soft key, or an immutable legacy row is 409.

Errors: signup_token_invalid, signup_token_not_linked, signup_token_ownership_mismatch, discovery_source_not_allowed, rp_attestation_invalid, rp_broker_untrusted, rp_broker_unavailable (retryable), agent_revoked, internal_error (retryable).

inbox_list

Lists recent inbound and outbound messages, newest first.

Field Type Required Rule
limit integer no 1-50, default 10.
direction inbound | outbound no Omit for both.

Result: messages with id, direction, sender/recipient, subject, timestamps and a detected OTP flag. Side effects: none. Errors: agent_revoked, scope_not_granted, internal_error.

inbox_read

Reads one message, including body, headers and any detected six-digit OTP.

Field Type Required
message_id UUID yes

Side effects: none. Errors: message_not_found, agent_revoked, internal_error.

inbox_wait_for_email

Waits for a matching inbound message and returns the newest match.

Field Type Required Rule
from_contains string no Case-insensitive sender substring.
subject_contains string no Case-insensitive subject substring.
since_seconds_ago integer no Lookback seconds, default 60.
timeout_seconds integer no 1-60, default 30.

Side effects: none. Errors: wait_timeout (retryable), agent_revoked, internal_error. Do not poll tightly; prefer one wait with a reasonable budget.

inbox_send

Sends mail from the agent inbox.

Field Type Required
to email yes
subject string yes
text string yes
html string no

Side effects: sends email and records the message. Retry: not idempotent. Errors: send_failed (retryable; nothing sent), scope_not_granted, agent_revoked, internal_error (check side_effects.email_sent before resending).

Verification record

The tool names, input shapes, and result keys above were checked against the shared MCP schema and the tool registration at broker commit 5e57ecf on 2026-10-24. There are nine tools. identity_signup is registered before identity_prove and is preferred in the server instructions and all four resources. Live tools/list and per-tool calls are re-run in the release verification; this page does not claim a live deployment of the v1.2 broker.

sections

type to search.

up/down navigateenter selectesc close