02

The Cast of Characters

Five components, each with a single job. Together they turn one CLI command into a fleet of cooperating agents.

Architecture at a Glance

Five components, three layers. Your commands flow down; agent results flow back up.

C
cao CLI — your terminal. Sends HTTP requests to the server.
S
cao-server

FastAPI on :9889. Sessions, terminals, inbox, SQLite.

M
cao-mcp-server

Agent tools: handoff, assign, send_message, memory.

T
tmux

One window per agent. Output captured via pipe-pane.

E
Event Bus

Pub/sub glue. Drives status detection and message delivery.

📚
Persistent Memory

Agents also have access to a memory system — a persistent store that survives across sessions. Agents call memory_store to save learnings and memory_recall to retrieve them later. Memory is scoped (global, project, session, or per-agent) so knowledge stays organized. Think of it as the team's shared notebook.

Meet Each Component

cao CLI

User interface. Click-based Python CLI with commands like launch, session, profile, shutdown.

src/cli_agent_orchestrator/cli/

cao-server

State manager. FastAPI on port 9889 handling sessions, terminals, inbox, and the SQLite database.

src/cli_agent_orchestrator/api/

cao-mcp-server

Agent toolbox. Exposes handoff, assign, send_message, memory_*, load_skill via FastMCP.

src/cli_agent_orchestrator/mcp_server/

tmux backend

Process isolation. Creates sessions/windows per agent, runs pipe-pane to capture output into FIFOs.

src/cli_agent_orchestrator/clients/tmux.py

Event Bus

Async glue. Pub/sub connecting FifoReader, StatusMonitor, and InboxService without polling.

src/cli_agent_orchestrator/services/event_bus.py

How They Connect

Module 1 showed the high-level steps. Now let's see the same launch at the component level — which piece talks to which, and in what order:

0 / 7 messages

Code: The CLI Entry Point

cli/main.py (abridged) import click from cli_agent_orchestrator.cli.commands.launch import launch from cli_agent_orchestrator.cli.commands.session import session # ... one import per command module @click.group() @click.version_option(__version__, "-V", "--version") def cli(): """CLI Agent Orchestrator.""" cli.add_command(profile) cli.add_command(launch) cli.add_command(session) # ... 17 commands registered in total
Plain English
Import the click library for building CLI commands.
Pull in each command from separate files in the commands/ folder.
Create the top-level cao command group.
Register each subcommand. Adding a new command (like cao deploy) means creating a file in commands/ and adding one add_command line here.
💡
Key Insight

Each command is a separate file in cli/commands/. The main file only wires them together. This means you can add new CLI commands without touching existing ones.