Connect Claude Code
The ctrlb-agent plugin does three things in Claude Code:
- It uploads every session, including subagents, to the session store. Each message, thinking block, tool call and tool result is one row. Text that looks like a secret is replaced with
[REDACTED]before upload. - It adds the CtrlB Model Context Protocol (MCP) server. The agent gets the session tools (
search_sessions,find_command,next_actions,fetch_records) and the relay tools (peers,post,claim,release). - At session start it tells the agent its run id and agent id. Before each
Edit,Write,MultiEditorNotebookEdit, it checks the file against the run's claims.
Everything goes to CtrlB with your MCP key. The hooks are standard library Python 3.9 or newer. Nothing else is installed.
1. Generate your MCP key
- In CtrlB, open AI Observability in the sidebar and choose Connect.
- Under Your MCP key, click Generate key. Rotate key replaces an existing key.
- Choose the Claude Code tab under Connect an agent. The blocks show your CtrlB URL and
<your key>. Copy command fills your key into what you copy.
The key acts as you, with your roles and dataset grants.
2. Set the environment
Add these lines to your shell profile (~/.zshrc or ~/.bashrc) and open a new terminal:
export CTRLB_URL="<your CtrlB URL>"
export CTRLB_MCP_URL="<your CtrlB URL>/mcp"
export CTRLB_KEY="<your key>"
CTRLB_URLandCTRLB_KEYare what the hooks use to upload rows and check edits.CTRLB_MCP_URLis the MCP server's address. Claude Code expands it, and the key, in the plugin's.mcp.jsonwhen it starts.
3. Install the plugin
claude plugin marketplace add ctrlb-hq/ctrlb-agent
claude plugin install ctrlb-agent@ctrlb-agent
The first command adds the marketplace from the ctrlb-hq/ctrlb-agent repository. The second installs the plugin for your user.
Without the marketplace
If you cannot add a marketplace, load the plugin from a clone for each session:
git clone https://github.com/ctrlb-hq/ctrlb-agent.git ~/ctrlb-agent
claude --plugin-dir ~/ctrlb-agent/plugin
--plugin-dir loads the plugin for that session only. Pass it every time, or put it in a shell alias.
4. Verify
- Start Claude Code and run
/ctrlb-agent:setup. It checks the connection, shows the user your key carries, and offers to upload your past sessions. - Ask the agent anything, so the session has at least one turn. Rows are uploaded at the end of each turn.
- In CtrlB, open AI Observability, then Runs. The session appears as a run. Click it, then click the agent's name to read its transcript.
If nothing appears, read ~/.ctrlb/hooks.log.
Runs and agents
A session is its own run, and its subagents join it. To put several sessions in one run, give them the same CTRLB_RUN:
CTRLB_RUN=nightly-refactor-1 claude -p "Fix the failing tests in src/parser"
- The agent id is the session id. Set
CTRLB_AGENTto use a label instead, for exampleCTRLB_AGENT=builder-1. - A subagent's id is
agent-<id>, or<label>:agent-<id>when a label is set. /ctrlb-agent:relay <run id>has the agent pass that run id in its relay calls and loads the agent rules from Relay tools. The session's rows and edit checks stay on its own run; useCTRLB_RUNto put the whole session in a run.user_nameon every row is the user your key belongs to.CTRLB_USERis still read for compatibility, as the agent label whenCTRLB_AGENTis unset. It never setsuser_name.
Edit checks
Before an edit, a PreToolUse hook sends the file path, relative to the session's working directory, to CtrlB. The workspace's enforce mode decides the answer:
| Enforce mode | When another agent in the run holds the file |
|---|---|
off | Nothing happens. |
advisory (default) | The agent gets a note naming the holder and the claim call to make. The edit goes ahead. |
enforce | The edit is refused. The reason names the holder and the claim call to make. |
The check gives up after two seconds. If CtrlB does not answer, the edit goes ahead and the error is written to ~/.ctrlb/hooks.log. A file the agent holds itself is never a conflict. CTRLB_ENFORCE=off skips the check on one machine. See Limits for what the check does not cover.
Keep the key out of your profile
Clone the repository and run the configure step yourself, in a terminal, not through an agent:
git clone https://github.com/ctrlb-hq/ctrlb-agent.git ~/ctrlb-agent
python3 -I ~/ctrlb-agent/bin/configure.py
It asks for the URL, the sessions dataset, an optional run id, and the key. The key prompt hides what you type. It writes ~/.ctrlb/config.json with mode 0600 and checks that CtrlB answers. The hooks read that file when CTRLB_URL or CTRLB_KEY is not set. The MCP server still reads CTRLB_MCP_URL and CTRLB_KEY from the environment, because Claude Code expands them in .mcp.json.
Configuration
| Variable | Meaning |
|---|---|
CTRLB_URL | Your CtrlB URL |
CTRLB_KEY | Your MCP key |
CTRLB_MCP_URL | Your CtrlB URL followed by /mcp |
CTRLB_RUN | Run id for every session started with it (default: each session is its own run) |
CTRLB_AGENT | Agent label (default: the session id) |
CTRLB_DATASET | Sessions dataset (default agent_sessions) |
CTRLB_ENFORCE | off skips the edit check on this machine |
CTRLB_OFF | 1 turns every hook off |
CTRLB_HOME | Where the config, log and upload state live (default ~/.ctrlb) |
Environment variables win over ~/.ctrlb/config.json.
Turn off or remove
- Off for one session:
CTRLB_OFF=1 claude. - Status: run
/ctrlb-agent:setupin Claude Code. - Log:
~/.ctrlb/hooks.log. - Remove:
claude plugin uninstall ctrlb-agent@ctrlb-agent, then delete~/.ctrlb. Rows already in CtrlB stay there.