MCP Servers: The Model Context Protocol in Practice
A model writes good text. That is all it does on its own. It cannot reach your database, send mail or call an internal API. For a chatbot on a knowledge platform that means: without help the model knows nothing about your own content, it guesses.
MCP is that help, as an open standard. Instead of wiring a new integration for every LLM, the model gets one shared interface to tools and data sources. The model decides when to call which tool. The server decides what the tool returns.
Three parts, no magic
An MCP server has:
None of that is LLM-specific. That is the point.
The server from the healthcare project
For the healthcare platform with 500+ video and PDF items, I built an MCP server that gives the chatbot access to the knowledge base instead of stuffing every possible source into the prompt.
from mcp.server import Server
from mcp.types import Tool, TextContent
server = Server("health-knowledge")
@server.tool()
async def search_knowledge(
query: str,
category: str | None = None,
) -> list[TextContent]:
"""Search the knowledge base for relevant content."""
results = await vector_store.similarity_search(
query=query,
filter={"category": category} if category else None,
k=5,
)
return [
TextContent(
type="text",
text=f"**{r.metadata['title']}**\n{r.page_content}"
)
for r in results
]
@server.tool()
async def get_article_details(article_id: str) -> list[TextContent]:
"""Fetch the full details of a knowledge article."""
article = await db.get_article(article_id)
return [TextContent(type="text", text=article.to_markdown())]
Two tools. Search and detail. The chatbot calls search_knowledge, gets the top 5 hits, calls get_article_details when it needs the full version. The server runs independent of the client. Whether Claude, a custom LangChain agent or another model asks, it does not care.
MCP versus classic function calling
| Aspect | Function calling | MCP |
|---|---|---|
| Standard | per provider (OpenAI, Anthropic) | open standard |
| Transport | HTTP/REST | stdio, HTTP/SSE |
| Discovery | wired manually | automatic tool discovery |
| Reuse | rebuilt per integration | one server, many clients |
Function calling has been around longer, but it is wired differently per provider. MCP is open, has automatic tool discovery, and runs over stdio just as well as HTTP/SSE. The practical difference: a server I build once runs behind every MCP-capable client. With function calling you rebuild the integration per provider.
Access is not an afterthought
A tool that reaches the knowledge base needs the same access control as any other internal API. The MCP server often runs with wider privileges than the chat itself, because it touches a database or a filesystem directly. If you build the server on the argument that "the model decides what it queries anyway," with no authorization of its own, you hand access control to a text predictor. The tenant context belongs in the server call, not the prompt, for the same reason as the retrieval filter in a RAG system.
What breaks in practice
Tool descriptions are the interface, not documentation, and that gets underestimated regularly. The model decides purely from the text whether and when to call a tool. A weak description means the tool gets called too rarely or at the wrong moment, so I write examples into the description, not just one line of purpose.
Errors also have to be interpretable. The database is down, the search returns nothing. An MCP server that throws an exception in that case does not help the model. It has to return something the model can read as "no results" or "error, ask differently."
Without logging, a tool call is simply a blind spot: which tool, with which arguments, how long, what result. Every call needs metadata logged, timestamp, tool name, input, hit count, latency. Skip that and a bad answer cannot be reconstructed later, which becomes a problem the moment someone asks why the bot said something wrong.
And rate limits belong in the server, not the model. An agent looping on the same tool call ten times a second because one intermediate result was not enough to continue is not an edge case, it is the normal case in more complex agent flows. A simple limit per tool and per session stops a model loop from turning into a cost spike or a database incident.
When it is worth it
When the chatbot needs internal sources that are not in the training corpus. When the same tool integration should serve more than one LLM. When an agent should act on your systems, not only talk. For a demo with a handful of questions the effort is not worth it. For a system that runs in production over months, it is.
A server with the official Python SDK is built in a few days. The work after that, sharpening tool descriptions, covering error cases, setting up logging, takes longer than the first version.
When it is not worth it
A single internal endpoint that only ever gets called by one client does not need its own server with discovery and a transport layer. A direct function call is enough. MCP pays off once more than one client needs the same tools, or once the tool set grows enough that discovery makes the difference between a config file per client and one shared definition. Before that point, it is extra infrastructure for a problem that does not exist yet.
Practice: the healthcare chatbot. To read the existing estate before rollout: architecture reviews. Technical lead for a stretch: interim CTO. The service behind this sits under AI engineering.
If this needs to go into production: the LLM readiness check checks on day 3, among other things, whether tool calls can be traced.
The standard itself is still young. What it solves is not new: systems have always needed a clean interface to their data. MCP turns that into a shared language instead of every team reinventing its own.
Related articles
GDPR and data residency once an LLM is in the loop
Where does the model run, where do embeddings and logs sit? The technical list that makes a privacy review of an AI system possible.
Read articleThe EU AI Act from the seat of the person building the system
Traceability, human oversight, documentation: what an engineer can contribute to the AI Act, and where the legal classification begins.
Read articleA call
30 minutes. If the use case does not belong in production, I'll say so.