Building Better MCP Servers
MCP servers are everywhere now. GitHub, Atlassian, even BoardGameGeek have them. Plenty are badly built though. They're thin API wrappers that fire back a wall of data without sparing a thought for the context window they're filling. Everyone is rushing to ship one. Companies feel they need an MCP server, so they bolt one on regardless of whether it's any good. Some just expose their entire REST API wholesale, so a trivial query comes back as 15,000 tokens. That misses the point: a traditional API hands you raw data, but an MCP server should deliver an outcome.
The whole game comes down to respecting the context window. It's a limited resource, and it doesn't behave like a normal API constraint. Every token in your response eats into it, and a bloated response makes the model worse. I once saw a CRM return 50+ fields per user object: internal timestamps nobody asked for, base64-encoded avatars, the lot, when all anyone wanted was an email address. Return only what's needed by default, and put the extras behind optional parameters. GraphQL fits this nicely, since the client picks exactly what it wants.
From there, build tools around what the user is actually trying to do, not around your API. Don't map one tool to each endpoint. My BGG MCP works this way: instead of exposing the raw endpoints, the rules resolver combines several APIs into one tool that searches the forums and gives a direct answer. No bouncing through a chain of tool calls, no polluting the context along the way.
How you shape the response matters too. XML tags give the model more to grab onto than plain JSON, and I like to bake instructions into the response itself, telling the model how to read what it got back and nudging it toward a sensible next step or tool call. The same thinking applies to errors. A generic status code is useless to a model. An error deserves a real, context-aware response that says what went wrong, why it matters, and what to try instead.
There are also three newer parts of the protocol worth knowing about, because they let you build something more interesting than a wrapper. Sampling lets the server ask the host's model to do some reasoning on its behalf, so it can offload a bit of thinking without shipping its own API key or model. Roots define the trusted working directories, which keeps the server from wandering off and trashing something it shouldn't. Elicitation lets the server pause and ask the user for structured input mid-run, so it can get clarification when there's more than one sensible option.
The MCP servers worth having aren't the ones thrown together in an afternoon. They're the ones designed around real agentic workflows.