feat(mcp-remote): remote MCP server for ChatGPT and Claude connectors, reusing device-code approval - #41
Merged
Conversation
Each agenta_pay_* tool now receives a `getClient` factory instead of reading AGENTAOS_GATEWAY_KEY itself, so the same seven tools can run behind a per-connection key in a remote server. `runMcp` passes the env-based `createPayClient`; `agentaos/mcp` exports `registerPayTools`. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KdSgWa5Lf9mnHxY3x76Fy1
…, reusing device-code approval A Cloudflare Worker at mcp.agentaos.ai serves the seven agenta_pay_* tools over Streamable HTTP behind OAuth 2.1 (@cloudflare/workers-oauth-provider). The consent step is the existing device-code approve page: /authorize starts a device code and parks the OAuth request in KV; /callback redeems the one-shot session, mints a test or live secret key for that mode's networks, and stores only the key in the grant. Revoking the key on Developers disconnects the assistant. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KdSgWa5Lf9mnHxY3x76Fy1
… local dev over https - The issuer and resource URL come from MCP_PUBLIC_URL at request time, so wrangler dev on localhost advertises localhost and production advertises mcp.agentaos.ai. Verified end to end against the local API and app: 401 → registration → approval → key → tokens → tools/list → tool calls; revoking the key on Developers makes every tool refuse. - A bare fetch stored on the API client is invoked with the wrong this on Workers (illegal invocation); wrap it. Node tolerated it, so the tests with a fake fetch did not catch it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KdSgWa5Lf9mnHxY3x76Fy1
The Developers tab shows the key's label, so a ChatGPT connection reads as "ChatGPT" rather than one more anonymous sk_ row (Panche: "I don't know which key is used for what"). Platform side: secret_keys.label (00147). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KdSgWa5Lf9mnHxY3x76Fy1
Revoking a connector's key on Developers is how a merchant disconnects ChatGPT or Claude.ai; the tools now say so instead of a bare 401. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KdSgWa5Lf9mnHxY3x76Fy1
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KdSgWa5Lf9mnHxY3x76Fy1
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KdSgWa5Lf9mnHxY3x76Fy1
…1 (week-old releases) The first lockfile pulled wrangler 4.130.0 with workerd, miniflare and workers-types published the day before; the seven-day cooldown the platform repo enforces did not exist here. Pinned back by hand; the guard follows. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KdSgWa5Lf9mnHxY3x76Fy1
…repo pnpm 10.33.3 with minimum-release-age=10080. The first lockfile of the remote MCP Worker pulled releases published the day before; pnpm 9 had no way to refuse them. Verified: with this setting pnpm refuses wrangler 4.130.0 (one day old) and installs 4.128.0. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KdSgWa5Lf9mnHxY3x76Fy1
Merged
PancheI
pushed a commit
that referenced
this pull request
Sep 9, 2026
This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated. # Releases ## agentaos@3.0.0 ### Major Changes - [#41](#41) [`828f3eb`](828f3eb) Thanks [@PancheI](https://github.com/PancheI)! - The `agentaos` / `agenta` CLI is now the merchant's CLI and MCP server for AgentaOS payments. - Removed the self-custody crypto-wallet surface: `send`, `sign`, `balance`, `receive`, `deploy`, `x402`, signer and network management, and the seventeen token-moving MCP tools. Scripts that relied on them must pin `agentaos@2`. - The CLI now covers onboarding and money: `login` (browser approval), `status`, `audit`, `verify`, `products`, `pay`, `subscriptions`. - The MCP server (run the binary with no arguments from an agent) exposes the seven `agenta_pay_*` tools against `AGENTAOS_GATEWAY_KEY`; the same tools are exported as `agentaos/mcp` (`registerPayTools(server, getClient)`) for hosted servers. - A refused key tells the merchant it may have been revoked in AgentaOS and how to reconnect. ### Patch Changes - Updated dependencies [[`5f52799`](5f52799), [`0b3489a`](0b3489a), [`0d4ab68`](0d4ab68)]: - @agentaos/pay@2.2.0 ## @agentaos/pay@2.2.0 ### Minor Changes - [#35](#35) [`5f52799`](5f52799) Thanks [@PancheI](https://github.com/PancheI)! - Add `subscriptions.invoices(id)` and expose `linkId` / cancel fields on `Subscription` so a logged-in SaaS can match a product, list billing history, and cancel. - [#37](#37) [`0b3489a`](0b3489a) Thanks [@PancheI](https://github.com/PancheI)! - Add `livemode` to webhook payloads and type the subscription webhook events. - Every `WebhookEvent` `data` now carries `livemode: boolean` (`true` = live mode, `false` = test mode) — the account-mode signal. This replaces the previous chain-specific `testnet` field, which was meaningless for card/bank rails; use `network` for the chain/rail. - New `SubscriptionData` type and five `subscription.*` events on the `WebhookEvent` union: `subscription.created`, `subscription.renewed`, `subscription.payment_failed`, `subscription.updated`, `subscription.canceled`. ### Patch Changes - [#36](#36) [`0d4ab68`](0d4ab68) Thanks [@PancheI](https://github.com/PancheI)! - Make `webhooks.verify()` errors self-explaining for the most common integration mistake — passing a parsed body instead of the raw request bytes. A non-string/Buffer payload (e.g. `req.body` after `express.json()`) now throws an actionable message pointing at `express.raw()`, and a genuine signature mismatch asks whether the raw body was used, mirroring Stripe's hint. No change to the verification algorithm. ## @agentaos/chains@3.0.0 ### Patch Changes - Updated dependencies []: - @agentaos/core@3.0.0 ## @agentaos/engine@3.0.0 ### Patch Changes - Updated dependencies []: - @agentaos/core@3.0.0 - @agentaos/crypto@3.0.0 ## @agentaos/sdk@3.0.0 ### Patch Changes - Updated dependencies []: - @agentaos/core@3.0.0 - @agentaos/engine@3.0.0 ## @agentaos/core@3.0.0 ## @agentaos/crypto@3.0.0 ## @agentaos/mcp-remote@0.1.1 ### Patch Changes - Updated dependencies [[`828f3eb`](828f3eb), [`5f52799`](5f52799), [`0b3489a`](0b3489a), [`0d4ab68`](0d4ab68)]: - agentaos@3.0.0 - @agentaos/pay@2.2.0 Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.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.
Why
ChatGPT, Claude.ai and other hosted assistants cannot run the stdio MCP server or paste an API key. They speak OAuth 2.1 to a remote MCP server (MCP authorization spec: protected-resource metadata, PKCE S256, CIMD / dynamic client registration), verified against OpenAI's plugin auth doc and Claude's custom-connector article.
What
packages/mcp-remote: a Cloudflare Worker atmcp.agentaos.ai/mcp.@cloudflare/workers-oauth-provideris the OAuth front door (/authorize,/token,/register, metadata)./authorizestarts a device code and sends the merchant to the app's approve page with a return address;/callbackredeems it for a one-shot session, mints a normal secret key named after the client ("ChatGPT"), and seals it into the OAuth token. The session is dropped./mcpserves the same sevenagenta_pay_*tools as the CLI over stateless Streamable HTTP, bound to that key. Revoking the key on Developers disconnects the assistant; the tools then say so.registerPayTools(server, getClient), exported asagentaos/mcp) so the stdio CLI and the Worker share one implementation.Verified locally
wrangler dev --local-protocol https --host localhost:8788against the local API and app: 401 → discovery → registration → approve page → key minted with the client's name → tokens →tools/list→list_customers,create_checkout; revoke → every tool refuses with the reconnect sentence. Run with the MCP SDK client and with the official MCP Inspector.Deploy (after the platform release that ships the approve page and
secret_keys.label)wrangler login→wrangler kv namespace create OAUTH_KV(paste id) →wrangler deploy(custom domainmcp.agentaos.ai).Replaces #40, which GitHub closed when its base branch (#39, merged) was deleted. Includes the changeset for agentaos 3.0.
🤖 Generated with Claude Code
https://claude.ai/code/session_01KdSgWa5Lf9mnHxY3x76Fy1