Skip to content

Latest commit

 

History

History
232 lines (182 loc) · 10.1 KB

File metadata and controls

232 lines (182 loc) · 10.1 KB

API Overview

The default base URL is http://localhost:9889.

This page maps the public API by family and gives representative requests. When cao-server is running, its generated FastAPI OpenAPI schema and schema UI are the exhaustive contract for individual HTTP operations. OpenAPI does not describe WebSocket behavior; the PTY WebSocket contract is documented below.

Representative HTTP usage

curl http://localhost:9889/health
curl http://localhost:9889/sessions
curl http://localhost:9889/agents/providers

HTTP errors use standard status codes and generally return a JSON detail field. Authentication and network behavior depend on server configuration; see Configuration and Security.

HTTP route families

Health and auth discovery

  • GET /health reports service health.
  • GET /.well-known/oauth-protected-resource publishes OAuth protected resource metadata when applicable.

Events and AG-UI

  • /events and /events/history expose server events.
  • /agui/v1/stream and /agui/v1/emit_ui provide the AG-UI stream and generative UI input.

See AG-UI for enablement, event shapes, and privacy boundaries.

Profiles, providers, and settings

  • GET /agents/profiles and GET /agents/profiles/{name} list and inspect installed profiles.
  • GET /agents/profiles/search ranks installed, loadable profiles by capability using the same service as cao profile find.
  • GET /agents/profiles/templates lists public template metadata (name and description only); internal template filesystem paths are never returned.
  • GET /agents/profiles/templates/{category}/{name}/schema returns a template's JSON-Schema.
  • POST /agents/profiles/templates/validate validates a config object against a template's JSON-Schema without writing a profile.
  • POST /agents/profiles/templates/preview validates and renders a template to Markdown without writing a profile.
  • POST /agents/profiles/validate validates a finished profile's frontmatter against the profile JSON-Schema plus CAO conventions, without writing anything. This is the HTTP equivalent of cao profile validate, and is distinct from templates/validate, which checks a template config against that template's own schema. Findings are severity-tagged (error or warning); only errors clear the valid flag, so warnings are advisory.
  • GET /agents/profiles/schema returns the agent profile JSON-Schema, so a client can render create and edit forms from the server's definition instead of duplicating the field list.
  • POST /agents/profiles/install installs a profile.
  • Template validation and preview require the selected template to include a schema.json file.
  • /agents/providers reports provider availability.
  • /settings/* exposes supported agent-directory, skill-directory, and memory settings.

See Agent Profiles and Configuration.

Skills

  • /skills/{name} retrieves an installed skill.

See Skills for discovery, installation, and catalog behavior.

Sessions and terminals

  • /sessions* creates, lists, inspects, and deletes sessions.
  • /sessions/{session_name}/terminals* creates and lists session terminals.
  • /terminals/{terminal_id}* inspects terminals, sends input or keys, reads output and working-directory state, exits providers, and deletes terminals.
  • GET /terminals/{terminal_id}/output?mode=full returns the StatusMonitor rolling buffer (most recent state_buffer_max bytes of streamed output — server setting, 32KB by default, see Configuration), not unbounded scrollback. Long sessions are truncated to the tail; use the on-disk terminal log for complete history.
  • Terminal creation accepts use_worktree (bool, default false, issue #100 Phase 1): provisions an isolated git worktree on its own branch instead of sharing working_directory as given, requiring the resolved directory to be inside a git repository. At deletion, the worktree's working-tree contents are always discarded, but the branch is only deleted if it has no unmerged commits — commit and merge/push results before the terminal is deleted if they need to be kept. See the MCP handoff/assign tool descriptions for the full behavior.
  • POST /sessions accepts optional group/metadata at creation, opting a session's initial terminal into peer discovery (a mid-session worker uses PATCH /terminals/{terminal_id}/group/metadata instead — see below). group is an ordered, general-to-specific array (e.g. ["tenant_1", "project_5"]); metadata is a free-form JSON object the running agent updates via the update_metadata MCP tool. Both PATCH endpoints are whole-value replace, not merge, last-write-wins under concurrent calls, and reject an omitted field with 422 (an explicit null/[]/{} clears the value; omitting it does not).
  • GET /terminals/{terminal_id}/siblings lists other terminals sharing a leading prefix of terminal_id's own group, optionally narrowed by depth; a caller can never see a wider scope than its own group, and a terminal with no group set finds no siblings. Session-scoped by default — results are also filtered to the caller's own tmux session unless the explicit cross_session=true opt-in is passed. Sibling metadata is agent-authored, untrusted content — same trust domain as an inbound send_message body. The list_siblings/update_metadata MCP tools also require the discovery entry in allowedTools — a separate opt-in from orchestration tools, not bundled into @cao-mcp-server — see Tool Restrictions and Discovery Tool Coexistence.

group is an organizational label, not a security boundary. On a default install with auth disabled, a worker already has local shell access to this API, so group/discovery/session-scoping provide no tenant isolation or access-control guarantee even used together — do not build a security boundary on top of them.

Terminal identifiers used in these routes are eight-character hexadecimal strings. See Control Planes for operator-facing choices.

Inbox

  • /terminals/{terminal_id}/inbox/messages sends and reads terminal inbox messages.

Agents normally use the in-session supervisor protocols rather than calling these routes directly.

Workflows

  • /workflows* validates and inspects workflow specifications.
  • POST /workflows/runs starts a run inline and holds the connection until it finishes, returning the complete result.
  • POST /workflows/runs:submit starts a run asynchronously: it returns 202 with {run_id, state, links} as soon as the run is durably journaled, then drives the run in the background. The links map always carries self/status/result/cancel; events appears only on a build that serves the events route, so treat it as optional.
  • GET /workflows/runs lists journaled runs newest-first (?state=, ?limit=).
  • GET /workflows/runs/{run_id} returns a point-in-time status snapshot.
  • GET /workflows/runs/{run_id}/result returns the complete retained result. It is assembled from the journal, so it answers for a detached, in-flight, or post-restart run — not only a finished one. No run-level output field is returned (run-level output is not journaled); per-step outputs are on steps[].output.
  • POST /workflows/runs/{run_id}/cancel cooperatively cancels a run; POST /workflows/runs/{run_id}/resume re-drives a crashed/failed one.

See Workflows.

Memory and graph

  • /settings/memory reports memory enablement (including learning_enabled).
  • /memory* lists, reads, exports, and deletes memories.
  • /memory/relationships* lists, creates, patches, promotes, rejects, and soft-deletes typed relationships between memories. GET is read-scoped and capped by limit (default 50, max 100); the mutating routes are write-scoped. DELETE is a soft-delete — the row is retained with status=deleted.
  • /graph/{provider}* projects and exports graph views.
  • /outcomes records (POST, write-scope) and lists (GET) workflow outcomes for the self-learning loop. Both return 404 while memory.learning_enabled is false.

See Memory, Self-Learning, and Knowledge Graph Viewing.

Flows

  • /flows* creates, lists, reads, deletes, enables, disables, and runs scheduled flows.

See Flows.

PTY WebSocket

Connect to:

/terminals/{terminal_id}/ws

The path must identify an existing terminal. This endpoint is unauthenticated and grants full read/write access to that terminal's PTY.

Client access boundary

By default, only loopback clients identified as 127.0.0.1, ::1, or localhost are allowed. CAO_WS_ALLOWED_CLIENTS adds comma-separated client IP addresses or hostnames to that allowlist. A literal * disables the client-IP restriction.

Adding clients or using * gives those clients full PTY read/write access. Treat either change as a security-boundary change and do not expose the endpoint to untrusted networks. See the network configuration for related server settings.

Frames and messages

The server sends binary WebSocket frames containing raw PTY bytes.

Clients send JSON in text frames:

{"type":"input","data":"ls -la\n"}

The input message writes the UTF-8 string in data to the PTY.

{"type":"resize","rows":24,"cols":80}

The resize message changes the PTY dimensions. Missing values default to 24 rows and 80 columns.

Close outcomes

  • 4003: the client is restricted, or terminal/backend target metadata is invalid.
  • 4004: the terminal does not exist, or the backend cannot attach to it.
  • A normal viewer disconnect detaches that viewer and preserves the session.

Malformed JSON, missing input data, unsupported message types, and other forwarding errors do not currently have a documented stable application close code.