t3-code-agent-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@t3-code-agent-mcpStart a Codex thread to fix the flaky test"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
t3-code-agent-mcp
A small, local MCP server that lets a coding agent (Claude Code, Codex CLI, Cursor, or any MCP client) start and drive threads in your running T3 Code app.
Use it when an agent in one thread needs to kick off more work: "open a Codex thread on this repo with gpt-5.6-sol and ask it to fix the flaky test", then read the reply, send follow-ups, or cancel.
Talks to T3 the same way the T3 web app does: T3's own HTTP + WebSocket interfaces, T3's own pairing tokens. T3 handles each harness's protocol.
Threads show up in the normal T3 UI, with a link back to them.
Never opens or writes T3's database.
Runs over stdio on your machine. No cloud, no extra ports.
Contents
Related MCP server: t3code-mcp
Tools
Tool | What it does |
| Projects the T3 server knows, with ids and workspace roots |
| Git worktrees and local branches of one project |
| Harnesses (Codex, Claude, Cursor, Grok, OpenCode, …) and the models each offers, with a usable flag and reason |
| Recent threads, newest first, optionally per project |
| Create a thread with an explicit project + worktree + harness + model and send the first prompt |
| Send a follow-up prompt to an existing thread |
| Status, latest turn state, and recent messages including the assistant reply |
| Block until the current turn finishes, then return the reply |
| Interrupt the running turn |
Guarantees
No silent substitution. If the harness or model you name is unknown, disabled, not installed, or signed out, the call fails and lists the valid options. Same for projects and worktrees.
No duplicate launches. Pass an
idempotencyKeyand retries reuse the same thread (or the same turn). Command ids are derived from the key, and T3 dedupes on command id, so even a retry after a crash cannot launch twice. If T3 rejected a command, that key is burned: fix the cause and call again with a new key. The error text says so.Loud on drift. The few response fields the wait loop relies on are checked at runtime. If a T3 upgrade renames them, tools fail with a clear message instead of reporting "done".
Requirements
Node.js 20 or newer.
A running T3 Code server on the same machine: the desktop app, or
npx t3.A pairing link from that T3 (Settings → Connections).
Install
git clone https://github.com/gfsaaser24/t3-code-agent-mcp
cd t3-code-agent-mcp
npm install
npm run buildThe server entry point is dist/cli.js.
Pair with T3
One-time step. T3 issues short-lived pairing codes; this server exchanges one for a 30-day bearer token and stores it locally.
In T3 open Settings → Connections and create a pairing link. (CLI users:
t3 pair.)Copy the pairing URL or the short code.
Run one of:
node dist/cli.js pair "http://127.0.0.1:3773/pair#token=XXXXXXXX"
node dist/cli.js pair XXXXXXXXThe token is stored in ~/.t3-code-agent-mcp/credentials.json. Check everything is wired:
node dist/cli.js status
# Server: http://127.0.0.1:3773 (v0.0.52, …) via …/server-runtime.json
# Token: ok (…/credentials.json)
# Projects: 12, threads: 80, harnesses: codex, claudeAgent, cursor, …When the token expires, run pair again. You can revoke it any time in T3 → Settings → Connections.
Headless alternative: set T3_ACCESS_TOKEN to a token from t3 auth session issue --token-only.
Configure your MCP client
Replace /path/to/t3-code-agent-mcp with where you cloned it. Ready-made files are in examples/.
Claude Code
claude mcp add --scope user t3 -- node /path/to/t3-code-agent-mcp/dist/cli.jsor in .mcp.json / ~/.claude.json:
{
"mcpServers": {
"t3": { "command": "node", "args": ["/path/to/t3-code-agent-mcp/dist/cli.js"] }
}
}Codex CLI (~/.codex/config.toml)
[mcp_servers.t3]
command = "node"
args = ["/path/to/t3-code-agent-mcp/dist/cli.js"]Cursor (.cursor/mcp.json)
{
"mcpServers": {
"t3": { "command": "node", "args": ["/path/to/t3-code-agent-mcp/dist/cli.js"] }
}
}Any other MCP client
Command node, argument /path/to/t3-code-agent-mcp/dist/cli.js, transport stdio. Optional environment variables are listed below.
Typical agent flow
t3_list_projects → pick a project id
t3_list_worktrees {project} → pick a worktreePath (or use the project root)
t3_list_harnesses → pick harnessId + model slug
t3_create_thread {project, worktreePath, harness, model, title, prompt,
idempotencyKey, wait: true} → reply text + thread url
t3_send_message {threadId, prompt, wait: true} → next reply
t3_get_thread {threadId} → status + recent messages
t3_cancel_turn {threadId} → stop a running turnEvery thread result includes url, which opens the thread in the T3 web UI, and turn.state (running, completed, interrupted, error).
Tool reference
t3_list_projects
No input. Returns [{ id, title, workspaceRoot, defaultModelSelection }].
t3_list_worktrees
Input | Notes |
| Project id, exact title, or workspace root path |
Returns the project root (always a valid worktreePath), every other worktree with its branch, and the local branch list.
t3_list_harnesses
Input | Notes |
| Also list harnesses that cannot start threads, with a |
Returns [{ harnessId, driver, displayName, usable, reason, status, auth, version, models: [{ model, name, aliases, isDefault, isLegacy }] }]. T3 calls harnesses "providers"; harnessId is the provider instance id (claudeAgent, codex, cursor, …).
t3_list_threads
Input | Notes |
| Optional filter |
| Default false |
| Default 25, max 200 |
t3_create_thread
Input | Notes |
| Project id, exact title, or workspace root |
| Harness id exactly as listed |
| Model slug or alias exactly as listed for that harness |
| Thread title shown in T3 |
| First user message |
| Optional |
| Existing worktree from |
|
|
|
|
|
|
| Stable key; retries reuse the same thread |
| Wait for the first turn and return the reply (default false) |
| Max wait, default 300 |
Returns the thread summary plus reused (true when the key matched an existing thread) and, with wait, reply and timedOut.
t3_send_message
Input | Notes |
| |
| |
| Optional blocks as above |
| Default: the thread's current modes |
| Stable key; retries do not start a second turn |
| As above |
Refuses if a different turn is still running so an in-flight turn is never clobbered. A retry with the same key is always safe.
t3_get_thread
Input | Notes |
| |
| Default 10, max 200 |
| Truncate each message, default 20000 |
t3_wait_for_turn
Input | Notes |
| |
| Default 300 |
Prefer wait: true on t3_create_thread / t3_send_message, which know exactly which turn to wait for.
t3_cancel_turn
Input | Notes |
|
Returns cancelled: false with a reason when nothing is running.
Environment variables
Put these under env in your MCP client config when needed.
Variable | Meaning |
| Skip discovery and use this origin, e.g. |
| T3 data directory to search for |
| Bearer token to use instead of the stored one |
| Path of the credentials file. Default |
CLI commands: serve (default), pair <url-or-code>, status, help.
How it works
Discovery. Reads
<T3 home>/userdata/server-runtime.json(thendev/), checks the pid is alive, and probes/.well-known/t3/environmentfor the environment id and version.Auth. Bearer token from T3's pairing flow (
POST /oauth/tokentoken exchange), sent as anAuthorizationheader on HTTP and on the WebSocket upgrade.Reads.
GET /api/orchestration/shell(projects + thread list) andGET /api/orchestration/threads/:id(thread detail, windowed by turn).Commands.
orchestration.dispatchCommandover T3's WebSocket RPC with T3's typed commands:thread.turn.startwithbootstrap.createThread(and optionalprepareWorktree), andthread.turn.interrupt. The socket handler is the one that expandsbootstrapand returns typed errors. Thread, command, and message ids are SHA-256 of youridempotencyKey.RPC client.
server.getConfig(harnesses + models) andvcs.listRefs(worktrees) are socket-only in T3, so a small client speaks the Effect RPC JSON envelope:Request,Chunk+Ackback-pressure,Exit,Ping/Pong,Interrupt. Failures are scoped to the socket that carried the request.Waiting. One thread subscription stays open for the whole wait. On session/settle events the HTTP snapshot is re-read a few times (it lags the event by a tick). After a dispatch the wait only accepts the turn that carries your own message id, so a retry or a lagging projection cannot return the previous turn.
Compatibility
Wired against upstream pingdotgg/t3code main at 8419238 (server 0.0.40, 2026-09-14). Every touch point was checked against that source:
Touch point | Upstream |
Pairing exchange |
|
Pairing link |
|
Socket auth |
|
Discovery |
|
Reads |
|
Commands | RPC |
Config + git | RPC |
Waiting | RPC |
Scopes |
|
Thread link | Web route |
Forks that keep these surfaces work unchanged; a fork that moves its data directory only needs T3CODE_HOME.
Troubleshooting
Symptom | Fix |
| Start T3 Code, or set |
| Create a pairing link in T3 → Settings → Connections and run |
| Install, enable, or sign in to that harness inside T3; check |
| Use a slug or alias from |
| Wait with |
| The command failed once and T3 remembers it; fix the cause and use a new key |
| Your T3 is newer than this server's contract mirror; update t3-code-agent-mcp |
Development
npm test # unit tests against a fake WebSocket server; no T3 needed
npm run typecheck
npm run buildLive smoke test (creates one real thread in your T3, visible in the UI):
npx tsx test/smoke.live.mts <projectIdOrRoot> [harness] [model]Layout:
src/cli.ts entry point: serve | pair | status
src/discovery.ts find the running T3 server
src/credentials.ts pairing exchange + token store
src/http.ts HTTP snapshot reads
src/rpc.ts WebSocket RPC client (Effect RPC envelope)
src/t3.ts typed T3 API + wait loop
src/resolve.ts strict project / harness / model / worktree lookup
src/ids.ts idempotency-key → deterministic ids
src/tools.ts MCP tool definitions
src/types.ts wire shapes mirrored from T3's contractsSecurity
The stored token carries T3's standard client scopes (
orchestration:read/operate,terminal:operate,review:write,relay:read). Revoke it in T3 → Settings → Connections.The credentials file is written with mode
0600where the OS supports it. Treat it like a password.Anything reachable through your T3 (its projects, its harness credentials) is reachable through this server. Only expose it to MCP clients you trust.
The server never opens or writes T3's SQLite database.
License
MIT. See LICENSE.
This server cannot be deployed
Maintenance
Related MCP Connectors
Run and manage H Company's Computer-Use Agents from any MCP client.
Hosted MCP memory and agent control plane for durable conversations, jobs, and operations.
Remote MCP learning coach for coding agents.
List, read, edit, and deploy your GenMB AI-generated apps from any MCP client.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables MCP clients to spawn and control Codex CLI and Claude Code sessions on the host machine, with session management and filesystem access.4MIT
- FlicenseAqualityCmaintenanceMCP server for interacting with a running T3 Code instance. Enables viewing agent threads, sending messages, and approving permission requests from Claude Code or voice-controlled models.19-
- AlicenseNot gradedqualityBmaintenanceEnables Claude Code to delegate coding implementation and testing to a local pi agent via MCP tools, including dispatching task books, monitoring status, steering or aborting runs mid-execution, and retrieving results and transcripts.26 npm2MIT
- AlicenseAqualityAmaintenanceEnables agent managers to launch and supervise Antigravity CLI, Claude Code, CodeBuddy Code, or Grok CLI as subagents through local MCP tools for starting, waiting on, and cancelling invocations.4MIT