Bridges
Chio mediates several upstream protocols through bridge and edge crates. Each surface routes invocations through the kernel guard pipeline, produces a signed receipt, and reports a fidelity rating so clients can tell whether the projection is lossless, adapted, or unsupported.
Source
This page normatively reflects spec/BRIDGES.md in the chio repository. Status: Normative companion to PROTOCOL.md. Version 3.0.
Shared invariant
Bridge Model
Two integration shapes appear in the spec:
- Bridges map an upstream protocol surface inward to MCP-style Chio tools. The OpenAPI-to-MCP bridge takes an OpenAPI spec and exposes each operation as an MCP tool.
- Edges project Chio kernel-governed tools outward to a different protocol. The A2A and ACP edges serve Chio tools to A2A and ACP clients respectively. The OpenAI adapter wraps OpenAI-style function calls.
In every case the kernel evaluates the invocation, signs the receipt, and emits the result through the originating surface.
Fidelity Levels
All edges classify each tool projection at registration time using a three-level rating. The rating is reported to clients in discovery metadata so they can decide whether the surface is sufficient for their needs.
| Level | Meaning | Guidance |
|---|---|---|
lossless | The Chio tool maps cleanly to the target protocol's native primitives | No caveats are required and the bridge MAY publish by default |
adapted | The Chio tool is publishable only with explicit caveats | Discovery metadata MUST surface the caveats honestly |
unsupported | The target protocol cannot represent the required semantics honestly | The tool MUST remain unpublished on that surface |
Per-Protocol Fidelity Matrix
The matrix below summarizes how each surface handles common Chio feature requirements. Cells reflect the rules in the per-protocol sections that follow.
| Feature | OpenAPI bridge | A2A edge | ACP edge | OpenAI adapter |
|---|---|---|---|---|
| Capability validation | lossless | lossless | lossless | lossless |
| Signed receipts | lossless | lossless | lossless | lossless |
| Side-effecting tools | lossless (via DenyByDefault) | adapted (caveat surfaced) | adapted (permission required) | lossless |
| Approval-required tools | lossless | unsupported | unsupported | lossless |
| Streaming output | unsupported | deferred task lifecycle | deferred task lifecycle | not applicable |
| Cancellation | unsupported | via task/cancel | via tool/cancel | not applicable |
| Filesystem / terminal tools | not applicable | adapted | lossless (native categories) | lossless |
| Browser tools | not applicable | adapted | unsupported (auto-suppressed) | lossless |
OpenAPI-to-MCP Bridge
Crate: chio-openapi-mcp-bridge. The bridge presents a Chio-governed HTTP API as an MCP tool surface. Given an OpenAPI 3.x specification, it produces a manifest, exposes each operation as an MCP tool, and routes invocations through the kernel before dispatching to the upstream HTTP API.
Scope
- Parses the spec via
chio-openapito produceToolDefinitionvalues. - Wraps each HTTP operation as an MCP-visible tool via
chio-mcp-edge. - Routes invocations through the kernel for capability validation and receipt signing before dispatch.
Manifest validity
chio.manifest.v1 manifest from the OpenAPI spec. If the spec contains zero publishable operations, the bridge MUST reject construction with a manifest error.tools/list Generation
Each (method, path) pair becomes one entry in the MCP tools/list response.
| OpenAPI field | MCP tool field | Notes |
|---|---|---|
operationId | name | Falls back to "{METHOD} {path}" when absent |
summary / description | description | Concatenated when both present |
| Request body schema or parameters | inputSchema | Merged into a single JSON Schema object |
| Response schema (200/201) | outputSchema | Optional; included when include_output_schemas is set |
| HTTP method | annotations.readOnlyHint | true for GET/HEAD/OPTIONS; false otherwise |
The bridge MUST set has_side_effects to false for GET, HEAD, and OPTIONS operations and true for all other HTTP methods. When x-chio-* extensions are present, they propagate to the corresponding ToolDefinition fields per the rules on the OpenAPI Integration page.
Invocation Flow
The bridge MUST resolve the route binding from the tool name before dispatching. If the tool name does not match any known route binding, the bridge MUST return a ToolNotFound error without contacting the upstream API.
The structuredContent field in the MCP response MUST include:
httpStatus: HTTP status from the upstream responsemethod: HTTP method usedpath: URL path templatebody: parsed response body
Receipt Generation
Every bridged invocation that reaches the upstream HTTP API MUST produce a signed Chio receipt. The receipt MUST include:
tool_name: the MCP tool name (derived fromoperationId)server_id: the bridge's configured server IDdecision:allowfor successful invocations;denyif the guard pipeline rejects
Simulation mode
structuredContent.bridgeMode to "simulation" and SHOULD NOT produce receipts since no upstream call occurs.Kernel Integration
The bridge implements ToolServerConnection, allowing direct registration with a kernel instance. Two variants exist:
BridgeToolServer<'a>: borrows the bridge for scoped registration.OwnedBridgeToolServer: consumes the bridge for long-lived registration.
Both delegate invoke() to the bridge's internal dispatch logic, mapping BridgeError to KernelError::ToolServerError. See the bridge OpenAPI to MCP guide and the OpenAPI sidecar example.
A2A Edge
Crate: chio-a2a-edge. The A2A edge exposes Chio kernel-governed tools as A2A skills. This is the reverse of chio-a2a-adapter: instead of consuming a remote A2A server, this crate serves Chio tools to external A2A clients. Every invocation flows through the kernel guard pipeline, producing a signed receipt.
Agent Card Generation
The edge MUST serve an Agent Card at /.well-known/agent-card.json. The card is generated from the edge configuration and registered tool manifests.
| Field | Source | Notes |
|---|---|---|
name | A2aEdgeConfig.agent_name | MUST be non-empty |
description | A2aEdgeConfig.agent_description | Human-readable summary |
version | A2aEdgeConfig.agent_version | Semantic version |
supportedInterfaces | Derived from config | One entry per endpoint URL |
capabilities.streaming | Fixed false on the authoritative profile | Chio does not advertise a receipt-bearing push-stream lifecycle |
defaultInputModes | ["text"] | Fixed for current implementation |
defaultOutputModes | ["text"] | Fixed for current implementation |
skills | Derived from tool manifests | One skill per Chio tool |
Each interface entry MUST include:
url: A2A endpoint URLprotocolBinding: protocol binding (default"JSONRPC")protocolVersion:"1.0"
Skill Projection
Each Chio ToolDefinition from registered manifests becomes one A2A skill entry.
| Chio field | A2A skill field | Notes |
|---|---|---|
tool.name | id, name | Skill ID matches the Chio tool name |
tool.description | description | Passed through unchanged |
| (inferred) | tags | Empty by default; MAY be populated by operators |
| (fixed) | inputModes | ["text"] |
| (fixed) | outputModes | ["text"] |
tool.has_side_effects | bridgeFidelity | Used as fidelity signal |
Ambiguous names
SendMessage and SendStreamingMessage
message/send is a blocking request. The edge resolves the target skill from params.metadata.chio.targetSkillId. If only one skill is registered, the edge MAY infer the target. With multiple skills and no target, the edge MUST return JSON-RPC error code -32602.
The task response MUST include:
id: monotonically increasing identifier (formata2a-task-{n})status:completedon success;failedon tool server errormessage: present when status iscompleted; carries the converted tool resultstatusMessage: present when status isfailed; carries the error description
message/stream is exposed as a deferred receipt-bearing task lifecycle rather than a push-stream transport. It MUST resolve the target skill using the same rules, create a working TaskResponse with signed-authority metadata and receiptPending = true, persist the deferred execution request under the returned task ID, and require follow-up task/get or task/cancel calls to resolve or cancel the task. task/get MUST execute the deferred request through the authoritative path the first time it is called for a working task. Terminal task results MUST carry the same signed receipt metadata as message/send.
Result Conversion
| Result type | A2A part type | Conversion |
|---|---|---|
| String value | text | Used directly |
Object with content array | text (per entry) | Each content[].text becomes a text part |
| Other object or array | data | Passed through as structured data |
| Other scalar | text | Converted via to_string() |
A2A BridgeFidelity Evaluation
| Level | Criteria | Implications |
|---|---|---|
lossless | Tool is publishable and does not depend on approval, deferred-stream, cancellation, or partial-output caveats | The current A2A edge can project the tool without semantic loss |
adapted | Tool is publishable but side-effect, deferred-stream, cancellation, or partial-output semantics require explicit caveats | The edge preserves the tool but MUST surface caveats in discovery metadata |
unsupported | Tool requires interactive approval or explicit publication suppression (x-chio-publish: false) | The tool MUST NOT be auto-published on the A2A surface |
The bridgeFidelity field is included in each skill entry. Clients SHOULD use this field to assess whether the A2A interface is sufficient. unsupported skills are withheld from the Agent Card entirely. The implementation reads these semantic hints when present on the tool schema:
x-chio-publishx-chio-approval-requiredx-chio-streamingx-chio-cancellationx-chio-partial-output
See the A2A adapter integration page and the hello-a2a example.
Kernel-Mediated Receipts
Every SendMessage invocation that reaches the tool server MUST flow through the kernel guard pipeline. The signed receipt includes:
tool_name: matches the A2A skill IDserver_id: from the manifest that owns the tooldecision:allowfor completed tasks;denyfor guard rejections
When the tool server returns an error, the task status is failed but a receipt is still generated with the deny or incomplete decision as appropriate.
ACP Edge
Crate: chio-acp-edge. The edge exposes Chio kernel-governed tools as ACP (Agent Client Protocol) capabilities so ACP-compatible editors and IDEs can reach Chio tools through the ACP permission model.
ACP organizes tools around four categories: filesystem, terminal, browser, and generic tool. The edge maps Chio tools into this model with category inference and fidelity assessment.
Capability Mapping
| Chio field | ACP capability field | Notes |
|---|---|---|
tool.name | id, name | Capability ID matches the Chio tool name |
tool.description | description | Passed through unchanged |
| (inferred) | category | See the inference rules below |
tool.has_side_effects + config | requiresPermission | true when config requires permission OR the tool has side effects |
| (evaluated) | bridgeFidelity | See the fidelity rules below |
Category Inference and Routing
The edge infers the ACP category from the tool name using keyword matching, applied in order:
| Pattern | Category | Examples |
|---|---|---|
Name contains read_file, write_file, list_dir, or starts with fs_ | filesystem | read_file, fs_stat, write_file |
Name contains terminal, exec, shell, or command | terminal | exec_command, run_shell |
Name contains browser, navigate, or screenshot | browser | browser_click, take_screenshot |
| No match | tool (configurable default) | search, get_weather |
When no pattern matches, the edge MUST fall back to AcpEdgeConfig.default_category, which defaults to tool.
Permission Evaluation
The edge implements fail-closed permission evaluation backed by Chio capabilities. It handles session/request_permission requests by:
- Looking up the capability by ID. If unknown, the edge MUST return
deny. - If
requiresPermissionistrue, the edge MUST returndenyby default. Explicit permission grants require kernel capability token validation (full integration deferred to Phase 324). - If
requiresPermissionisfalse, the edge MUST returnallow.
ACP BridgeFidelity Assessment
| Level | Criteria | Implications |
|---|---|---|
lossless | Category is filesystem or terminal and no caveated semantic hints are present | ACP natively supports the projection without caveats |
adapted | Capability is publishable but depends on permission-preview, collected streaming, partial-output, cancellation, or generic-tool-category caveats | The capability remains discoverable but caveats MUST be surfaced in bridgeFidelity |
unsupported | Category is browser, category is generic mutating tool, or publication is disabled with x-chio-publish: false | The capability MUST NOT be auto-published on the ACP surface |
unsupported capabilities are withheld from session/list_capabilities.
JSON-RPC Interface
| Method | Purpose | Response |
|---|---|---|
session/list_capabilities | List all ACP capabilities | { capabilities: [...] } |
session/request_permission | Evaluate permission for a capability | { decision: "allow" | "deny" } |
tool/invoke | Invoke a capability through the kernel | Invocation result or error |
tool/stream | Create a deferred authoritative invocation task | { task: {...} } |
tool/cancel | Cancel a deferred invocation task before execution | { task: {...} } |
tool/resume | Resolve a deferred invocation task through the kernel | { task: {...}, result: {...} } |
Unknown methods MUST return JSON-RPC error code -32601.
See the wrap an ACP server guide and the hello-acp example.
OpenAI Adapter
Crate: chio-openai. The adapter intercepts OpenAI-style tool_use / function-calling requests and routes them through the Chio kernel for capability validation and receipt signing. It supports both the Chat Completions API format and the Responses API format. Every function call produces a signed receipt; guards fail closed by default.
Function Definition Generation
| Chio field | OpenAI field | Notes |
|---|---|---|
tool.name | function.name | Used directly; MUST match the receipt tool_name |
tool.description | function.description | Passed through unchanged |
tool.input_schema | function.parameters | JSON Schema for function parameters |
Chat Completions tool envelope:
[
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the weather for a location",
"parameters": {
"type": "object",
"properties": {
"location": { "type": "string" }
},
"required": ["location"]
}
}
}
]Receipt Behavior
Every function call MUST produce a signed receipt. The receipt MUST include tool_name, server_id, the kernel-issued receipt_ref, and the signed ChioReceipt object when the call reached the kernel.
| Outcome | denied | receipt_ref | Notes |
|---|---|---|---|
| Successful invocation | false | Present | Kernel returns signed receipt with allow verdict |
| Guard denial | true | Present | Kernel returns signed denial receipt |
| Tool server error | true | Present | Kernel returns signed denial receipt |
| Function not found | true | Absent | No kernel interaction occurred |
| Argument parse failure | true | Absent | No kernel interaction occurred |
Batch Execution
execute_tool_calls() processes calls sequentially in input order. A failure in one call MUST NOT prevent execution of subsequent calls. The caller receives the full results array and inspects each entry's denied field individually. Each call that reaches the kernel returns the kernel-issued receipt.id as its receipt_ref.
Cross-Cutting Requirements
Fail-Closed Invariant
All bridges and edges MUST maintain the fail-closed invariant:
- If the kernel is unreachable, requests MUST be denied.
- If a capability token is invalid or expired, requests MUST be denied.
- If guard evaluation produces an error, the request MUST be denied.
- Unknown tools, capabilities, or functions MUST be rejected before any upstream dispatch occurs.
- Unknown JSON-RPC methods MUST return error code
-32601.
Receipt Chain Continuity
Signed receipts from bridged invocations MUST be compatible with the core receipt contract defined in protocol section 6:
- Receipts use the same
chio.receipt.v1schema. - Receipts join the same Merkle-committed receipt log.
- Bridged receipts are indistinguishable from native Chio receipts to downstream consumers (trust-control, evidence export, federation).
Auditors and operators see one unified evidence trail regardless of the protocol surface that originated the invocation.
Related
- OpenAPI integration: extension vocabulary and the
chio api protectcontract. - Protocol: core capability, receipt, and manifest contract.
- Wire protocol: native framed transport.
- Wrap an MCP server.
- Wrap an ACP server.
- A2A adapter.
- hello-a2a and hello-acp examples.