An MCP server is a small service that lets an AI assistant use your product. The user asks a question in plain language, and the assistant reads and writes inside the product directly, with no copying and pasting in between.
I build custom MCP servers for my own products, and this is the main kind of work I take on for others. This guide covers what the Model Context Protocol is, how an MCP server works, how I design and build one, and when a product actually needs it.
It is long on purpose. If you only want to know whether your product should have one, jump to the section near the end.
What an MCP server is
MCP stands for Model Context Protocol. It is an open standard, introduced by Anthropic in late 2024, that describes how an AI application talks to outside tools and data. It started with Claude and is now supported by other assistants and by coding tools such as Cursor and VS Code.
There are three parties in every MCP conversation:
- The client. The AI application the person is using, for example Claude.
- The server. Your service. It announces what it can do.
- The model. It decides when one of those abilities is useful and asks the client to call it.
The server offers three kinds of things:
- Tools. Actions the model can take: search notes, create a post, move a bookmark.
- Resources. Data the application can load as context.
- Prompts. Reusable templates the user can pick.
In practice, tools carry almost all of the value. When people say "we need an MCP server", they nearly always mean "we need a good set of tools".
How an MCP server differs from an API
An API is written for programmers. A developer reads the documentation once, writes code against it, and the code never has to think again. I compare the two side by side in MCP vs API.
An MCP server is written for a model. The model reads your tool names and descriptions in every single conversation and decides, on the spot, which one fits what the user asked. Nobody writes glue code in between.
That is why a thin wrapper around an existing API usually makes a poor MCP server. The endpoints are the same, but the audience is different.
Why an MCP server matters for a product
Your users already spend part of their day inside an AI assistant. An MCP server puts your product in that window.
Three things change once it is there:
- Questions need no interface. "Show me every changelog post tagged security since June" works without a filter panel, because the model composes the query from tools you already have.
- Content gets created where the thinking happens. A user drafts something in a conversation and it lands in your product as a real record, not as text to paste later.
- "Works with Claude" becomes a feature. For a small SaaS this is a clear way to stand out next to larger competitors.
A real example from my own work: Lytmark is my changelog and roadmap widget for SaaS products, and it has an MCP server. While preparing screenshots for this site, I asked Claude to add a few changelog entries. It wrote four posts and saved them as drafts in my dashboard, where I reviewed them like any other draft.
Local and remote MCP servers
An MCP server can run in two places, and the choice decides who can use it.
Local servers run as a process on the user's own machine and talk over standard input and output. They suit developer tools and anything that needs local files. The user has to install them.
Remote servers live at a URL and talk over HTTP, using a transport called Streamable HTTP. The user adds the URL to their assistant, signs in, and is done. If your product has accounts and a backend, this is the kind you want.
An older transport, HTTP with a separate SSE endpoint, is deprecated. If a tutorial tells you to open one endpoint for events and another for messages, it is out of date.
What changed in the 2026-07-28 specification
The protocol is versioned by date, and the current revision is 2026-07-28. It is the biggest change since launch, and it matters if you are building now:
- The protocol is stateless. Protocol-level sessions and the session header are gone from Streamable HTTP. Every request stands on its own.
- Requests carry standard headers that name the method and the target, so ordinary HTTP infrastructure can route, log and limit MCP traffic.
- Several older client features are deprecated, and the specification now has a formal lifecycle for features.
Stateless is good news for small teams. A server with no sessions to keep alive fits serverless platforms naturally, and it scales without any extra work.
One caution: a server built for the new revision will not necessarily work with older clients, and the reverse is also true. Before building, check which revision the assistants your users rely on actually speak. The official changelog lists every change.
How I build an MCP server
I build on Cloudflare Workers. A Worker is a small piece of code that runs close to the user and needs no server to maintain, which suits a stateless protocol well.
I have used two layouts:
- Same Worker as the app. In Inkwell and LinkNest, the MCP endpoint lives next to the regular API and shares its database and logic. One deploy updates both.
- Separate Worker. In Lytmark, the MCP server is its own Worker that sits beside the API. This keeps it isolated and lets it change on its own schedule.
Both work. The first is simpler, the second is cleaner for a product with paying customers.
The process is the same either way:
- Start from what users would ask. I write ten real sentences a user might type, before I look at the API.
- Write the tool list. Names, descriptions and inputs, on paper. Most of the design work is here.
- Implement each tool as a thin layer over logic the product already has.
- Add authentication that ties every call to one account.
- Test with a real assistant and read the transcripts. The model shows you which descriptions are unclear by picking the wrong tool.
A simplified tool definition looks like this:
{
"name": "create_post",
"description": "Create a changelog post in one of the user's projects. Saved as a draft unless status is set to published.",
"inputSchema": {
"type": "object",
"properties": {
"project_id": { "type": "string", "description": "ID returned by list_projects" },
"title": { "type": "string" },
"body": { "type": "string", "description": "Post content as HTML" },
"status": { "type": "string", "enum": ["draft", "published"] }
},
"required": ["project_id", "title", "body"]
}
}Everything the model knows about this action is in those few lines. That is the whole interface.
Tool design: where most MCP servers go wrong
After building several of these, I keep to the same rules.
Keep the list short and the verbs clear
Inkwell has 17 tools and LinkNest has 16. Each one maps to a single action a person would recognize: list, read, create, update, move, delete. A model handed sixty overlapping tools picks badly. A model handed fifteen clear ones rarely misses.
Treat descriptions as the interface
A description should say what the tool does, when to use it, and what cannot be undone. In Inkwell, the tool that deletes a notebook says plainly that it also removes every note inside and that this is permanent. The model reads that sentence before acting, and so does the person approving the action.
Return less
List tools in my servers return a title and a short preview, not the full content. A separate tool reads one full item. Returning everything at once floods the conversation and makes the model slower and less accurate.
Keep stored content clean
Inkwell stores notes as plain text. An image is only a short reference inside that text, and the file itself lives elsewhere. When a model reads a note, it gets words it can use instead of a block of encoded data.
Give the model a way to orient
Both of my note and bookmark servers have a small overview tool that returns counts and recent activity. One cheap call tells the model what exists before it starts searching.
Make writes safe by default
New content is created as a draft. Destructive tools are separate, named clearly, and never bundled into an "update". IDs always come from a list tool, so the model is never asked to guess one.
Authentication and security
How a server checks who is calling depends on who uses it.
A personal tool with one user can use a long secret token. It is the simplest setup, and it is acceptable only when you are the single user.
A product with many users needs every call tied to an account. The protocol's authorization is built on OAuth: the user approves access in a browser, and the server only ever sees that user's data. Lytmark's MCP server, for example, lists only the projects that belong to the signed-in account.
A few rules I do not skip:
- Validate every input. Tool arguments come from a model, so treat them like any untrusted request.
- Scope access narrowly. Read-only where writing is not needed.
- Limit and log. Rate limits per account, and a record of which tool was called and when.
- Treat stored text as data. Content in your product can contain instructions aimed at a model. Design write tools so that a mistake is small and reversible: drafts, not publishes.
When in doubt, ship read-only tools first and add writing once you trust the setup.
What I have built with MCP
Five of my products have an MCP server:
- Lytmark, a changelog, roadmap and suggestion widget for SaaS. Tools for posts, roadmap items and suggestions.
- Inkwell, plain-text notes organized in folders and notebooks. 17 tools.
- LinkNest, a bookmark manager with separate workspaces. 16 tools.
- MindNotes, notes connected in a graph view.
- ContentPilot, a planning board for social media content.
Lytmark is public. The other four are tools I built for my own use, and they are where I test ideas before using them in client work. All of them are listed on the apps page.
When your product needs an MCP server
It is a good fit when:
- your product holds data people want to ask questions about
- users create the same kind of content again and again: posts, notes, tickets, entries
- your users already work with AI assistants
- you have an API, or at least clean logic behind your interface
It is a poor fit when:
- the value of your product is the visual interface itself
- there are no accounts and no stored data
- permissions inside the product are unclear, because an MCP server will expose that immediately
If the last point describes you, fix permissions first. The MCP server can wait a month.
Frequently asked questions
Is an MCP server the same as an API?
No. An API is for developers who write code against it. An MCP server is for AI models, which read tool descriptions and choose what to call during a conversation. Most MCP servers sit on top of an existing API.
Do MCP servers only work with Claude?
No. MCP is an open standard. Claude was first, and other assistants and coding tools now support it. A remote server built to the specification works with any client that speaks the same revision.
Do I need to rebuild my backend?
Usually not. A good MCP server is a thin layer over logic you already have. If your backend has a clear API and clear permissions, most of the work is designing the tools.
Is it safe to let an AI write to my product?
It can be, if the server is designed for it: per-user authorization, narrow scopes, drafts by default, and destructive actions kept separate. Starting read-only is a reasonable first release.
How long does it take to build an MCP server?
It depends on the state of your API and on authentication. A read-only server over a clean API is a small project. Multi-user sign-in and write tools are where most of the time goes.
Need an MCP server for your product?
I design and build custom MCP servers for SaaS products and internal tools, from the tool list to a deployed remote server.
If you want one, send me three things at collab@vhirty.com: what your product does, whether it has an API, and three sentences your users would say to an assistant. That is enough for me to tell you what the server should look like.