Skip to content

T3 Code as an app link, with the gate keeping each nibblet's grant - #52

Merged
IAmJSD merged 3 commits into
mainfrom
t3-code-app-link
Oct 28, 2026
Merged

IAmJSD merged 3 commits into
mainfrom
t3-code-app-link

Conversation

@IAmJSD

@IAmJSD IAmJSD commented Oct 28, 2026 •

Copy link
Copy Markdown
Member

T3 Code (pingdotgg/t3code, MIT) serves an MCP server at /mcp on each environment for agents it didn't start. This links one, so nibblets can start, message, wait on and read its threads.

What's in it

  • @nibblets/app-link-t3code: you link by signing in to T3 Code, using OAuth the way MCP servers do it. You approve in T3 Code with a pairing code from its Settings → Sharing & access, choosing read only or how much a thread may do. The link's id is the environment's, from t3_environment_read. The logo is T3 Code's own SVG.
  • Linking by signing in (via: "sign_in"), alongside codes. The app sends the person back to the server's new /api/app-links/callback, a plain page load that isn't signed in. The state it brings back finishes the attempt that's waiting on it, and only once. The callback address is the one the UI reached the server at (serverUrl on appLinks.begin) if it's https or this computer, otherwise the server's public address. If neither works, the plugin says it can't link.
  • Grants the gate keeps (grants: "gate"). T3 Code can't make a credential per nibblet, so every nibblet uses the link's sign-in and the gate narrows it. Each T3 Code tool is its own scope, grouped by system (threads, attachments, projects, pull requests, scheduled tasks, the environment) in packages/app-link-t3code/src/tools.ts. That catalogue is kept by hand from T3 Code 0.1.3's source (9826dbb). It leaves out tools only a T3 Code thread can call, and says whether each tool reads, changes things, or both. The gate lists and allows only the tools a grant names (AppLinkServer.tools) and refuses any other before anyone is asked. A link T3 Code approved read-only offers only the tools that read, and a tool T3 Code adds reaches no nibblet until it's catalogued. Grants survive the link's sign-in running out (30 days, with no refresh) and work again once it's linked again.
  • Narrowing to machines. A grant can also be limited to some of the person's machines: the linked environment and the ones linked to it in T3 Code (t3_environment_links). These are ticked in the existing "Only for these" row, and none ticked means all of them, including any linked later. The gate checks where each call acts (AppLinkServer.providers): the machine its top-level environmentId names, or the linked one if it names none. The two tools that use environmentId for a machine to link or forget always act on the linked one.
  • @nibblets/oauth: the OAuth Connect uses for third parties has moved here, so both use it. @nibblets/third-party keeps its API and says errors in its own types, so Connect is unchanged apart from one scopes: null.

Limits, from T3 Code's side

  • T3 Code's MCP server can't approve commands or file changes; only its own app can. The nibblet's prompt tells it to ask its person to approve those there.
  • T3 Code has no sign-out route, so unlinking only forgets the link here. The plugin's description says to revoke it in T3 Code.
  • Every nibblet shares one T3 Code session, so T3 Code can't tell them apart.

Test plan

  • pnpm typecheck (all 33 tasks)
  • vitest run for everything outside test/. New tests cover the T3 Code plugin against a fake T3 Code (OAuth endpoints plus a real MCP server over the SDK's web transport), linking by sign-in and the callback, gate-kept grants through a revoke and a relink, the catalogue, machines, and the gate's tool and machine limits over HTTP.
  • prettier --check
  • Docker integration tests (test/), not run
  • Linking a real T3 Code environment over T3 Connect, not done

🤖 Generated with Claude Code

IAmJSD and others added 3 commits October 28, 2026 21:56
… sign-in, with the gate keeping each nibblet's grant

- `@nibblets/app-link-t3code` links a T3 Code environment over the MCP
  server it serves at `/mcp` for agents it didn't start. Linking is signing
  in there (OAuth as MCP servers have it, approved with a T3 Code pairing
  code), and the link's id is the environment's.
- App links can now link by signing in as well as with a code: the app
  sends the person back to the server's `/api/app-links/callback`, at the
  address the UI reached it at or its public one, and the state they bring
  back finishes the attempt waiting on it, once.
- T3 Code can't make a credential per nibblet, so its grants are the
  gate's (`grants: "gate"`): every nibblet uses the link's sign-in, and one
  granted only to read has the gate list and allow only the tools marked
  `readOnlyHint`. They're kept while the link's 30-day sign-in has run out,
  and work again once it's linked again.
- The OAuth Connect signs in to third parties with moves to
  `@nibblets/oauth`, which both use; `@nibblets/third-party` keeps its API.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…owing only the tools a nibblet was given

- Each T3 Code tool an outside agent can call is its own scope, grouped by
  system (threads, attachments, projects, pull requests, scheduled tasks,
  the environment) in a catalogue kept from T3 Code 0.1.3's source. A link
  T3 Code approved read-only offers only the tools that read; a tool T3 Code
  adds reaches no nibblet until it's catalogued.
- The gate's limit is now a list of tools (`AppLinkServer.tools`) rather
  than read-only, so it lists and allows exactly what a grant gives.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…th the gate refusing calls on any other

- A grant's providers are T3 Code's machines: the linked environment and
  the ones linked to it there (`t3_environment_links`), ticked in a
  nibblet's settings, none for all of them and any linked later.
- The gate checks where a call acts (`AppLinkServer.providers`): the
  machine its `environmentId` names, or the linked one when it names none.
  The two tools that use it for a machine to link or forget always act on
  the linked one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@IAmJSD
IAmJSD merged commit 9479e28 into main Oct 28, 2026
12 checks passed
@IAmJSD
IAmJSD deleted the t3-code-app-link branch October 28, 2026 22:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant