MCP technical docs

MCP Technical Docs

This page is for actual integration work. It documents the MCP endpoint, session setup, signature model, tool reference, resources, and common errors.

MCP Endpoint

Use the public MCP endpoint below for all official integrations:

https://api.fromaiagent.com/mcp

Transport and session

The transport is Streamable HTTP style: `POST /mcp` carries JSON-RPC messages and `GET /mcp` returns SSE notifications for a session.

HTTPMCP methodUse
POST /mcpinitializeStart an MCP session and receive the `MCP-Session-Id` response header.
POST /mcptools/listList all MCP tool definitions.
POST /mcptools/callCall a tool. Pass tool arguments in `params.arguments`.
POST /mcpresources/listList supported resources.
POST /mcpresources/readRead a resource payload. Mailbox event resources require signature material.
POST /mcpresources/subscribeSubscribe to resource updates. Requires `MCP-Session-Id` and signature material.
POST /mcpresources/unsubscribeRemove a resource subscription.
GET /mcpSSE notificationsPoll `notifications/resources/updated` with `MCP-Session-Id`.

Signing model

All mailbox-mutating tools except `get_mailbox_status` depend on Ed25519 signing. MCP callers pass signature material inside tool arguments and the server derives the signed transport headers.

HeaderDescription
x-actor-idThe signing actor identifier.
x-nonceA request-unique nonce.
x-signatureA base64 Ed25519 signature over the signing payload.
METHOD + PATH + actorId + nonce + bodyHash

The signing payload is newline-joined as METHOD, PATH, actorId, nonce, and bodyHash. Sign it with Ed25519 and send the base64 result as `x-signature`.

Minimal flow

  1. Call `initialize` and save the `MCP-Session-Id` response header.
  2. Call `tools/list` or go directly to `create_mailbox`.
  3. Solve the returned challenge and submit it with `answer_challenge`.
  4. After activation, use `send_mail`, `list_mails`, `get_mail`, `get_mail_attachment`, and `watch_mailbox`.
  5. If you need resource notifications, subscribe to `mailbox://{mailbox_id}/events` with `resources/subscribe`.

1. initialize request

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {}
}

initialize response

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2026-04-01",
    "capabilities": {
      "resources": {
        "subscribe": true
      }
    },
    "serverInfo": {
      "name": "fromaiagent-core",
      "version": "0.1.0"
    }
  }
}

MCP-Session-Id: <response-header>

2. create_mailbox

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "create_mailbox",
    "arguments": {
      "mailboxId": "mbx_agent_001",
      "address": "<mailbox-address>",
      "publicKey": "<base64-ed25519-public-key>",
      "actorId": "agent-runtime",
      "nonce": "nonce-register-001",
      "privateKeyPkcs8": "<base64-pkcs8-private-key>"
    }
  }
}

3. send_mail

{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "send_mail",
    "arguments": {
      "mailboxId": "mbx_agent_001",
      "publicKey": "<base64-ed25519-public-key>",
      "actorId": "agent-runtime",
      "nonce": "nonce-send-001",
      "privateKeyPkcs8": "<base64-pkcs8-private-key>",
      "to": "<recipient-address>",
      "subject": "Project update",
      "bodyText": "Here is the latest status."
    }
  }
}

4. get_mail_attachment

{
  "jsonrpc": "2.0",
  "id": 4,
  "method": "tools/call",
  "params": {
    "name": "get_mail_attachment",
    "arguments": {
      "mailboxId": "mbx_agent_001",
      "publicKey": "<base64-ed25519-public-key>",
      "actorId": "agent-runtime",
      "nonce": "nonce-attachment-001",
      "privateKeyPkcs8": "<base64-pkcs8-private-key>",
      "mailId": "<mail-id>",
      "attachmentId": "0"
    }
  }
}

Tool Reference

create_mailbox

Register a new mailbox and receive a registration challenge.

Inputs

FieldTypeRequiredDescription
mailboxIdstringyesA client-generated unique mailbox ID.
addressstringyesThe mailbox address to register.
publicKeybase64 Ed25519 raw keyyesThe public key used to control the mailbox.
actorIdstringyesThe signing actor identifier.
noncestringyesUnique per request.
privateKeyPkcs8base64 PKCS#8yesThe private key used to sign the request.
currentRatePolicystringnoOptional rate policy. Defaults to `default`.

Returns

FieldTypeDescription
mailboxIdstringThe mailbox ID.
status`pending_challenge`The current state.
publicKeyFingerprintstringThe public key fingerprint.
challengeobjectIncludes `challengeId`, `challengeType`, `prompt`, and `expiresAt`.

get_mailbox_status

Read mailbox status. This tool does not require a signature.

Inputs

FieldTypeRequiredDescription
mailboxIdstringnoUse either `mailboxId` or `address`.
addressstringnoUse either `address` or `mailboxId`.

Returns

FieldTypeDescription
mailboxIdstringThe mailbox ID.
addressstringThe mailbox address.
statusstringThe current status, such as `pending_challenge` or `active`.
publicKeyFingerprintstringThe current key fingerprint.
currentRatePolicystringThe current policy name.
createdAt / updatedAtISO timestampCreation and update timestamps.

answer_challenge

Submit the registration challenge. A successful answer activates the mailbox.

Inputs

FieldTypeRequiredDescription
mailboxIdstringyesThe mailbox ID.
challengeIdstringyesReturned by `create_mailbox`.
answerstringyesThe challenge answer. The default challenge expects a lowercase SHA-256 hex digest.
publicKeybase64 Ed25519 raw keyyesThe current mailbox public key.
actorId / nonce / privateKeyPkcs8stringyesSignature material.

Returns

FieldTypeDescription
mailboxIdstringThe mailbox ID.
status`active`The active status after a successful answer.

send_mail

Queue an outbound email. The initial delivery state is `queued`.

Inputs

FieldTypeRequiredDescription
mailboxIdstringyesThe mailbox ID.
publicKeybase64 Ed25519 raw keyyesThe current mailbox public key.
tostringyesThe destination email address.
subjectstringnoThe mail subject.
bodyTextstringnoPlain-text body content.
attachmentTextstringnoSearchable text extracted from attachments.
actorId / nonce / privateKeyPkcs8stringyesSignature material.

Returns

FieldTypeDescription
mailIdstringThe mail ID.
threadIdstringThe thread ID.
folder`sent`The current folder.
deliveryStatus`queued`The current delivery state.
createdAtISO timestampCreation time.

list_mails

List mails with cursor-based pagination. Trash is excluded by default.

Inputs

FieldTypeRequiredDescription
mailboxIdstringyesThe mailbox ID.
publicKeybase64 Ed25519 raw keyyesThe current mailbox public key.
folder`inbox | sent | trash`noFilter by folder.
includeTrashbooleannoInclude trash when `true`.
limitnumbernoDefaults to 20. Maximum 100.
cursornumbernoPagination offset.
actorId / nonce / privateKeyPkcs8stringyesSignature material.

Returns

FieldTypeDescription
mailsMailSummary[]An array of mail summaries.
nextCursornumber | nullThe next pagination offset.

search_mails

Run full-text search across subject, snippet, body text, and text attachments.

Inputs

FieldTypeRequiredDescription
mailboxIdstringyesThe mailbox ID.
publicKeybase64 Ed25519 raw keyyesThe current mailbox public key.
querystringyesThe full-text query.
includeTrashbooleannoInclude trash when `true`.
limitnumbernoDefaults to 10. Maximum 100.
actorId / nonce / privateKeyPkcs8stringyesSignature material.

Returns

FieldTypeDescription
mailsMailSummary[]The matched mail summaries.

get_mail

Fetch the full stored record for a single mail.

Inputs

FieldTypeRequiredDescription
mailboxIdstringyesThe mailbox ID.
publicKeybase64 Ed25519 raw keyyesThe current mailbox public key.
mailIdstringyesThe mail ID.
actorId / nonce / privateKeyPkcs8stringyesSignature material.

Returns

FieldTypeDescription
mailId / threadId / mailboxIdstringIdentity fields.
direction / folder / deliveryStatusstringMail direction, folder, and delivery state.
fromAddress / toAddress / subject / snippetstringPrimary addressing and summary fields.
bodyText / attachmentTextstringText content ready for model use.
attachmentsMailAttachmentSummary[]Attachment metadata including `attachmentId`, `filename`, and `contentType`.
retentionUntilISO timestamp | nullTrash retention deadline.

get_mail_attachment

Fetch one attachment. The binary stays in private R2 and `core` returns controlled base64 content.

Inputs

FieldTypeRequiredDescription
mailboxIdstringyesThe mailbox ID.
publicKeybase64 Ed25519 raw keyyesThe current mailbox public key.
mailIdstringyesThe mail ID.
attachmentIdstringyesThe attachment identifier returned by `get_mail`.
actorId / nonce / privateKeyPkcs8stringyesSignature material.

Returns

FieldTypeDescription
mailId / attachmentIdstringMail and attachment identifiers.
filename / contentTypestring | nullThe attachment filename and MIME type.
encoding`base64`The encoding used for the returned payload.
contentBase64stringThe attachment bytes encoded as base64.

delete_mail

Move a mail into trash with a fixed 30-day retention window.

Inputs

FieldTypeRequiredDescription
mailboxIdstringyesThe mailbox ID.
publicKeybase64 Ed25519 raw keyyesThe current mailbox public key.
mailIdstringyesThe mail ID.
actorId / nonce / privateKeyPkcs8stringyesSignature material.

Returns

FieldTypeDescription
mailIdstringThe mail ID.
folder`trash`The target folder.
retentionUntilISO timestampThe cleanup deadline.
retentionDays`30`The fixed retention window.

restore_mail

Restore a trashed mail to its prior folder.

Inputs

FieldTypeRequiredDescription
mailboxIdstringyesThe mailbox ID.
publicKeybase64 Ed25519 raw keyyesThe current mailbox public key.
mailIdstringyesThe mail ID.
actorId / nonce / privateKeyPkcs8stringyesSignature material.

Returns

FieldTypeDescription
mailIdstringThe mail ID.
folderstringThe restored folder.
retentionUntilISO timestamp | nullUsually `null` after restore.

list_threads

List conversation threads with cursor-based pagination.

Inputs

FieldTypeRequiredDescription
mailboxIdstringyesThe mailbox ID.
publicKeybase64 Ed25519 raw keyyesThe current mailbox public key.
limitnumbernoDefaults to 20. Maximum 100.
cursornumbernoPagination offset.
actorId / nonce / privateKeyPkcs8stringyesSignature material.

Returns

FieldTypeDescription
threadsThreadSummary[]The thread summaries.
nextCursornumber | nullThe next pagination offset.

rotate_key

Rotate the mailbox control key.

Inputs

FieldTypeRequiredDescription
mailboxIdstringyesThe mailbox ID.
currentPublicKeybase64 Ed25519 raw keyyesThe current mailbox key.
nextPublicKeybase64 Ed25519 raw keyyesThe next mailbox key.
actorId / nonce / privateKeyPkcs8stringyesThe private key must correspond to `currentPublicKey`.

Returns

FieldTypeDescription
mailboxIdstringThe mailbox ID.
statusstringThe mailbox status.
publicKeyFingerprintstringThe fingerprint of the next key.

watch_mailbox

Long-poll the mailbox event stream.

Inputs

FieldTypeRequiredDescription
mailboxIdstringyesThe mailbox ID.
publicKeybase64 Ed25519 raw keyyesThe current mailbox public key.
cursornumbernoThe starting event cursor.
limitnumbernoDefaults to 50. Maximum 100.
timeoutMsnumbernoDefaults to 1000. Maximum 10000.
actorId / nonce / privateKeyPkcs8stringyesSignature material.

Returns

FieldTypeDescription
eventsDeliveryEventRecord[]An array of events including `cursor`, `eventId`, `eventType`, and `payload`.
nextCursornumberThe cursor to use for the next poll.
timedOutbooleanReturns `true` when no new events arrive before the timeout.

Resource subscription

The public resource is `mailbox://{mailbox_id}/events`. It returns JSON with `mailboxId`, `cursor`, `nextCursor`, and `events`. After subscribing, `GET /mcp` yields `notifications/resources/updated` over SSE.

mailbox://{mailbox_id}/events

When subscribing to a resource, send `uri`, `publicKey`, `actorId`, `nonce`, and `privateKeyPkcs8` in `params`.

Common errors

ErrorWhen it happens
missing_mcp_session_idThe request is missing the MCP session header.
missing_mcp_signature_materialA resource request is missing `actorId`, `nonce`, `privateKeyPkcs8`, or `publicKey`.
missing_signature_headersThe signed transport headers are missing.
invalid_signatureSignature verification failed, usually because the key or payload does not match.
invalid_request_signatureThe key material or signature payload could not be parsed.
nonce_reuse_with_different_requestThe same `actorId + nonce` was reused for a different request body.
challenge_answer_incorrectThe challenge answer is wrong.
challenge_expiredThe challenge has expired.
challenge_already_answeredThe challenge was already submitted.
mailbox_not_foundThe mailbox does not exist or the mailboxId is wrong.
mail_not_foundThe requested mail does not exist.
stale_current_public_keyThe current key used for rotation is no longer valid.
invalid_public_keyThe next public key is malformed.
method_not_supportedThe MCP method is not implemented.