Transport parity matrix
Chorus exposes the same core operations through several public surfaces. They are intended for different callers, so do not infer a command name on one surface from another surface’s name.
Choose a surface
Section titled “Choose a surface”| Caller | Recommended surface | Why |
|---|---|---|
| TypeScript service or automation | SDK | Typed resource methods, response types, error handling, and pagination helpers |
| Tool-using agent | Standalone MCP | Discoverable chorus_* tools over local stdio or a shared remote-safe HTTP wrapper |
| Human operator | CLI | Focused, scriptable commands with table or JSON output |
| Non-TypeScript integration | REST | Conventional routes described by the generated OpenAPI document |
| Client that needs canonical command dispatch | JSON-RPC | Dot-style command IDs through POST /rpc when that command has a registered RPC method |
| In-process Chorus extension | Embedded MCP | Server-owned tools without the standalone chorus_ prefix |
The SDK uses REST and JSON-RPC internally. SDK callers normally should not choose between those wire formats themselves.
Naming rules
Section titled “Naming rules”The command catalog ID is the canonical operation name. A registered dot-style JSON-RPC method uses that ID verbatim. REST routes, SDK methods, MCP tools, and CLI commands use names suited to their callers.
The two MCP surfaces are distinct:
- The standalone
chorus-mcppackage exposeschorus_*tools. Its complete local/stdio tool list is generated from the live registry. - Shared HTTP mode uses the same standalone registry but omits five operations that would access
paths on the MCP service host:
chorus_artifact_upload,chorus_artifact_upload_many,chorus_artifact_download,chorus_workspace_upload_file, andchorus_workspace_download_file. - The MCP server embedded in Chorus exposes server-owned names such as
admin_object_storage_health. Do not add or removechorus_mechanically; consult the registry for the surface you are connected to.
Legacy slash-style JSON-RPC aliases remain for compatibility in selected domains. New raw RPC integrations should use the registered dot-style method when one exists.
MCP protocol-local errors
Section titled “MCP protocol-local errors”Both embedded and standalone MCP transports carry transport failures in JSON-RPC
error.data.chorus_code. These transport codes are shared and typed by the SDK’s
MCP_PROTOCOL_ERROR_CODES set:
MCP_BODY_INVALIDMCP_BODY_TOO_LARGEMCP_MEDIA_TYPE_UNSUPPORTEDMCP_RESPONSE_TOO_LARGEMCP_BATCH_UNSUPPORTEDMCP_PROTOCOL_VERSION_REQUIREDMCP_RUNTIME_INCOMPATIBLE(standalone runtime-tree compatibility checks)MCP_AUTHORITY_VALIDATION_FAILED(standalone could not safely classify the upstream authority failure)
The standalone tool wrapper also has a distinct MCP_TOOL_ERROR_CODES set for codes rendered
inside failed CallToolResult text: MCP_OUTPUT_VALIDATION_FAILED,
MCP_RESPONSE_TOO_LARGE, MCP_TOOL_INPUT_INVALID, and MCP_TOOL_INTERNAL_ERROR.
MCP_RESPONSE_TOO_LARGE can appear on either carrier; the others are tool-result-only.
They are deliberately separate from the REST/HTTP error catalog. An MCP error may travel over
HTTP 200 as a JSON-RPC error or over stdio, so assigning it one canonical HTTP status would be
incorrect. HTTP MCP admission can additionally forward ordinary Chorus REST error codes such as
AUTH_KEY_INVALID or RATE_LIMIT_EXCEEDED in the same chorus_code field.
Object-storage administration
Section titled “Object-storage administration”All three object-storage administration operations require an admin identity. They are available on every public surface shown below.
| Operation | Catalog / JSON-RPC | REST | Embedded MCP | Standalone MCP | SDK | CLI |
|---|---|---|---|---|---|---|
| Health | admin.object_storage.health |
GET /admin/object-storage/health |
admin_object_storage_health |
chorus_admin_object_storage_health |
client.admin.objectStorageHealth() |
chorus admin object-storage health |
| List operations | admin.object_storage.list |
GET /admin/object-storage/operations |
admin_object_storage_list |
chorus_admin_object_storage_list |
client.admin.objectStorageOperations(options) |
chorus admin object-storage list |
| Retry cleanup | admin.object_storage.retry_cleanup |
POST /admin/object-storage/operations/:id/retry-cleanup |
admin_object_storage_retry_cleanup |
chorus_admin_object_storage_retry_cleanup |
client.admin.retryObjectStorageCleanup(id) |
chorus admin object-storage retry-cleanup ID |
Inputs and safety boundaries
Section titled “Inputs and safety boundaries”Health takes no input and returns fixed aggregate counters.
List accepts these optional fields:
states: up to eight unique operation states:prepared,uploading,uploaded,cleanup_pending,pending_delete,committed,completed, anddead_letter. REST and CLI encode the list as a comma-separated query value; RPC, MCP, and the SDK use an array.after: thecursorreturned by the previous page. Pass it back unchanged.limit: page size from 1 to 100; the default is 50.
Each listed operation ID is canonical: object_storage_operation: followed by 32 lowercase
hexadecimal characters. The list response contains operations, cursor, and has_more.
Health, list, retry results, and retry audit details are deliberately secret-free. They do not return provider URLs, physical or logical object keys, references, request metadata, lease authority, or arbitrary provider error text.
Retry accepts only the operation ID. The server owns provider verification, reference checks, lease generation, and accounting settlement:
- A dead-lettered upload produces
action: "upload_cleanup_observed". It records a bounded cleanup observation and retains the tombstone and accounting authority. - A dead-lettered delete produces
delete_retry_completed,delete_retry_pending, ordelete_retry_in_progress. The server creates or reuses the fenced retry chain and reports whether accounting remains retained.
Do not invent flags such as “provider absent” or “settled”; no public surface accepts them.
SDK example
Section titled “SDK example”import { ChorusClient, isCommittedMutationAcknowledgement,} from "@chorus-protocol/sdk";
const client = new ChorusClient({ url: process.env.CHORUS_URL!, apiKey: process.env.CHORUS_API_KEY!,});
const health = await client.admin.objectStorageHealth();const page = await client.admin.objectStorageOperations({ states: ["dead_letter"], limit: 50,});
const operation = page.operations[0];if (operation) { // Retry only after an operator has reviewed and selected this operation. const result = await client.admin.retryObjectStorageCleanup(operation.id); if (isCommittedMutationAcknowledgement(result)) { // The mutation committed. Reconcile by the returned resource/request identity; do not retry it. console.log(result); } else { console.log(result.action, result.operation.state, result.accounting_retained); }}
console.log(health.global_unresolved, page.cursor, page.has_more);CLI example
Section titled “CLI example”chorus admin object-storage health --jsonchorus admin object-storage list --states dead_letter --limit 50 --jsonchorus admin object-storage retry-cleanup object_storage_operation:0123456789abcdef0123456789abcdef --jsonUse the returned cursor to request the next page:
chorus admin object-storage list \ --states dead_letter \ --after object_storage_operation:0123456789abcdef0123456789abcdef \ --limit 50 \ --jsonMCP inputs
Section titled “MCP inputs”The embedded and standalone MCP tools take the same logical inputs; only their names differ.
{ "states": ["dead_letter"], "limit": 50}Retry input:
{ "id": "object_storage_operation:0123456789abcdef0123456789abcdef"}Raw HTTP and JSON-RPC
Section titled “Raw HTTP and JSON-RPC”REST list filters are query parameters and retry has an empty request body:
curl --fail-with-body \ -H "Authorization: Bearer $CHORUS_API_KEY" \ "$CHORUS_URL/admin/object-storage/operations?states=dead_letter&limit=50"
curl --fail-with-body -X POST \ -H "Authorization: Bearer $CHORUS_API_KEY" \ "$CHORUS_URL/admin/object-storage/operations/object_storage_operation:0123456789abcdef0123456789abcdef/retry-cleanup"The equivalent raw RPC call uses the canonical command ID:
{ "jsonrpc": "2.0", "id": "object-storage-health-1", "method": "admin.object_storage.health", "params": {}}For a list page, use method admin.object_storage.list with
{"states":["dead_letter"],"limit":50}. For a reviewed retry, use method
admin.object_storage.retry_cleanup with
{"id":"object_storage_operation:0123456789abcdef0123456789abcdef"}.
Avoid obsolete commands
Section titled “Avoid obsolete commands”- Foundation signal emission is aligned across the catalog, standalone MCP, and CLI:
pulse,sense,query,alert,artifact,approval_request,proposal, andshiftare accepted.taskemission was removed; create work with the native task API,chorus_task_create, orchorus tasks create. chorus statusreads the current flat stats response; the historical nested-stats caveat no longer applies.- Chorus does not implement a
chorus auth codexOAuth flow. Authenticate the Codex host with its officialcodex logincommand, then configure Chorus separately withchorus login --api-keyor an MCP Bearer header.
Related references
Section titled “Related references”- Object-storage reconciliation — operating model, retention, inventory, and recovery semantics
- SDK — typed client construction and response handling
- CLI — profiles and command-line behavior
- JSON-RPC — raw RPC envelope and error format
- Generated MCP tool manifest — exact standalone local/stdio names