Skip to main content
Glama

t3-mcp

Let any agent spawn and manage T3 Code agents over MCP.

t3-mcp is a small HTTP Model Context Protocol server that drives a T3 Code instance on behalf of another agent. Your orchestrator, whether that's Claude Code, a custom agent or a cron job, can then:

  • start research or coding agents as T3 threads;

  • send them follow-ups;

  • wait for their results;

  • answer their approval prompts.

All of this goes through 15 MCP tools. Every thread also shows up in the T3 app, where you can watch it or take over.

your agent ──HTTP MCP──▶ t3-mcp ──WebSocket RPC──▶ T3 Code ──▶ Claude / Codex / … agents
            Bearer token          paired session
  • Pair once, like any other T3 device. Paste a pairing link from T3 → Settings → Connections. No patches to T3 and no access to its database.

  • Research agents in one call. create_thread with just a prompt starts an agent in a fresh Scratch folder. create_threads starts up to 20 at once.

  • Waiting and approvals built in. wait_for_thread returns when the agent finishes or needs input, and respond_to_request answers approvals and questions.

  • Safe to retry. A clientRequestId maps to deterministic T3 ids, so a lost response never creates duplicate agents.

  • Small and boring. Node, three runtime dependencies (@modelcontextprotocol/sdk, ws, zod) and a hand-written client for T3's WebSocket protocol.

IMPORTANT

t3-mcp targetsT3 Code Nightly (orchestration protocol 2). It uses the same internal protocol as T3's own apps, which can change between Nightly builds. The bridge refuses to connect to a server that reports a different protocol version. Run npm run smoke after T3 updates.

Quick start

You need Node ≥ 22.18 and a T3 Code (Nightly) instance the bridge can reach.

1. Make T3 reachable. For a bridge on another machine:

  • Option A: in T3 open Settings → Connections and enable Network access.

  • Option B: enable Tailscale HTTPS, which is recommended because it gives you TLS.

A bridge on the same machine can use 127.0.0.1.

2. Serve.

npx t3-mcp serve

On first start, t3-mcp generates the bearer token MCP clients must send and saves it next to its other state. It then prints the endpoint and a command to connect Claude Code:

t3-mcp 0.1.2 is serving MCP at http://127.0.0.1:8787/mcp
  Bearer token: generated and saved to ~/.local/state/t3-mcp/mcp-bearer-token (print it with `npx t3-mcp token`)

  Add it to Claude Code (run this from the same folder):
    claude mcp add --transport http t3 http://127.0.0.1:8787/mcp --header "Authorization: Bearer $(npx t3-mcp token)"

  Not paired with T3 Code yet.
  Create a pairing link in T3 → Settings → Connections, then run:
    npx t3-mcp pair '<link>'
  in another terminal. This server picks it up without a restart.

3. Pair. In T3, create a pairing link under Settings → Connections. It needs the orchestration:read and orchestration:operate scopes. Within 5 minutes, in another terminal in the same folder, run:

npx t3-mcp pair 'http://192.168.1.10:3773/pair#token=XXXXXXXXXXXX'

The running server switches to the new pairing within a few seconds. Use the same command whenever you need a new pairing, for example when the 30-day pairing expires: no restart needed. Quote the link, because it contains # and sometimes ?.

You can also pair at startup with npx t3-mcp serve '<link>' or T3_PAIRING_URL, or let your agent call the t3_pair tool.

4. Connect your agent. Run the claude mcp add command that serve printed. If the server is behind a TLS proxy, use its public URL instead:

claude mcp add --transport http t3 https://t3-mcp.example.com/mcp \
  --header "Authorization: Bearer $(npx t3-mcp token)"

Then ask it something like: "Spin up three research agents in T3 — one each on X, Y and Z — wait for them, and summarize what they found."

Settings come from environment variables or a .env file in the folder you run t3-mcp from; see Configuration. Running pair, token and serve from the same folder makes sure they share the same state. To run from source instead of npm, clone the repository, run npm ci && npm run build, and use node dist/cli.js wherever these steps say npx t3-mcp.

Related MCP server: subturn

Tools

Tool

What it does

t3_status

Pairing/connection state, environment, token expiry (needsPairing, daysLeft)

t3_pair

Pair with a pairing URL (or a bare code plus baseUrl)

list_providers

Provider instances (Claude, Codex, …), availability, model slugs, default model

list_projects

Projects with thread counts

add_project

Register a folder on the T3 host as a project

create_thread

Start an agent with an optional first prompt. Defaults to a fresh Scratch folder; choose project, provider, model, runtimeMode, interactionMode (plan), or a worktree; optional wait

create_threads

Up to 20 threads in one call; errors reported per entry

list_threads

Filter by project, status (active / idle / needs_input / failed), title

read_thread

Timeline as messages or full activity (tools, commands, file changes); incremental with afterPosition

send_message

Follow-up with auto, queue, steer or restart delivery

wait_for_thread

Block until the run finishes or needs input (≤ 10 min; never cancels work)

interrupt_thread

Stop the active run

list_pending_requests

Approvals and questions agents are waiting on

respond_to_request

Answer an approval or question, or dismiss a question

archive_thread

Archive or unarchive

Failed tool calls return JSON with an error code, for example needs_pairing, thread_not_found, model_unavailable or runtime_mode_escalation_denied, plus a message written for the calling agent.

Configuration

Every setting can be given as a command-line flag, an environment variable, or a line in ./.env in the working directory. Flags win over environment variables, which win over ./.env. .env.example lists all the variables.

Flag

Variable

Default

Description

--host

MCP_HOST

127.0.0.1

Address to listen on; 0.0.0.0 for all interfaces

-p, --port

MCP_PORT

8787

Port to listen on

--path

MCP_PATH

/mcp

URL path of the MCP endpoint

--pair, or a link argument

T3_PAIRING_URL

—

Pair at startup. The flag always pairs; the variable is used only when no valid pairing is stored

--state-dir

T3_STATE_DIR

~/.local/state/t3-mcp

Where the T3 pairing and the generated bearer token are stored (mode 0600). pair, status, token and unpair must use the same one as serve

--max-mode

T3_MAX_RUNTIME_MODE

full-access

Highest permission level threads may be created with

--default-mode

T3_DEFAULT_RUNTIME_MODE

same as the ceiling

Permission level threads start with

--model

T3_DEFAULT_MODEL

T3's default

<providerInstanceId>:<model>, e.g. claudeAgent:claude-opus-5-5

--label

T3_CLIENT_LABEL

t3-mcp (<hostname>)

Name shown for this client in T3 → Connections

--log-level

LOG_LEVEL

info

debug / info / warn / error. Logs go to stderr: readable lines in a terminal, JSON lines otherwise (e.g. under systemd)

—

MCP_BEARER_TOKEN

generated

Token MCP clients must send; ≥ 32 characters. When unset, serve generates one, stores it in the state dir and t3-mcp token prints it. There is no flag, because command lines are visible to other users and end up in shell history

Runtime modes, from narrowest to broadest: approval-required < auto-accept-edits < auto < full-access. If --max-mode is below a default set in the environment or .env, the default is lowered to match, with a warning.

CLI

t3-mcp [serve] [<link>] [options]   start the MCP server (the default command)
t3-mcp pair <link>                  pair, or replace the pairing; a running serve switches over within seconds
t3-mcp status [--json]              show the pairing and test the connection
t3-mcp token                        print the bearer token MCP clients must send
t3-mcp unpair                       forget the pairing; a running serve disconnects

t3-mcp --help lists every option. Some examples:

npx t3-mcp --port 9000                            # another port
npx t3-mcp --host 0.0.0.0                         # reachable from other machines (put TLS in front)
npx t3-mcp --max-mode approval-required           # agents stop at every approval
npx t3-mcp --model claudeAgent:claude-opus-5-5    # default model for new threads
npx t3-mcp --state-dir ~/t3-work -p 8788          # a second bridge, e.g. for another T3 instance
npx t3-mcp pair '<link>' --state-dir ~/t3-work    # ...and pairing it

pair also accepts a bare pairing code followed by the T3 server URL: t3-mcp pair ABCD2345EFGH http://192.168.1.10:3773.

Deployment

  • TLS. t3-mcp speaks plain HTTP. Put a TLS proxy in front, such as Caddy, nginx, a Cloudflare Tunnel or tailscale serve.

  • Unauthenticated route. /healthz is the only route that skips the bearer check.

  • Long waits. wait_for_thread can hold a request open for up to 10 minutes. It sends MCP progress notifications about every 30 seconds if the client asked for them. If your proxy closes idle requests sooner, use smaller timeoutMs values and call again.

  • systemd. deploy/t3-mcp.service is a hardened unit.

Pairing lifetime

  • T3 issues a 30-day bearer token at pairing and has no refresh.

    • t3_status reports daysLeft and sets expiringSoon in the last 3 days.

    • After expiry or revocation, tools return needs_pairing until someone provides a fresh link.

  • To renew, create a new link and run t3-mcp pair '<link>' while the server keeps running. The previous session stays listed in T3 → Connections until it expires; you can remove it there.

  • To revoke the bridge, remove its session in T3 under Settings → Connections.

Security

A bearer token for this server lets someone run agents on your T3 host. With the default full-access ceiling, that includes running arbitrary commands as the user T3 runs as. Treat the bearer token like an SSH key, whether it is MCP_BEARER_TOKEN or the generated $T3_STATE_DIR/mcp-bearer-token.

  • Lower the ceiling if you can. When you don't need full access, pass a narrower --max-mode (or set T3_MAX_RUNTIME_MODE). With approval-required, agents stop at every approval, which the orchestrator (or you, in T3) answers.

  • Pair over HTTPS where possible, using Tailscale HTTPS or another TLS route. Over a plain HTTP LAN route, the pairing code and session token cross the network unencrypted.

  • To rotate a generated bearer token, delete $T3_STATE_DIR/mcp-bearer-token and restart serve. Then update your MCP clients.

  • The T3 credential is stored on the bridge host in $T3_STATE_DIR/t3-credential.json with mode 0600. The bridge only requests the orchestration:read and orchestration:operate scopes, with no terminal or access-management rights.

  • Paths in tool arguments (add_project, existing_worktree) refer to the T3 host's filesystem.

Development

npm ci
npm test            # unit tests + end-to-end tests against an in-process fake T3 server
npm run typecheck
npm run dev         # serve from source
npm run smoke -- [--pair '<url>'] [--provider claudeAgent --model claude-haiku-4-5] [--keep]

npm run smoke runs against a real T3 instance. It creates a Scratch thread, waits for it, sends a follow-up and then archives the thread.

The repository ships a t3.json, so working on t3-mcp in T3 Code is set up for you:

  • new threads start in their own git worktree;

  • scripts/setup-worktree.ts installs dependencies and links your main checkout's .env before the agent starts;

  • Test, Typecheck, Build, Serve and Smoke actions appear in the scripts menu.

Releasing

There are no manual releases. Every merge to main is published to npm under the latest tag by .github/workflows/release.yml, after the typecheck and tests pass.

  • Versions take major.minor from package.json; the patch number is the commit count on main (for example 0.1.42). To start a new line, change package.json to 0.2.0 or 1.0.0 in a PR.

  • Never backwards. A run whose version is not newer than npm's current latest (for example a re-run of an old run) publishes nothing.

  • Pull requests run the same pipeline with npm publish --dry-run, so packaging problems show up before merging.

  • No npm token is stored anywhere: the workflow uses npm trusted publishing, and each version carries a provenance attestation linking it to the commit it was built from. Only the publish job can obtain publish credentials, and it runs no project or dependency code.

docs/architecture.md covers how pairing, the WebSocket RPC protocol and the tools map onto T3's internals.

License

MIT. t3-mcp is an independent project and is not affiliated with T3 Code or Ping Labs.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers