Skip to content
ochat
Search documentation

Use quotes for an exact phrase.

Search by topic, command, or code identifier.

    GitHub ↗

    Agent protocol

    Initialize a client and understand methods, scopes, acknowledgements, events, and replay.

    View Markdown source ↗

    Use the same method/envelope contract over Unix, stdio, or HTTP. Transport framing and authentication differ; session semantics do not. This is JSON-RPC-style Ochat protocol, not an MCP endpoint.

    Send this complete request before other work:

    {"jsonrpc":"2.0","id":"initialize","method":"protocol.initialize","params":{"implementation":{"name":"tutorial","version":"1"},"protocol_min":{"major":1,"minor":0},"protocol_max":{"major":1,"minor":0},"features":[],"event_encodings":["json"],"max_inbound_event_bytes":16777216}}

    The response identifies the negotiated protocol, server/features/limits. Reject an unsupported version; do not silently assume a future version is compatible. Request IDs may be strings or numbers and are returned exactly. Notifications have no request ID. Response envelopes contain result or error; notifications use method and params. The validated discovery stream shows complete requests. List methods require a positive limit even when other filters are absent. Server limits may be narrower than the codec’s encoded range.

    The generated type reference includes every public request, result, event, nested content shape, enum, error and scope, with links to the actual JSON encoders/decoders. It is regenerated from public interfaces by the documentation check. OCaml option denotes optional data, not permission to add unknown wire fields; enum/tag encoding is defined by the linked codec.

    All methods below use the corresponding Command variant and Method_result variant of the same name in the type reference. Request type names identify the complete field schema there. All mutations require applicable actor state and authorization, not merely passing JSON validation.

    MethodRequest typeMinimum method scopeResult / behavior
    protocol.initializeInitialize.RequestAuthentication onlyNegotiate protocol; must precede other methods.
    protocol.pingPing.RequestAuthentication onlyPing response; not proof of a model completing work.
    server.infoEmpty objectAuthentication onlyImplementation/version/features/transports/limits and unsafe-development-auth indicator.
    server.healthHealth.RequestAuthentication only; details scopedCurrent health projection.
    prompt.listPrompt.List_requestprompt.listPaged catalog.
    prompt.getPrompt.Get_requestprompt.listPrompt definition/revision projection.
    workspace.listWorkspace.List_requestworkspace.listPaged catalog.
    workspace.getWorkspace.Get_requestworkspace.listWorkspace projection.
    blob.readBlob.Read_requestsession.transcript.read plus blob ownershipBounded chunk with cursor and metadata.
    session.createSession.Create_requestsession.create plus requested attachment scopesSession, mutation acknowledgement and optional attachment/replay.
    session.listSession.List_requestsession.transcript.readPaged visible sessions with filters.
    session.getSession.Get_requestsession.transcript.readScoped snapshot; optional history window.
    session.attachSession.Attach_requestsession.transcript.read plus requested modeAttachment, replay decision, sequence and optional reclaim token.
    session.detachSession.Detach_requestsession.transcript.readDetach supplied attachment; idempotent mutation acknowledgement.
    session.renew_ownerSession.Renew_owner_requestsession.transcript.read plus valid owner leaseRenew matching generation; owner lease and mutation result.
    session.startSession.Start_requestsession.message.sendWritable attachment; start or queue if permitted.
    session.stopSession.Stop_requestsession.stopWritable attachment; graceful/cancel stop.
    session.cancel_operationSession.Cancel_operation_requestsession.message.sendWritable attachment; target current operation ID.
    session.send_messageSession.Send_message_requestsession.message.sendWritable attachment; history ID, started/deferred disposition and optional operation ID.
    session.compactSession.Compact_requestsession.message.sendWritable attachment; optional expected revision; starts compaction.
    session.delete_historySession.Delete_history_requestsession.message.sendWritable attachment; required expected revision; remove a canonical occurrence and matching tool pair while idle/stopped.
    session.exportSession.Export_requestsession.transcript.readAuthorized attachment; format/revision/window, principal-bound blob.
    session.resetSession.Reset_requestsession.ownWritable attachment; required expected revision and explicit preservation flags.
    session.rebuildSession.Rebuild_requestsession.ownWritable attachment; expected revision, pinned/current-catalog choice.
    session.upgrade_promptSession.Upgrade_prompt_requestsession.ownWritable attachment; expected revision, target revision, migration flag.
    session.deleteSession.Delete_requestsession.deleteWritable attachment; expected revision, archive/remove policy; confirmation equals session ID.
    permission.listPermission.List_requestsecurity.readPaged permission state.
    permission.respondPermission.Respond_requestpermission.respondWritable attachment; offered decision, identity and compare-and-set checks.
    grant.listGrant.List_requestgrant.managePaged grant state.
    grant.revokeGrant.Revoke_requestgrant.manageWritable attachment; revoke matching grant.
    audit.readAudit.Read_requestaudit.readRedacted audit records; not executable replay.
    job.listJob.List_requestsession.message.sendPaged jobs; no generic external job-create method.
    job.getJob.Get_requestsession.message.sendJob state/delivery projection.
    job.cancelJob.Cancel_requestsession.message.sendWritable attachment checked inside actor; cancel job.
    schedule.listSchedule.List_requestsession.message.sendPaged schedules.
    schedule.getSchedule.Get_requestsession.message.sendSchedule state.
    schedule.createSchedule.Create_requestsession.message.sendWritable attachment; persist timer/delivery intent.
    schedule.cancelSchedule.Cancel_requestsession.message.sendWritable attachment; cancel schedule.

    Read-only attachments cannot mutate or answer permissions even with a powerful credential. Read scopes are not stripped by read-only mode. Additional session, blob, owner-lease and revision checks still apply beyond this minimum-scope table.

    Obtain catalog IDs from prompt.list/workspace.list, not by converting friendly configuration names yourself. Session.Spec chooses host, prompt reference, workspace request, liveness, persistence, start intent, optional profile/display name and labels. Daemon sessions select configured catalogs; local-path host options belong to embedded execution, not arbitrary remote filesystem access.

    Create can return an attachment; otherwise attach explicitly. Keep session, attachment, operation, history, permission and blob IDs distinct. Never use IDs as paths. An attach response can report current state, replayed durable events or a snapshot. Apply it before treating live notifications as an initialized view.

    Message content supports plain text or ChatMD plus blob attachments. Validate content parts, tool-output/image encodings and size constraints against the history/blob codecs. Untrusted tool result text is data, not a protocol command.

    ChatMD message admission converts the first <user> element (including its inline helpers), rather than appending arbitrary transcript roles or tool-call records. Text not starting with < is wrapped in a user element; missing-user or parse failures are returned as errors. Root prompt declarations still come from the configured, pinned source, not from a client message.

    session.delete_history requires session_id, attachment_id, history_id, nonnegative expected_revision, and idempotency_key. Obtain the stable history ID from a current snapshot, not a row index or provider item ID. It rejects stale revisions, read-only attachments, active operations and borrowed idle moderator execution. The result is a Session_mutation; committed history.replaced events update subscribers. It removes the nearest matching function/custom call-result pair without crossing another same-direction occurrence with the same call ID. It neither executes nor reverses tools.

    Snapshot.archived_revisions lists pre-change archive revisions from compaction, reset, rebuild and prompt upgrade, newest first (older peers may omit it; the decoder defaults to an empty list). session.export.revision may be absent/current or one of those archived revisions, not an arbitrary old journal revision. Historical export uses the current principal projection and blob authorization. Missing/corrupt archive files fail instead of falling back to current history. See history and archives.

    Administrative methods carry explicit expected revisions where specified. session.reset preservation flags are independent; inspect the current snapshot before choosing them. session.rebuild is not an alias for restart. Session deletion requires confirmation exactly equal to the session ID and can remove data; prefer archive when recovery is needed. See operations.

    Errors carry a typed code, message, retryable flag and data. The complete code set is in Protocol_error in the type reference. Typical classes: invalid request/method/version, authentication/permission denial, unknown IDs, attachment/lease conflicts, stale revision, capacity/resource limit, snapshot required, persistence failure and server draining. Treat retryable as guidance, not permission to retry a changed or irreversible operation blindly.

    For methods with idempotency_key, generate a new key for each new mutation and retain it until the outcome is resolved. Retry the same payload/key after an uncertain reply. A different payload under the same key is a conflict. The store uses a fixed one-day expiry for Standard receipts; maintenance prunes them after expiry. Protected receipts (including message submission, compaction, history deletion, reset/rebuild/upgrade, session deletion and job/schedule mutations) do not expire through that pruning. This is not a configurable retention interval or an exactly-once external-execution guarantee. Keys are nonempty, up to 256 characters, using alphanumeric characters or -_.:/. Revision preconditions and idempotency solve different problems. Acknowledgement is not terminal model/tool completion, and durability depends on selected flush mode. No exactly-once external side-effect guarantee.

    session.event carries a durable event with session ID, sequence, revision, timestamp, kind, visibility and payload. session.live_event carries recoverable operation-scoped data with operation sequence and durable anchor. Do not advance the durable cursor with an operation sequence.

    Durable families include session creation/state/update/error; owner changes; deferred/appended/replaced history; moderator overlays/notices; requested/resolved permissions; created/revoked grants; started/completed/failed/cancelled/interrupted operations; job transitions; schedule creation/transitions/cancellation; prompt upgrade; workspace state. Recoverable families include provider/sourced/history- correlated streams, tool start/progress/trace/finish, agent classification/progress, activity and compaction progress. Exact payload shapes are in Event.

    Client synchronization:

    1. Initialize and establish an attachment/projection.
    2. Apply snapshot or bounded replay in sequence, then process notifications.
    3. Track stable history and operation IDs; preserve local drafts separately.
    4. Redacted/hidden durable events still advance sequence. Do not infer missing protected data by treating hidden payloads as deserialization failures.
    5. Protocol 1.0 does not expose replay of recoverable deltas. They are live-only notifications; their operation sequence is not an accepted reconnect cursor. Recover through durable replay or a replacement snapshot, then resume live notifications. Finalized canonical state remains authoritative.
    6. On replay loss, replace from a scoped snapshot, including active-call summaries; do not append duplicate rows or preserve a terminal stale loading indicator.
    7. On reconnect, re-establish identity/connection/attachment as required, then replay after the last durable position or request replacement.

    Transcript-only principals receive finalized text/redacted tool placeholders. Recoverable streams and tool/permission summaries require security.read, grants require grant.manage, jobs/schedules require session.message.send. Export and snapshot caching use the same principal projection; no unscoped cache reuse.

    History entry role is a coarse protocol classification: both system and developer input messages have outer role: "system". The exact role remains in payload.role ("developer" for developer instructions). Model reconstruction uses the payload, not the coarse classification; this does not convert developer instructions into system messages. ChatML Item.role also reports the exact role.

    List requests carry limit and optional cursor, plus method-specific filters. Signed cursors bind identity/scopes, query, collection and host; changing any may invalidate them. Restart the listing on invalid_request rather than editing a cursor. History windows support bounded before/after/tail/cursor selectors and canonical/effective views. Partial windows advertise structural incompleteness; complete them before using them as model context.

    All types and generated inventories are refreshed with @agent-docs-check; see testing. The wire implementations remain authoritative for exact encoding and validation.