Giving an AI agent a captcha tool over MCP: setup, spend limits and failure handling A developer outlined a pattern for wiring a paid captcha-solving tool into a browser-driving AI agent over MCP, covering configuration, spend limits and failure handling. The approach keeps the solver API key in the server's environment rather than tool arguments, enforces a hard dollar cap server-side that fails closed when unset and reserves worst-case cost before each call so parallel solves cannot overshoot, and restricts solving to an allowlist of hosts to prevent a page from steering the tool. The writeup also covers using free test keys for owned sites and handling each failure mode. An agent driving a browser through MCP will eventually land on a form with a captcha. Adding a solver tool takes a few lines of config. The harder part is that this tool is unlike the others: every successful call costs money, the model decides when to call it, and the page it is reading can try to influence that decision. This post covers the setup, the spend limit, stopping a page from steering the tool, and handling each kind of failure. The scope is automation you are allowed to run: your own sites, staging environments, and sites whose terms permit it. If you own the site, start with test keys. They are free, predictable and made for this. 1x00000000000000000000AA always passes and 2x00000000000000000000AB always fails, so you can test both branches of your form. Cloudflare's docs warn that suites like Playwright are detected as bots, which is why these keys exist. 6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ MXjiZKhI , which never shows a challenge and always verifies. The widget displays a warning so it can't slip into production unnoticed. A real solver earns its place when test keys can't answer the question: checking the production configuration, or monitoring a live flow you run. Most MCP clients take the same stdio shape. Here is a browser server next to a solver server, with a placeholder package name: { "mcpServers": { "playwright": { "command": "npx", "args": "@playwright/mcp@latest" }, "captcha": { "command": "npx", "args": "-y", "your-solver-mcp" , "env": { "SOLVER API KEY": "...", "MAX SPEND USD": "1.00", "ALLOWED HOSTS": "staging.example.com" } } } } In Claude Code the equivalent is claude mcp add , with -e KEY=value for each variable and -- before the server command. The default scope is local to you. --scope project writes the config to .mcp.json , which is shared with everyone in the project, so don't put a real key in it. Keep the API key in the server's environment, never in a tool argument: arguments pass through the model and land in the transcript. Use a dedicated key for agents. The flow then has three steps. Read the sitekey and page URL from the page. Call the solve tool. Put the token where the page expects it. Playwright MCP's browser evaluate covers that last step for a standard widget: js = { document.querySelector ' name="g-recaptcha-response" ' .value = "