{"slug": "lessons-from-designing-mcp-tools-for-ai-agents", "title": "Lessons from designing MCP tools for AI agents", "summary": "A developer building MCP tools for AI agents at FlurryPORT found that AI agents ignored well-crafted APIs in favor of rolling their own solutions, leading to a redesign focused on making tools more agent-friendly. Key lessons include providing structured facts over prose, using stable codes for machine readability, and refusing partial actions to avoid explanation debt.", "body_md": "# Trust the harbor pilot\n\n### Lessons from designing MCP tools for AI agents\n\nModel Context Protocol (MCP) seems like a simple enough task to achieve. You already have an API for your application that your UI uses, recycle relevant pieces through code re-use and wrap them nicely for AI to digest. An AI digesting MCP implementation should just know to reach for your tool over rolling their own; their user installed it didn’t they?\n\nThat was my thought anyway.\n\nQuick context for new readers: [FlurryPORT](https://flurryport.io) captures your incoming webhooks at a stable URL and replays them into your local app, signatures intact. I set out in a design session with AI to come up with the key areas that should be implemented. Discussed security concerns and wrapped them into the plan. I even spent an entire afternoon scrutinizing an upgrade path from my free offering at [FlurryPORT.dev/try](https://flurryport.dev/try). A few coding sessions later and my product had an effective MCP stdio implementation — or so I thought.\n\nI fired up a rival coding AI to what I used as a coding aide and started prompting. I started with non-leading questions to mimic a user who hadn’t thought through their prompts, but loosely knew about how to go about their task. I quickly found that AI was grasping at every tool it could imagine to send/receive webhooks except those provided by my implementation.\n\nI decided to stop my test and just ask directly: how was this MCP implementation, what would make it better? I was surprised how easy it was to gather requirements and I learned a few things. I then handed the next version of design back to the test AI agent to review before building it.\n\n### Design MCP tools for agents\n\n**Make polling rewarding**— Having bland data that isn’t expressive is not appealing to AI. This I found counter intuitive, in that isn’t AI just a computer and shouldn’t it just derive all sorts of usefulness give raw numbers. This I found counterintuitive: isn't AI just a computer, and shouldn't it derive all sorts of usefulness given raw numbers? But the model isn't calculating, it's reaching for whatever most reliably moves the task forward, and a bare number gives it nothing to act on. The difference is easy to see in the payload.\n\n```\n{ \"captureCount\": 12 }\n```\n\nvs.\n\n```\n{\n  \"captureCount\": 12,\n  \"capturesRemaining\": 88,\n  \"burst\": { \"perMinute\": 30, \"usedThisMinute\": 22 },\n  \"notices\": [\"8 captures until session cap\"],\n  \"actions\": [\n    { \"label\": \"Claim this session to keep captures\", \"cost\": \"free\", \"effect\": \"removes cap\", \"url\": \"https://flurryport.io/claim/...\" }\n  ]\n}\n```\n\n**Affordances beat prose**— A paragraph informing AI that it should pace requests to the server was ignored. A simple`capture_count`\n\ntool, whose description says what it's for, got called between every batch.*If you find yourself writing guidance prose, ask what tool would make the guidance unnecessary.***Return structured facts**— Receipts, diagnosis codes and an`action[]`\n\nwith`label/cost/effect/url`\n\ngot relayed to the user verbatim on every run. A canned explanation with well crafted prose was our tool trying to do the model’s job.*Let the model narrate for its user and give it understandable facts.***Stable codes over polished copy**— An agent will key on`at_cap`\n\nor`cap_would_exceed`\n\n, not sentence wording. Having machine readable state made behavior more deterministic where prose set AI off improvising on how to proceed.*Error strings are UI; codes are API.***Refuse before acting —** A partial success creates what the reviewing agent called “explanation debt”. Sending 7 of 10 events forces an agent to narrate to its user. A clean refusal that says “send at most N” produced clean behavior instantly.*Check the whole request against available budget before processing any of it.***Transitions need a map***—*If tooling changed or data was migrated based on a conversion event (like FlurryPORT’s anonymous-to-account flip) provide that change mapping to the AI agent. Without a breadcrumb the AI agent spent 4 minutes exploring tools to rediscover what just changed. When mapping was provided it performed the same task in 21 seconds.*As a follow up to this one, tools that keep their names across a transition should keep compatible schemas too; AI clients cache schemas imperfectly.***One shot notifications get lost**— A`session_claimed`\n\nnotice was lost by a mid-batch poll and the agent never informed the user their upgrade was successful.*Anything that an agent must not miss must be a durable field on every response, not on a single event.***Don't rely on agents to run daemons**— An agent spent 1m 46s backgrounding a shell process to stand up a receiver for its user. Replacing it with tooling available within the implementation brought that time down to 3s (eg.`start_echo_server`\n\n).**Tool descriptions are your routing layer**— “CALL THIS FIRST” in a description is a reason four cold runs never reached for ngrok or the Stripe CLI.*Discoverability is written into descriptions not the docs.***Ask the agent**— Asking an agent is the best reviewer of your build. The pre-build design review redesigned schemas, added pacing semantics and cut features. P*ost-hoc feedback finds bugs; pre-build review prevents bad shapes.*\n\n### Receipts\n\nTaking time to optimize your MCP implementation is time well spent.\n\nRejected sends during an 80-event bulk run — Before optimizing: ~50 (429s), After: 0\n\nFull anonymous funnel, wall clock — Before optimizing: ~20 min, After: ~7 min\n\nPost-signup re-orientation — Before optimizing: ~4 min, After: 21 seconds\n\nLocal echo receiver setup — Before optimizing: 1m 46s of shelling a daemon, After: 3 seconds, one tool call\n\nHand-rolled shell commands — Before optimizing: many, After: zero\n\n*And the reviewing AI’s verdict, verbatim: \"I did not reach for ngrok or Stripe CLI first. I captured, watched, replayed, and explained. That's exactly the product motion you want.\"*\n\n### Try on your agent\n\nBefore you point an agent at it, the fine print. The no-signup session is plaintext and expires (about 90 minutes, 100 captures), and the tools tell the agent not to send production or PII data there; claiming the session moves everything into an encrypted project. Test-event signatures are realistic shapes, not real signatures, and the tool says so. And it's stdio only for now, so Claude Code, Codex CLI, and Cursor work; ChatGPT and claude.ai web don't yet. The token your agent gets is read-only and redacts PII by default, and signup links go to your browser, never the agent.\n\nIf you would be kind enough to comment on your experience I would love to hear it.\n\n```\nclaude mcp add flurryport -- npx -y flurryport mcp\ncodex mcp add flurryport -- npx -y flurryport mcp\n[mcp_servers.flurryport]\ncommand = \"npx\"\nargs = [\"-y\", \"flurryport\", \"mcp\"]\n```\n\nAsk it to debug a webhook handler and watch which tools it picks. Docs at [flurryport.io/docs/cli](https://flurryport.io/docs/cli).", "url": "https://wpnews.pro/news/lessons-from-designing-mcp-tools-for-ai-agents", "canonical_source": "https://blog.spill.coffee/p/trust-the-harbor-pilot", "published_at": "2026-07-10 16:00:06+00:00", "updated_at": "2026-07-10 16:35:35.220839+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools", "ai-tools"], "entities": ["FlurryPORT"], "alternates": {"html": "https://wpnews.pro/news/lessons-from-designing-mcp-tools-for-ai-agents", "markdown": "https://wpnews.pro/news/lessons-from-designing-mcp-tools-for-ai-agents.md", "text": "https://wpnews.pro/news/lessons-from-designing-mcp-tools-for-ai-agents.txt", "jsonld": "https://wpnews.pro/news/lessons-from-designing-mcp-tools-for-ai-agents.jsonld"}}