Been heads-down building out an MCP server boilerplate kit for the past few months. Figured I'd share the actual technical lessons, not the "here's why AI agents are the future" takes you can find anywhere. ## The thing that bit me first: tool schema design My initial instinct was to build fat tools. One tool that does a lot. Felt clean from an API design perspective. It was wrong. LLMs call tools more reliably when they're narrow and explicit. A tool called get_user_and_recent_orders_and_preferences fails silently way more often than three separate tools. The model gets confused about intent, passes malformed args, or just picks the wrong tool entirely. The pattern that actually works: // Instead of this get_full_user_context(userId) // Do this get_user(userId) get_recent_orders(userId, limit) get_user_preferences(userId) More surface area, way better reliability. ## State management across tool calls is trickier than it looks MCP is stateless by default. That's fine until your agent needs to do multi-step work where step 3 depends on what step 1 returned. What I ended up doing in the boilerplate was adding a lightweight session context object that tools can read from and write to within a single run. Not persisted, just in-memory scoped to the request lifecycle. Saved me from passing enormous payloads through every tool call. ## Error messages are part of your tool's interface This one is subtle. When a tool fails, the error string goes back to the LLM. If it says Error: undefined the agent usually gives up or hallucinates a fix. If it says User not found. Verify the userId format is a UUID before retrying. the agent actually recovers. Treat your error messages like you're writing them for another developer, because in a way you are. ## What I'd do differently I'd spec out the tool surface area on paper before writing any code. The architecture decisions at that layer ripple through everything else. Building the MCP Server Boilerplate Kit forced me to make all of these mistakes at small scale, which is honestly the best outcome. --- Anyone else building MCP servers or multi-tool agents? Curious what your session/state patterns look like - I've seen a few different approaches and haven't landed on a definitive answer yet.
Spot on with the 'narrow tools' advice! I learned that the hard way too—fat tools are basically an invitation for hallucinations. Your take on treating error messages as a 'developer interface' for the LLM is brilliant.For AgentShare, we've found that returning structured, machine-readable errors actually helps agents self-correct their search parameters. Regarding state, have you experimented with passing a 'session_id' in the MCP context to a lightweight store for persistence across longer multi-step runs? It seems to be the only way to avoid passing enormous payloads back and forth.
MCP is one of those things that sounds simple until you actually build it. the protocol itself is clean but the edge cases around tool registration, error handling, and context management are where all the complexity hides. we use MCP tools extensively in our automation stack — browser tools, file tools, web search, custom API tools. the boilerplate approach is smart because most MCP servers follow the same pattern: define tools, handle requests, return results. having a solid starting point saves a ton of setup time. whats the hardest integration youve seen someone build with your boilerplate?