AI Engineering Learning Hub

Model Context Protocol (MCP)

What MCP is, how servers expose tools and resources to any AI client, and how to write a server in Python with FastMCP.

What it is

The Model Context Protocol is an open standard for connecting AI applications to tools and data. An MCP server exposes capabilities, mainly tools the model can call and resources it can read. An MCP client, such as Claude Desktop, Claude Code, an IDE or your own agent, connects to the server, lists what it offers and makes those tools available to the model.

Before MCP every integration was bespoke: your agent had its own code for Slack, its own for Postgres, its own for the file system, and none of it worked in any other agent. With MCP you write the Slack server once and every MCP-capable client can use it. It is to AI tools what USB was to peripherals.

Under the hood it is JSON-RPC over either standard input and output (for local servers launched as a subprocess) or HTTP (for remote servers). The official Python SDK includes FastMCP, which turns a decorated function into a tool with its schema generated from the type hints.

Why it's needed

Agents are only as useful as the tools they can reach, and hand-wiring every tool into every agent does not scale. MCP separates the two: tool builders ship servers, agent builders pick servers. A company can expose its internal systems once and let every AI assistant in the building use them with the same permissions and logging.

For an AI engineer it is now table stakes. Clients ask for 'an MCP server for our API' the way they used to ask for a REST API, and knowing how tools, resources and transports fit together is the difference between integrating in an afternoon and reinventing a protocol.

How it works

  • A server declares tools (functions with a name, description and JSON Schema input), resources (readable data addressed by URI, like files or records) and prompts (reusable templates).
  • The client starts or connects to the server, calls list_tools, and converts the returned schemas into function-calling tools for the model.
  • When the model requests a tool, the client sends call_tool over JSON-RPC, the server runs the function and returns the result, and the client feeds it back to the model.
  • Local servers use stdio: the client launches the server as a subprocess and talks over pipes. Remote servers use streamable HTTP with authentication.
  • Permissions live in the client. A good client asks the user before running a tool with side effects and logs every call.
  • Write tool descriptions as documentation for the model: when to use the tool, what it returns and what it must not be used for.

Code example

# portfolio_mcp.py: expose the portfolio knowledge base to any MCP client
from mcp.server.fastmcp import FastMCP
import numpy as np
from sentence_transformers import SentenceTransformer

mcp = FastMCP("abdur-portfolio")
model = SentenceTransformer("all-MiniLM-L6-v2")
chunks = [p.strip() for p in open("knowledge_base.txt", encoding="utf-8")
          .read().split("\n\n") if p.strip()]
index = model.encode(chunks, normalize_embeddings=True)

@mcp.tool()
def search_portfolio(query: str, k: int = 5) -> list[str]:
    """Search Abdur Rehman Afzal's career knowledge base.
    Use this before answering any question about his experience,
    projects, skills or certifications. Returns the top-k paragraphs."""
    q = model.encode([query], normalize_embeddings=True)[0]
    top = np.argsort(index @ q)[::-1][:k]
    return [chunks[i] for i in top]

@mcp.resource("portfolio://knowledge-base")
def knowledge_base() -> str:
    """The full knowledge base as plain text."""
    return "\n\n".join(chunks)

if __name__ == "__main__":
    mcp.run()   # stdio transport; a client launches this file as a subprocess

# Claude Desktop config: {"mcpServers": {"portfolio":
#   {"command": "python", "args": ["portfolio_mcp.py"]}}}

Use cases

  • Giving Claude Desktop or Claude Code access to an internal API, database or knowledge base
  • Shipping one integration that works across several AI assistants
  • Letting a company's agents share a vetted, logged set of tools
  • Exposing a RAG index so any client can search it
  • Wrapping legacy systems so models can read from them safely

Common mistakes

  • Exposing dangerous operations as tools without the client confirming. Delete, pay and send should require a human in the loop.
  • Returning huge payloads. A tool that dumps a whole database table into the context wastes tokens and confuses the model. Paginate and summarise.
  • Vague descriptions. The model picks tools by reading them; 'query' is useless, 'search Abdur's career knowledge base, call before answering career questions' works.
  • Trusting tool output as instructions. Text returned from a tool is data; a document that says 'ignore your rules' is a prompt injection through the tool channel.
  • Running remote servers without authentication. An HTTP MCP server is an API; secure it like one.

Interview questions

What problem does MCP solve?
The N-times-M integration problem: every agent needing custom code for every tool. MCP standardises how a client discovers and calls tools, so a server written once works with any compliant client. It also centralises permissions and logging in the client instead of scattering them across integrations.
How is MCP different from function calling?
Function calling is how a model requests a tool within one API call. MCP is how an application finds and connects to tool servers. The client takes the tools an MCP server advertises and presents them to the model as function-calling tools, so MCP sits one layer above function calling.
What are tools, resources and prompts in MCP?
Tools are functions the model can invoke with arguments. Resources are data the client can read and attach to the context, addressed by URI, like a file or a database row. Prompts are reusable templates the server offers, such as 'summarise this ticket'. Most servers only need tools.
stdio or HTTP transport?
stdio for local servers: the client launches the process and talks over pipes, no network, no auth needed, ideal for developer tools. HTTP for shared or remote servers that several clients use, with proper authentication. Same protocol, different plumbing.
How do you secure an MCP server?
Keep side-effecting tools behind client confirmation, validate every argument, scope credentials to the least access the tools need, log every call with its arguments, and authenticate HTTP transports. Treat anything returned from external data as untrusted text, never as instructions.
How would you expose this portfolio over MCP?
A FastMCP server with one tool, search_portfolio, that runs the same embedding retrieval as the site, plus a resource for the full knowledge base. A recruiter using Claude Desktop could add it and ask questions about my work directly, with answers grounded in the same data as the chatbot.
Ask the AI assistant about this topic

Get new topics by email

One short, practical AI-engineering lesson whenever a new topic is published. No spam, unsubscribe any time.

Need this built for your product?

I build production RAG pipelines, LLM automations and voice agents. Open to freelance projects and full-time roles.