Skip to content
Conduit

mcp server

t3-fleet-gateway

Let hosted AI agents connect to your T3 Code servers over MCP on all of your computers.

boundsj/t3-fleet-gatewaycommunitylistedunreviewed

Set up

Runs on your computer. Pick your agent and operating system.

This project does not publish an install method we can turn into a config. Follow the README instead.

README

synced Oct 21, 2026

t3-fleet-gateway

CI

Ask your bot to get something done. Let T3 Code do the coding on your machines.

T3 Fleet Gateway connects Grok Bot, Notion and other MCP clients to your T3 servers through one connection. Your agent can find projects, start work, answer worker questions and bring back the result. Each new job gets a T3 thread you can open in T3 whenever you want: a named project's job gets its own git worktree and branch, and work with no named project can run in a machine's T3 scratch workspace.

  • One connection for the fleet. Add machines behind the gateway without adding an MCP connection to every bot.
  • Work you can follow. Jobs have stable IDs, readable replies and a feed of changes that survives restarts.
  • Access you choose. Give an agent Read or Operate access to all machines or selected ones. Project rules decide what its workers may do.
  • Updates when work changes. Webhooks wake your bot when a turn finishes or a job needs attention.

Get going with prompts

You need an always-on machine with Node.js 24.22.1+ on 24.x or 26.12.1+ (older releases do not block the compromised eMudhra intermediates), a running T3 Code server and its t3 CLI. A coding agent on that machine can do the setup. The gateway runs from a Git checkout; it is not published to npm.

1. Ask your coding agent to set up the gateway

Set up https://github.com/boundsj/t3-fleet-gateway on this machine.
Follow docs/setup.md and docs/operations.md. Use a dedicated service
checkout, enroll this machine's T3 server, and add these project
aliases: <your projects>.

Use <your HTTPS tunnel> for the public MCP connection. Enable the
dashboard on a private tailnet URL, separate from the public MCP
listener. Keep discovery off and project approval settings at their
defaults. Run doctor, then give me the MCP URL and dashboard URL.

What this does: gives your cloud agent a secure way to reach T3 while keeping the operator dashboard private. The gateway handles T3 credential renewal after enrollment.

Prefer doing it yourself? The same steps are in the manual setup guide.

2. Connect your bot

Add the returned /mcp URL as a remote MCP connection in Grok Bot or your chosen client. For OAuth clients, ask the setup agent to mint a one-time approval code. Enter it on the gateway's approval page, choose Read or Operate, and select the machines.

Pick the right access: Read follows work; Operate also starts and steers it. All machines includes hosts you add later. Selected machines stays limited to those you approve.

If your client only accepts a bearer token, as Notion's custom MCP connections do, ask the setup agent:

Create a gateway bearer token for <client name>, with <read or operate>
access to <host IDs> and a 90-day expiry. Help me enter it privately in
the client's connection settings. Do not put the token in chat.

Once connected, tell your bot:

Call fleet_status and tell me which machines and projects you can use.
When I give you work, use the gateway to start or continue the right
job. Follow its status, read the worker's replies, and tell me when it
is ready for review or needs my help. Keep the job ID and T3 link.

3. Give it a small job

In project <alias>, check the README for broken local links and propose
the smallest fix. Run the relevant checks and bring me the result for
review. Don't merge or deploy it.

What happens next: the gateway starts a T3 thread in a fresh worktree, tracks it, and lets your bot read the result. Worker questions can come back through the bot. Permission approvals still need your click in T3; unattended projects can use a different runtime mode.

Settle finished work

When review is complete, your bot can call work_settle({ jobId, requestId }) with a unique request ID. It needs Operate access. The job must be idle, cancelled, failed or released, with no running turn, queued user messages or active delegated work. The gateway checks T3 first and confirms settlement by reading it back. work_status reports settled and settledAt; work_feed emits thread_settled.

Settling parks the thread, clears its pin, ends PR watches and detaches provider sessions. It does not archive the thread or change the job state. work_continue can resume a settled idle job; T3 clears settlement when it accepts the message. Terminal jobs keep their existing behavior. If the host credential cannot settle the thread, the tool returns t3_unauthorized; ask the operator to review its T3 access. Settlement checks, retry rules and bounds.

Give your bot a doorbell 🔔

A webhook tells your bot that something changed, so it can check the job without waiting for its next scheduled poll. The gateway sends a small notification; the bot uses its existing MCP connection to read the details.

1. Create the routine in Grok Bot

In the bot conversation you want to receive updates, try:

Create a webhook-triggered routine for T3 gateway updates. For type
"ping", acknowledge the connection test; it has no job ID. For job
events, deduplicate by eventId, call work_status for jobId, and read
work_messages when needed. Report a short status update here.

For this first test, only report: don't start, change or cancel work.
If waitingOnDelegatedWork is true, say the coordinator is still waiting
on its helpers. Keep scheduled work_feed catch-up as a fallback.

Give me the clickable Webhook URL, Webhook key and Authorization header
links that open this routine's private fields. Do not print the actual
URL, key or header value in chat.

2. Copy the routine's connection details

Use the links Grok supplies to open the routine's private fields. If the routine list doesn't show them, ask Grok for those links explicitly. In the routine panel, copy POST to into the gateway's Webhook URL field, and header into Full authorization header. The full header already contains the key; you don't need to copy the separate key field.

Paste both values directly into Connect Grok Bot on the private gateway dashboard, then choose the project to follow. Keep them out of chats.

3. Click Connect & Test

The gateway tests the connection, saves it privately and starts delivering updates. No terminal commands, JSON editing or service restart. Use Replace key to update the connection details, Send test to try again, or Disconnect to stop delivery.

If you recreate the routine or rotate its credentials, copy both fields again: the POST to URL can change along with the key.

What success means: “Test accepted” means the receiver accepted the HTTP request. Check your Grok conversation for its reply to confirm that the routine ran. An already-idle job doesn't produce a new event just because you connected.

The default events cover finished turns (idle), questions or approvals (needs_input), failures, cancellations and delegated work ending. Excerpts are off by default. Delivery may be retried, so routines should deduplicate events and keep feed catch-up enabled. Delivery and recovery details.

Using another receiver? Generic HTTPS subscriptions support its own authentication header and project, machine and event filters. See webhook configuration. The quick connection flow needs a routine created in Grok first: two pasted fields and one button, rather than automatic account linking.

See what's happening

The real dashboard running on a synthetic demo fleet. Names and activity are made up.

Open your private dashboard to see which machines answer, which agents have connected, and which jobs need you. Run checks refreshes health checks. Webhook controls connect your routines; job approvals and control stay in T3.

The dashboard uses a separate loopback listener and belongs behind your private tailnet proxy. Your public MCP URL is for agents. Dashboard setup and access.

Follow a job's pull requests

Ask your bot:

Which PRs came out of that job? Show me what's open and what's merged.

work_status and work_list include cached PR links and states, even for text-only clients: up to 20 per job, open ones first and then the newest. A job follows up to 200 PRs, so a merge among the others is still noticed, and the text says so when it shows only part (20 of 35 shown). The dashboard shows a small PR #21 open badge beside the job. Workers need to register their PR with T3's link_pull_request; a coordinator should link its children's PRs too.

What this means: you can follow the result of a job without searching GitHub. PRs refresh about once a minute while the job is followed, on top of T3's own sync delay. Unknown means not yet readable; a finished or released job keeps its last snapshot.

Want your bot to wake when a PR opens or merges? Add pull_request_opened and pull_request_merged to a configured webhook subscription. These are opt-in; dashboard connections keep their existing five events.

Discover projects and choose models

Discovery is off by default: agents see the aliases you configured. To browse a machine's existing T3 projects and available models, ask your setup agent:

Enable project and model discovery on gateway host <id>. Keep launching
into projects without an alias disabled. Restart and run doctor.

Then ask your bot:

Use fleet_projects and fleet_models on host <id>. Show me its projects
and the models and reasoning efforts it offers. For my next job in
<configured alias>, use <model and effort> and tell me what you selected.

Browsing and launching are separate choices. To launch into projects without aliases, explicitly enable that host's discovery launch policy. Existing aliases keep their restrictions; model choices must match what T3 advertises. Discovery settings.

Start work with no named project

Some requests name a machine but no project. A machine can have a default scratch destination: T3's internal "No project" workspace, with no git worktree or branch. Named projects are unchanged and still get a fresh worktree per job. Ask your setup agent:

On gateway host <id>, add a scratch alias for T3's internal "No project"
workspace and make it the host's default project. Verify that project's
ID in T3 first; don't guess it from the title. Then restart and run
doctor.

When you name a machine but no project, your bot passes target: { host: "<id>" } to work_start. An explicit project still uses its alias or project ID, and an unknown named project is resolved or reported, never sent to scratch. The scratch default needs no discovery. Enabling discovery lets agents with Read access browse that machine's T3 projects and models; launching into projects without an alias stays off unless you enable it separately. Scratch configuration and upgrade notes.

Work in a project's own folder

By default every job in a named project gets a fresh git worktree and branch. Some project folders aren't git repositories, and sometimes you want a job to work in the project's own folder. Turn on workspace selection for a machine and the gateway chooses per job, when it launches: a git repository root still gets a fresh worktree, started from the freshly fetched origin/<baseRef>, and any other folder runs in place. Ask your setup agent:

On gateway host <id>, enable workspace selection with the reference
workspace probe (scripts/workspace-probe.js). Restart and run doctor.

Your bot can also ask for a workspace with work_start's workspace: { "type": "root" } for the project's own folder, or { "type": "worktree" } to insist on a worktree. Only one gateway job at a time works in the same folder: another one waits in the queue, and resuming an idle job is refused with workspace_root_busy while the folder is taken.

What this means: a job in a project's own folder edits that checkout directly, with no branch of its own to review. Machines without the probe behave exactly as before. Workspace probe settings.

Keep a coordinator in the loop

Already have a T3 thread that plans work and delegates to other agents? Adopt it as a standing job so your bot can keep talking to that same thread:

Register <T3 thread link> as a standing job for gateway project <alias>.
Give me its job ID. Leave the thread and any work running in it alone.

Give that request to your setup agent, then tell your bot to use the returned job ID with work_continue. The gateway follows the coordinator's replies and delegated work. Interrupting a standing job stops its current turn; it keeps the thread available for the next request. Standing jobs and coordinator-only projects.

Guides and reference

I want to…Read this
Install manually or connect a clientSetup
Change projects, models, discovery or subscriptionsConfiguration
Diagnose a connection, update, back up or recoverOperations
Understand access, credentials and trust boundariesSecurity
Read the implementation contractDesign
See what changed in a releaseGitHub releases · Changelog

Server-side and native MCP clients are supported; browser-only clients cannot complete OAuth sign-in because the OAuth endpoints do not provide CORS. Known limitations. Report vulnerabilities through SECURITY.md.

Development

npm install
npm run check             # typecheck and tests; fake T3, no production access
npm run dashboard:demo    # try the dashboard with made-up hosts and jobs
npm run webhooks:smoke    # isolated HTTPS, retries and process-crash checks

CI checks Node 24.22.1 and 26.12.1 on Linux, and Node 26.12.1 on macOS. The webhook smoke needs OpenSSL; see its evidence and instructions. The optional compatibility check compares T3's MCP schemas and runs read-only probes; it installs no schedule.

Contributing? Start with CONTRIBUTING.md and AGENTS.md.

License

MIT. See LICENSE.

↑↓ navigate openesc close