Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

Agent Teams

Agent Teams let Claude Code spawn teammate agents that work in parallel, each in its own TUICommander terminal tab. Teammates share a task list, communicate directly with each other, and coordinate autonomously.

How It Works

TUICommander automatically injects CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 into every PTY session. This unlocks Claude Code’s TeamCreate, TaskCreate, and SendMessage tools. When Claude Code spawns a teammate, TUICommander creates a new terminal tab via its MCP agent spawn tool — no external dependencies required.

Setup

No configuration needed. Agent Teams is enabled by default for all Claude Code sessions launched from TUICommander.

To verify it’s active, check the environment inside any terminal:

echo $CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS
# Should print: 1

Usage

Tell Claude Code to create a team using natural language:

Create an agent team with 3 teammates to review this PR:
- One focused on security
- One on performance
- One on test coverage

Claude Code handles team creation, task assignment, and coordination. Each teammate appears as a separate tab in TUICommander’s sidebar.

Claude Code supports two display modes for teammates:

ModeHow it worksRequirement
In-processAll teammates run inside the lead’s terminal. Use Shift+Down to cycle between them.None
Split panesEach teammate gets its own pane.tmux or iTerm2

TUICommander works with both modes. In-process mode is the default and requires no extra setup. With split panes, each teammate appears as a separate TUICommander tab.

Key Controls (In-process Mode)

KeyAction
Shift+DownCycle to next teammate
EnterView a teammate’s session
EscapeInterrupt a teammate’s current turn
Ctrl+TToggle the shared task list

What Teams Can Do

  • Shared task list — All teammates see task status and self-claim available work
  • Direct messaging — Teammates message each other without going through the lead
  • Plan approval — Require teammates to plan before implementing; the lead reviews and approves
  • Parallel work — Each teammate has its own context window and works independently

Good Use Cases

  • Code review — Split review criteria across security, performance, and test coverage reviewers
  • Research — Multiple teammates investigate different aspects of a problem simultaneously
  • Competing hypotheses — Teammates test different debugging theories in parallel and challenge each other
  • New features — Each teammate owns a separate module with no file conflicts

Limitations

Agent Teams is an experimental Claude Code feature. Current limitations:

  • No session resumption/resume does not restore in-process teammates
  • One team per session — Clean up before starting a new team
  • No nested teams — Teammates cannot spawn their own teams
  • Token cost — Each teammate is a separate Claude instance; costs scale linearly with team size
  • File conflicts — Two teammates editing the same file leads to overwrites; assign distinct files to each

Troubleshooting

Teammates not appearing as tabs:

  • Verify the env var is set: echo $CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS should print 1
  • Check that TUICommander’s MCP server is running (status bar shows the MCP icon)

Teammates not spawning at all:

  • Claude Code decides whether to create a team based on task complexity. Be explicit: “Create an agent team with N teammates”
  • Check Claude Code version: Agent Teams requires a recent version

Too many permission prompts:

  • Pre-approve common operations in Claude Code’s permission settings before spawning teammates

Inter-Agent Messaging

TUICommander includes a built-in messaging system that lets agents in different terminal tabs communicate directly. This works alongside (and independently from) Claude Code’s native Agent Teams messaging. There is no separate swarm action: callers compose the agent and session primitives documented below.

How It Works

Every PTY session gets a stable TUIC_SESSION UUID injected as an environment variable. Agents use this as their identity to register, discover peers, and exchange messages through TUICommander’s MCP agent tool.

When a channel-enabled Claude Code worker is connected via SSE and already working, messages are pushed in real-time into that turn as MCP channel notifications (notifications/claude/channel). Idle or completed ordinary managed agents use terminal submission to start a real next turn; managed non-Claude workers do the same even when their MCP bridge has an SSE stream. Every message also lands in a buffered inbox.

Once a registered peer spawns a managed child through TUICommander, it is treated as an orchestrator. Peer results and lifecycle payloads stay in its inbox: a working orchestrator is never injected or steered, while an idle/completed orchestrator receives only one coalesced notice that a message is available and should be read with agent action=inbox ([TUIC] message available …). When that notice would cover nothing but child lifecycle events, it prints them instead ([TUIC] child agent 8c261794 is now idle; child agent 8c261794 exited (exit 0)) and no inbox read is needed — a peer message anywhere in the batch sends you back to the generic notice. An active agent wait receives the mail directly and suppresses that notice.

If writing that payload-free notice has an uncertain outcome, TUICommander retries it at most once after five seconds. A second uncertain result exhausts the wake budget for the whole unread-mail group; later and newly coalesced mail stays inbox-only until a successful agent action=inbox or agent action=wait observation clears the group. Later mail then receives a fresh initial wake and one-retry budget.

What Gets Injected Automatically

TUICommander injects these into every Claude Code PTY session — no manual configuration needed:

Variable / FlagValuePurpose
TUIC_SESSIONStable UUID per tabAgent identity for messaging
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS1Unlocks TeamCreate/TaskCreate/SendMessage
--dangerously-load-development-channels server:tuicommander(CLI flag, agent spawn only)Enables real-time channel push from TUICommander

Messaging Flow

Identity is automatic. The bridge asserts your $TUIC_SESSION at connect (x-tuic-session header → server auto-bind), so an agent spawned inside TUICommander is already a registered peer. agent action=register is only needed to set a friendly name/project, or from a standalone/external session where the env-var route is unavailable. External MCP clients do not need a plain-shell identity tab: call agent action=register without tuic_session to receive an MCP-scoped UUID, or supply an explicit UUID when the same identity must be reclaimed after reconnect. Reconnecting under a new UUID? Add replaces="<old-uuid>" or the old inbox is left behind — nothing links the two identities otherwise, and TUIC never guesses one from a name. The reply reports mail_migrated, or mail_stranded with a warning when the old identity still has a live terminal of its own.

Prefer blocking waits over polling. agent action=wait returns as soon as new mail arrives; session action=wait session_id=<id> until=idle|exited blocks on a peer’s lifecycle. Both default to 60 seconds, cap at 300000 ms, and return {met, timed_out}. They are event-driven end to end; the bridge deadline follows the requested wait instead of its ordinary ten-second timeout. A successful agent wait also returns every retained fresh message (up to the 100-message inbox capacity) and a per-recipient logical next_since cursor, so the normal path needs no separate inbox call. Ordinary idle workers receive direct terminal delivery. An idle orchestrator instead receives a payload-free agent action=inbox wake; an active wait suppresses it.

  1. Register (optional — sets name/project) — the agent reads its $TUIC_SESSION:

    agent action=register tuic_session="$TUIC_SESSION" name="worker-1" project="/path/to/repo"
    
  2. Discover peers — Find other agents connected to TUICommander:

    agent action=list_peers
    agent action=list_peers project="/path/to/repo"   # filter by repo
    
  3. Send a message — Address by the recipient’s tuic_session UUID:

    agent action=send to="<recipient-tuic-session>" message="PR review done, 3 issues found"
    
  4. Wait for and receive messages — one blocking call returns the message bodies:

    agent action=wait
    

    Omit since: the server remembers where you got to and resumes from there, so a plain wait never re-reads mail you already saw. Pass it only to override — since=0 deliberately replays the whole inbox. next_since comes back on every response, timeouts included.

  5. Check inbox directly — useful after a reported FIFO eviction or if channel push was missed:

    agent action=inbox
    agent action=inbox limit=10 since=1712000000000
    

agent action=send also returns recipient_state with the recipient’s shell_state and agent_state when the recipient is a managed PTY. External generated peers omit this field.

Automatic lifecycle notifications contain state only (idle, completed, or exited). They do not contain the worker’s result. Every worker reports completed output or a real blocker with agent action=send; use session action=output only to investigate the anomaly where a child did not send that report.

Channel Push vs Inbox

DeliveryWhenLatencyRequires
Channel pushOrdinary Claude worker has an active turn and SSE streamReal-time--dangerously-load-development-channels server:tuicommander on the recipient’s CC process
Orchestrator wakeRegistered parent is idle/completed and not waitingReal-time, coalescedManaged PTY + authoritative lifecycle
Inbox bufferAlwaysPoll-basedRegistration only

Messages are always buffered in the inbox regardless of whether another delivery path succeeds. The inbox holds up to 100 messages per agent (FIFO eviction). Individual messages are capped at 64 KB.

Using Messaging from a Standalone Claude Code Session

If you run Claude Code outside TUICommander but still want to use TUIC messaging:

  1. Connect to TUIC’s MCP server — the MCP channel is a Unix socket (Windows: named pipe), reached through the tuic-bridge stdio adapter, not a TCP port. TUICommander auto-installs this entry into each supported agent’s config; to add it by hand:

    {
      "mcpServers": {
        "tuicommander": {
          "command": "tuic-bridge",
          "args": []
        }
      }
    }
    

    The bridge finds the socket via TUIC_SOCKETmcp.sock → any mcp-*.sock in the config dir.

  2. Register identity — omit the UUID for a generated identity scoped to this MCP connection:

    agent action=register name="external-reviewer" project="/path/to/repo"
    

    Pass tuic_session="<stable-uuid>" instead when a future reconnect must reclaim the same identity. Registration never creates a PTY.

  3. Enable channel push (optional, for real-time delivery):

    claude --dangerously-load-development-channels server:tuicommander
    

Messaging vs Claude Code Native SendMessage

FeatureTUIC MessagingCC Native SendMessage
TransportMCP tool call → server-side routingFile append + polling (~/.claude/teams/)
Real-time pushYes (MCP channel notifications)No (polling only)
Cross-appAny MCP client can participateClaude Code processes only
Discoverylist_peers with project filterTeam config file
PersistenceIn-memory ring buffer (lost on TUIC restart)Files on disk (survives restart)

Both systems work simultaneously. Claude Code agents spawned by TUICommander can use either or both.

Deprecated: it2 Shim

Earlier versions of TUICommander used an it2 shell script shim that emulated iTerm2’s CLI to intercept teammate creation. This approach is deprecated — teammate spawning now uses direct MCP tool calls (agent spawn). The shim at ~/.tuicommander/bin/it2 is no longer needed.