Skip to content

wallet: two tools an agent shouldn't have, and two that were one - #1448

Merged
asim merged 1 commit into
mainfrom
claude/guest-query-limits-rxda1o
Aug 2, 2026
Merged

wallet: two tools an agent shouldn't have, and two that were one#1448
asim merged 1 commit into
mainfrom
claude/guest-query-limits-rxda1o

Conversation

@asim

@asim asim commented Aug 2, 2026

Copy link
Copy Markdown
Member

The wallet surface was five tools. It is now one, plus pay.

wallet_transfer moved credits to another account by username, irreversibly, in a single call with no confirmation step. The same agent holds mail_inbox, news_read, web_fetch and db_list — four ways to read text a stranger wrote — and nothing downstream could tell "the user asked" from "the agent read it in an email". The web form's CSRF token does not apply to a caller holding a bearer token, so the caps were the only thing between an injected instruction and £100 a day. Transferring credits is something a person does a handful of times, deliberately, and /wallet/transfer already does it well. It is not a capability an agent should be granted, so it is no longer a tool. The page is untouched.

wallet_topup returned card tiers to a caller that cannot complete a card purchase. Its only real output was "tell your human where to go", which belongs in the message you get when a call fails for want of credits — so those messages now name /wallet/topup, the page that actually sells credits, rather than /wallet.

wallet and wallet_balance both answered "what is in my wallet" with different halves of the answer, which left the planner flipping a coin. Credits are what calls are charged in and USDC is how you top them up: two fields of one thing. They are merged into wallet_balance, with wallet kept as an alias so "my wallet" still resolves, and it is no longer path-backed — pointing a tool at /wallet is what made it scrape the wallet web page for data in the first place.

A test now fails if any tool moves money out of an account. pay is named as the deliberate exception rather than pattern-matched: settling a call to another server against your own wallet is buying something, not giving it away, and the spend limit bounds it.

Verified against a running binary: 56 tools listed, wallet_transfer and wallet_topup answer "Tool not found", the wallet alias still resolves, and /wallet, /wallet/transfer and /wallet/topup all still serve.

Claude-Session: https://claude.ai/code/session_01KdcPjN9ndJwMGKQSRrAGPE

The wallet surface was five tools. It is now one, plus `pay`.

wallet_transfer moved credits to another account by username,
irreversibly, in a single call with no confirmation step. The same agent
holds mail_inbox, news_read, web_fetch and db_list — four ways to read
text a stranger wrote — and nothing downstream could tell "the user
asked" from "the agent read it in an email". The web form's CSRF token
does not apply to a caller holding a bearer token, so the caps were the
only thing between an injected instruction and £100 a day. Transferring
credits is something a person does a handful of times, deliberately, and
/wallet/transfer already does it well. It is not a capability an agent
should be granted, so it is no longer a tool. The page is untouched.

wallet_topup returned card tiers to a caller that cannot complete a card
purchase. Its only real output was "tell your human where to go", which
belongs in the message you get when a call fails for want of credits —
so those messages now name /wallet/topup, the page that actually sells
credits, rather than /wallet.

wallet and wallet_balance both answered "what is in my wallet" with
different halves of the answer, which left the planner flipping a coin.
Credits are what calls are charged in and USDC is how you top them up:
two fields of one thing. They are merged into wallet_balance, with
`wallet` kept as an alias so "my wallet" still resolves, and it is no
longer path-backed — pointing a tool at /wallet is what made it scrape
the wallet web page for data in the first place.

A test now fails if any tool moves money out of an account. `pay` is
named as the deliberate exception rather than pattern-matched: settling
a call to another server against your own wallet is buying something,
not giving it away, and the spend limit bounds it.

Verified against a running binary: 56 tools listed, wallet_transfer and
wallet_topup answer "Tool not found", the `wallet` alias still resolves,
and /wallet, /wallet/transfer and /wallet/topup all still serve.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KdcPjN9ndJwMGKQSRrAGPE
@asim
asim merged commit 5220ca0 into main Aug 2, 2026
1 of 2 checks passed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 789e3480b5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread agent/agent.go
- apps_run: Run JavaScript code and return the result (args: {"code":"return 2+2"})
- wallet_balance: Check your wallet credit balance (no args)
- wallet: Get your Base wallet address and USDC balance (no args). Sending USDC there tops up credits.
- wallet_balance: Check your balance — credits, plus your Base address and USDC for topping up (no args). To add credits, point the user at /wallet/topup; there is no tool for it.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Remove the retired top-up tool from public catalogs

After retiring wallet_topup, the home-page ToolsDropdownHTML still lists “💳 Topup” under “Available Tools” (agent/agent.go:691-692), and the MCP catalog in README.md:73 still advertises wallet_topup. Users following either catalog will call a tool that now returns “Tool not found”; update these public tool lists as part of the removal.

Useful? React with 👍 / 👎.

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.

2 participants