Repository navigation
T3 Code as an app link, with the gate keeping each nibblet's grant - #52
Merged
Merged
Conversation
… 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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
T3 Code (pingdotgg/t3code, MIT) serves an MCP server at
/mcpon 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, fromt3_environment_read. The logo is T3 Code's own SVG.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 (serverUrlonappLinks.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: "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) inpackages/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.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-levelenvironmentIdnames, or the linked one if it names none. The two tools that useenvironmentIdfor 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-partykeeps its API and says errors in its own types, so Connect is unchanged apart from onescopes: null.Limits, from T3 Code's side
Test plan
pnpm typecheck(all 33 tasks)vitest runfor everything outsidetest/. 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 --checktest/), not run🤖 Generated with Claude Code