How to Build a Small MCP Server That Actually Helps
Start with one job
The quickest way to build an MCP server that gets used is to make it do one job well. Instead of exposing your whole database or product API, pick a question a coding agent currently cannot answer. For a small site, that might be "which landing page lost the most visitors between checkout steps" or "what did traffic look like before and after the last deploy."
Write down the exact question, the data needed, and one tool name. If you cannot describe the job in a sentence, narrow it before writing code.
Choose the transport
MCP servers can run in two common ways. A local process that the coding agent starts is simpler for personal use. A network-accessible server makes sense when several machines or teammates need the same tools. For a first server on your own machine, choose the local process route because there is less to secure and debug.
Hosted tools sometimes already provide an MCP server. For example, measuremy.site exposes website analytics to coding agents through its own MCP server. If your goal is to let an agent read analytics, adding an existing server is faster than building one. But when you need access to internal data or a workflow that is not exposed, building is the right choice.
Define the tool in plain terms
A tool definition is the contract between your server and the coding agent. It should contain a clear name, a short description, each input with its type, and what the tool returns. The agent relies on the description, not on guessing.
Here is a small read-only tool definition for a funnel drop-off question:
{
"name": "get_funnel_dropoff",
"description": "Return pageview counts for two funnel steps so the agent can calculate the drop-off.",
"parameters": {
"step_a": "string",
"step_b": "string"
}
}
The handler should do the smallest amount of work: look up the two numbers and return them. Do not try to make the tool answer the whole business question. Returning raw counts lets the agent do the arithmetic and explain the result.
def get_funnel_dropoff(step_a, step_b):
return {
"step_a": pageviews[step_a],
"step_b": pageviews[step_b]
}
Keep outputs small and predictable. A coding agent handles JSON well, but a huge payload can slow it down and make the answer less reliable.
Write descriptions like documentation
The description is not a label. It should say when to use the tool, what each parameter means, and what the output contains. For example, instead of "Gets funnel data," write "Returns pageview counts for two page paths. Use this when the user asks where visitors dropped off between two steps."
If your tool can change data, say so in the description. A tool with a vague description may be called when the agent is trying to answer a question. If the tool is read-only, make that explicit.
Use a real data source early
A demo server with made-up numbers will not show you whether the tool is useful. Connect it to a real source as soon as possible: a local database, a CSV export, your CRM, your analytics export, or an internal JSON file. Read-only access is enough for the first version.
For a small site, a useful first server might answer questions about pages, traffic sources, or signup events. Start with one table or one file. Once the agent can answer one real question reliably, add another tool.
Test with a direct prompt
After you connect the server, test it with a short prompt that asks for the exact thing the tool provides. For example: "Which step has the bigger drop-off, /checkout or /pricing?" Then ask a question that should not use the tool. If the agent calls the tool at the wrong time, improve the description.
You can also ask the agent to explain its answer. If the explanation is wrong, the issue is usually the tool output or the description, not the model. Return clearer fields or simplify the tool.
Secure the server from the start
Even a local MCP server can read files and environment variables. Do not include secrets in tool output. If a tool accepts a file path, validate that it points to the directory you intend. If the server listens over a network, add authentication and use HTTPS. If you are unsure what is required in your situation, check your own legal position.
Write access should be added later. A first server with read-only tools is easier to test and less likely to cause damage.
Iterate on tool boundaries
If the agent often asks for two numbers together, that may be one tool. If it asks for many different reports, create separate tools with narrow outputs. Avoid one tool that takes a generic query string and returns whatever the database returns, because the agent will not know what it can ask for and you will have a harder time securing it.
- Add tools only after a real question shows up.
- Keep each tool to one clear action.
- Return JSON with consistent field names.
- Version the server with a changelog so teammates know when tool behavior changes.
When to build and when to connect
Building an MCP server is worth the time when the data or action is internal and specific to your business. If the data already lives in a hosted service with an MCP server, connecting it may be enough. A coding agent can read website analytics through an existing MCP server without you writing a single handler.
If you do build one, keep it small. A server with three well-described tools is more useful than a server with thirty vague ones.
A custom MCP server is a small piece of infrastructure that translates a private data source into something a coding agent can reason about. Start with one real question, define a narrow tool, connect it to real data, and test the prompt before adding more. If a hosted service already provides the server you need, use that first and spend your build time on the part only you can expose.
See it on your own site
measuremy.site is cookieless analytics your coding agent can read. 30-day free trial, no card. Plans from $9/month.
Start free trial See the live demoAdd measuremy.site analytics to this project: connect the measuremy.site MCP server at https://a.measuremy.site/mcp for all my projects (claude mcp add --scope user; it signs in with OAuth, no key, and one sign-in covers every site), then tell me how to sign in. Details: measuremy.site/llms.txt
Free tools
- Analytics tag checker: Which analytics and pixels a site runs, plus duplicate and broken tags.
- Free UTM link builder: Add utm_source, medium and campaign to any link.
- Website traffic checker: A site's popularity rank and estimated monthly visits.
More from the blog
- How to calculate your website conversion rate, and what to compare it to
- Is my A/B test result significant? A plain-English guide with a worked example
- What is bounce rate, how is it calculated, and is yours a problem?
- How to add a visitor counter to your website or GitHub README
- How much traffic does a website get? How to estimate any site's visits
- How to track QR code scans: count them, and see which poster worked
- How to see how many people clicked your link (without a paid shortener)
- How to check if your Google Analytics 4 tag is installed (and only counting once)
- Why GA4 shows your campaign traffic as Unassigned (and how to fix the links)
- Does your redirect keep your UTM tags? How to check before a campaign goes out
- How I built a self-hosted analytics MCP server on Cloudflare Workers and D1
- UTM tracking explained: what the parameters mean and how to use them
- Conversion funnel analysis for small sites: a practical guide
- Sudden drop in website traffic? A checklist for finding the cause
- What is an MCP server? A plain-English guide for people who run websites
- How to Find the Biggest Drop Off in a Funnel
- What Is the Urchin Tracking Module?
- What Microsoft MCP servers actually do
- UTM parameters for email newsletters
- Track Button Clicks Without Google Tag Manager
- How to track the results of a social media post without cookies
- How to track traffic from a GitHub README
- How to measure a product launch without guessing