Chio/Docs

Wire Protocol

The shipped Chio wire protocol, defined tightly enough for an independent implementation. Native length-prefixed framing, hosted MCP HTTP session transport, and trust-control lifecycle endpoints share one signed-artifact contract for capabilities and receipts.

When to use this page

Use this page when: you are implementing or validating an independent Chio peer and need the normative framing rules, MCP HTTP session lifecycle headers, and trust-control lifecycle endpoints. Don't use this if: you want capability and receipt field semantics (see Protocol Reference) or HTTP-API protection via the sidecar (see HTTP Substrate).

Source

This page normatively reflects spec/WIRE_PROTOCOL.md in the chio repository. Status: Normative shipped surface. Version 1.0. The keywords MUST, SHOULD, and MAY are normative.


Surface Model

Chio ships four cooperating protocol surfaces:

SurfaceTransportPurpose
Native Chio transportLength-prefixed canonical JSONDirect agent-to-kernel messaging
Hosted MCP edgeJSON-RPC over HTTP POST plus SSERemote session admission and MCP-compatible runtime traffic
Trust-control lifecycle APIsJSON over HTTPCapability issuance, delegated issuance, receipt lookup, revocation
HTTP substrateJSON over HTTP (localhost sidecar)Evaluation and receipt signing for arbitrary HTTP API requests

The native Chio transport does not define a session-initialization message. Initialization in the shipped stack happens on the hosted MCP surface. Native direct peers obtain capability material out of band and then begin sending AgentMessage frames immediately.


Native Chio Transport

Framing

Each native Chio frame is encoded as:

text
+----------------------+---------------------------+
| 4-byte length prefix | canonical JSON payload    |
+----------------------+---------------------------+

Normative rules:

  • The length prefix MUST be an unsigned 32-bit integer in big-endian byte order.
  • The length value MUST count only the payload bytes that follow the prefix.
  • The payload MUST be canonical JSON as produced by RFC 8785-style canonicalization.
  • The maximum permitted payload length is 16,777,216 bytes (16 MiB).
  • A sender MUST NOT emit a larger frame.
  • A receiver MUST reject any frame whose advertised length exceeds that maximum.

Example: a payload length of 256 bytes is encoded as 00 00 01 00.

Sender Requirements

  • Senders MUST serialize native messages as canonical JSON before writing the frame.
  • Senders MUST emit exactly one top-level JSON object per frame.
  • Senders MUST use the discriminators and field names defined in the message catalog.

Receiver Behavior and Error Recovery

  • If EOF occurs before the 4-byte prefix is fully read, the receiver MUST treat the connection as closed and deliver no partial message.
  • If EOF occurs after the prefix but before the full payload is read, the receiver MUST treat the connection as closed.
  • If the advertised length is greater than 16 MiB, the receiver MUST reject the frame as message_too_large.
  • If the payload is not valid JSON for the expected message family, the receiver MUST reject the frame as a deserialization failure.

Recovery: Chio defines no in-band resynchronization marker for the native framed lane. After connection_closed, message_too_large, or deserialization failure, an implementation SHOULD close the current transport and establish a new connection before continuing.


Native Message Catalog

AgentMessage

All agent-to-kernel frames are JSON objects with a type discriminator.

typeRequired fieldsMeaning
tool_call_requestid, capability_token, server_id, tool, paramsInvoke one tool under one signed capability
list_capabilitiesnoneAsk the kernel for the caller's currently valid capabilities
heartbeatnoneLiveness probe

tool_call_request fields:

FieldTypeMeaning
idstringCorrelation identifier echoed by kernel responses
capability_tokenCapabilityTokenSigned authority for this call
server_idstringTarget tool server identifier
toolstringTool name within the target server
paramsJSON valueTool arguments

KernelMessage

typeRequired fieldsMeaning
tool_call_chunkid, chunk_index, dataStreaming chunk emitted before the final response
tool_call_responseid, result, receiptTerminal result plus signed receipt
capability_listcapabilitiesReply to list_capabilities
capability_revokedidNotification that a capability identifier is no longer valid
heartbeatnoneLiveness reply

ToolCallResult

KernelMessage.tool_call_response.result is a tagged object with a status discriminator.

statusRequired fieldsMeaning
okvalueTool completed and returned a value
stream_completetotal_chunksTool completed after streaming chunks
cancelledreason, chunks_receivedExplicit cancellation
incompletereason, chunks_receivedNon-terminal interruption or upstream truncation
errerrorDenial or failure

ToolCallError

ToolCallResult.status = "err" carries a tagged error object with a code discriminator.

codeRequired fieldsMeaning
capability_denieddetail stringCapability was malformed, invalid, or bound to the wrong subject
capability_expirednoneCapability is outside its validity window
capability_revokednoneCapability identifier is revoked
policy_denieddetail.guard, detail.reasonA policy guard denied the action
tool_server_errordetail stringUpstream tool server failed
internal_errordetail stringKernel-side internal failure

Signed Artifact Requirements

Two nested signed Chio artifacts appear directly on the native wire:

  • CapabilityToken
  • ChioReceipt

Preserve nested signed objects

Implementations MUST preserve all fields on those nested objects exactly as received. A native sender MUST NOT rewrite or recanonicalize nested signed object fields prior to forwarding. Receivers SHOULD verify signatures before treating capability or receipt content as authoritative.

Hosted MCP HTTP Session Transport

Endpoint Shape

  • POST /mcp carries JSON-RPC requests and notifications.
  • GET /mcp is the notification replay/live stream.
  • DELETE /mcp terminates an existing session.

Session headers:

  • MCP-Session-Id
  • MCP-Protocol-Version

Initialization Rules

  • An initialize request MUST be sent to POST /mcp.
  • An initialize request MUST be a JSON-RPC request and therefore include an id.
  • An initialize request MUST NOT include MCP-Session-Id.
  • A successful initialize response MUST return an SSE stream and include MCP-Session-Id on the HTTP response.
  • After successful initialize, the client MUST send notifications/initialized before relying on ready-state operations.

Established-Session Rules

  • Non-initialize requests MUST include MCP-Session-Id.
  • If the session has a bound protocol version and the client sends MCP-Protocol-Version, that header MUST match the stored session value.
  • POST requests MUST use Content-Type: application/json.
  • GET notification streams MUST include MCP-Session-Id.
  • Ready-state methods such as tools/list and tools/call MUST not run until the session has received notifications/initialized.

Notification Stream and Replay

  • At most one active GET notification stream is allowed per session.
  • Notification replay uses the Last-Event-ID request header.
  • Event identifiers are encoded as {session_id}-{sequence}.
  • Replay requests outside the retained event window fail with 409 Conflict.
  • Hosted deployments that reuse one upstream owner across multiple sessions MUST keep late notifications and task handles scoped to the originating session. They MUST NOT fan out unattributed notifications or allow a different session to act on a foreign task id.

Hosted Session Lifecycle

Hosted sessions move through these states:

  • initializing
  • ready
  • draining
  • deleted
  • expired
  • closed

Requests against draining, deleted, expired, or closed sessions MUST not silently resume prior state. Clients encountering those terminal states MUST re-run initialization.

Version Negotiation

The machine-readable negotiation artifact for the shipped stack is spec/versions/chio-protocol-negotiation.v1.json.

  • Clients MAY send initialize.params.protocolVersion.
  • The server compares that value against its supported version set.
  • The current shipped implementation supports one MCP protocol version: 2025-11-25.
  • Compatibility determination is therefore an exact-match test against that supported set.
  • There is no downgrade path; unsupported requested versions are rejected rather than silently downgraded.
  • On success, the selected version is echoed in result.protocolVersion and exposed under result.capabilities.experimental.chioProtocol.selectedProtocolVersion.
  • On failure, initialize is rejected with JSON-RPC -32600 plus a structured Chio protocol error descriptor in error.data.chioError.

Model Metadata Admission

  • Hosted tools/call requests MAY carry model metadata under either _meta.modelMetadata or _meta.chioModelMetadata.
  • The hosted edge normalizes that payload into Chio request model_metadata.
  • Caller-supplied metadata MUST be treated as asserted provenance at admission time even if the caller marks it verified.
  • Receipts and downstream exports MUST preserve the effective provenance class instead of silently upgrading caller assertions into verified runtime truth.

Native Direct Transport Versioning

  • Native Chio framed transport is currently chio-wire-v1.
  • Native direct peers do not negotiate in-band today; compatibility is an exact-match, out-of-band requirement.
  • Because no in-band downgrade exists, incompatible native peers MUST close or reset the transport instead of attempting best-effort interop.

Trust-Control Capability Lifecycle

The trust-control service is implemented by chio trust serve.

Capability Issuance

Endpoint: POST /v1/capabilities/issue.

Request body:

FieldTypeMeaning
subjectPublicKeystringEd25519 subject key in hex
scopeChioScopeCapability scope to issue
ttlSecondsintegerRequested lifetime
runtimeAttestationobject, optionalAttestation evidence used by issuance policy

Success response: { "capability": <CapabilityToken> }.

Federated / Delegated Issuance

Endpoint: POST /v1/federation/capabilities/issue.

Delegation-relevant request fields:

FieldMeaning
presentationPassport presentation proving federated subject identity
expectedChallengeChallenge the presentation must satisfy
capabilityRequested issued capability body
delegationPolicyOptional signed ceiling for delegated issuance
upstreamCapabilityIdOptional imported parent capability anchor for multi-hop lineage

Success response fields:

FieldMeaning
capabilityNewly issued child capability
delegationAnchorCapabilityIdOptional lineage anchor persisted by trust-control
subjectPublicKeyResolved subject key used for issuance

Normative delegation rules:

  • If upstreamCapabilityId is supplied, the request MUST also carry a delegation policy bound to that exact parent capability id.
  • If a delegation policy is supplied, the requested child capability MUST NOT exceed the policy ceiling.
  • The trust-control service MUST reject untrusted delegation-policy signers.

Receipt Query

Endpoint: GET /v1/receipts/query.

Supported query parameters: capabilityId, toolServer, toolName, outcome, since, until, minCost, maxCost, cursor, limit, agentSubject.

Response body fields: totalCount (integer), nextCursor (integer or null), receipts (array of receipt rows).

Revocation

Endpoint: POST /v1/revocations.

Request body: { capabilityId: string }.

Success response fields: capabilityId, revoked (boolean), newlyRevoked (boolean, whether this call changed state).


Error Taxonomy

The machine-readable error registry for the shipped stack is spec/errors/chio-error-registry.v1.json. Registry guarantees:

  • every Chio error entry has a unique numeric code
  • every entry names one category
  • every entry is marked transient: true|false
  • every entry carries explicit retry guidance

Current registry categories: protocol, auth, capability, guard, budget, tool, internal.

Surface mapping rules:

  • Native Chio ToolCallError discriminators map deterministically to registry entries such as capability_denied, capability_expired, capability_revoked, guard_denied, tool_server_error, and internal_error.
  • Hosted MCP initialize-time protocol rejection communicates the numeric Chio protocol code under JSON-RPC error.data.chioError.code.
  • Trust-control remains HTTP-status-driven, but registry codes define the stable cross-surface classification and retry semantics.

HTTP Substrate Surface

The HTTP substrate is a fourth cooperating protocol surface alongside the native Chio transport, the hosted MCP edge, and the trust-control lifecycle APIs. It enables Chio to evaluate and sign receipts for arbitrary HTTP API requests, not only agent-protocol traffic.

The HTTP substrate uses a sidecar model. A Chio kernel runs as a local process and exposes three HTTP endpoints on localhost:

EndpointMethodPurpose
/chio/evaluatePOSTEvaluate an HTTP request against loaded policy
/chio/verifyPOSTVerify a receipt signature
/chio/healthGETSidecar health check

All language-specific SDKs consume this surface. They are thin HTTP clients over the sidecar evaluation protocol, not independent policy engines. The kernel remains the single trust anchor for capability validation, guard evaluation, and receipt signing. See the HTTP Substrate page for the full normative spec.


Schemas and Conformance

Versioned native message schemas live under:

  • spec/schemas/chio-wire/v1/agent/
  • spec/schemas/chio-wire/v1/kernel/
  • spec/schemas/chio-wire/v1/result/
  • spec/schemas/chio-wire/v1/error/

Schema files in those directories are the machine-readable contract for the native Chio message families. Implementations MUST continue to serialize the native message variants in a form accepted by those schemas. Schema validation MUST be exercised against live Rust serialization, not handwritten examples alone.