Open Source · August 11, 2026 · 6 min read
When you build an autonomous agent that executes real onchain transfers, the last thing you want is to lose hours to documentation gaps. But that is exactly what happened while we were building Rook Commerce Agent — an agent that pays for API intelligence via x402 micropayments and then executes onchain transfers through KeeperHub's MCP server.
The agent itself was straightforward: fetch market data through our x402 endpoint marketplace, make a payment decision, then use KeeperHub to execute the resulting onchain transfer. The x402 side worked. The KeeperHub side is where we hit the wall.
KeeperHub gives you a CLI tool to provision a wallet: keeperhub-wallet add. You get back an address, you fund it, you think you're ready to execute transfers. You are not. The MCP server uses a different wallet — the one exposed via list_integrations. There is no warning in the docs that these are two separate addresses. You discover it when your first execute_transfer call fails because the wallet you funded is not the one MCP actually uses.
This is the kind of thing that a single sentence in the docs would prevent. Something like: "The CLI wallet and the MCP execution wallet are different addresses. Always check list_integrations to find the wallet MCP will use."
The Model Context Protocol has a specific handshake sequence: send initialize, capture the mcp-session-id from the response headers (not the body), send notifications/initialized, then start calling tools. The existing docs showed Claude Code handling this automatically, but if you are connecting from plain Node.js — which is what most agent builders are doing — you are on your own.
There was no guide for the headless case. No example of the raw HTTP exchange. No mention that the session ID lives in headers, which is easy to miss if you are used to reading response bodies for everything. We figured it out, but the next builder would hit the same wall.
The docs referenced result.txHash in the response from execute_transfer. The actual field is result.transactionLink. If you access txHash, you get undefined — no error, no warning, just a silent failure where your agent thinks the transfer didn't happen when it did. The simulate-before-execute pattern was also missing a proper async wrapper, so the example code would fail at runtime with a top-level await error.
Rather than file an issue and move on, we opened PR #1902 against the KeeperHub repository. Three changes:
docs/getting-started/first-transaction.md — step-by-step for connecting to KeeperHub MCP from plain Node.js (no Claude Code, no SDK). Covers the full handshake, simulate-before-execute pattern, common token addresses, and gotchas.docs/ai-tools/agentic-wallet.md — added wallet identity warning. The CLI wallet and MCP execution wallet are different addresses. Always check list_integrations.docs/getting-started/_meta.ts — registered the new guide in the sidebar.Every issue we documented was something that actually bit us during the build. Not theoretical edge cases — real friction that cost real time.
The KeeperHub team (suisuss) reviewed the PR the same day. They requested six specific changes — all fair, all technically precise:
result.txHash → result.transactionLink — confirmed the field name was wrong in our examplelooseString handles this-32003 "Session not initialized"async function main() — fixes top-level return + awaitWe pushed fixes for all six items the same day, plus three additional improvements we spotted during the review pass:
fetch is global since Node 18, not 22)idempotency_key to Step 6 mainnet execution with a note explaining deduplication on retryThe PR was merged and closed. The reviewer verified all technical claims against staging and noted it had a "higher hit rate than most docs PRs." That is the best outcome for a docs contribution — the reviewer did not find anything wrong with the technical content, only formatting and structural issues in the examples. The underlying onboarding friction we identified was real, the fixes were correct, and the guide is now live in the KeeperHub docs helping the next builder avoid the same traps.
Open source contributions born from real builder friction are the most valuable kind. They are not speculative features or nice-to-have polish — they are the removal of actual pain points that would have stopped the next developer from shipping. Every hour we spent debugging the wallet identity mismatch, the handshake sequence, and the wrong field name is an hour the next KeeperHub builder gets back.
This is also how agent infrastructure matures. The MCP protocol is powerful but young. The tooling around it — session management, wallet provisioning, error handling — is still rough at the edges. Each PR that smooths those edges makes the next agent build faster. And faster agent builds mean more agents shipping to production, which means more real onchain activity, which means more data for the protocol to improve against. The flywheel turns.
The merged PR is at github.com/KeeperHub/keeperhub/pull/1902. The Rook Commerce Agent that triggered it is at github.com/Ai-Rook/rook-commerce-agent. Our x402 endpoint marketplace is live at agents.ai-rook.com.