Learning objectives
After reading this article you will be able to:
- Understand what MCP solves and how host, client, and server relate
- Know the three things a server offers: tools, resources, and prompts
- Write and connect a minimal MCP server in Python
A language model on its own only knows what was in its training data and its prompt. To read your database, check a calendar, or open a GitHub issue, it needs a bridge to those systems. Without a common standard, every AI application builds that bridge on its own, one service at a time.
MCP (Model Context Protocol) is that common standard. The official documentation compares it to a USB-C port for AI applications: one connector instead of a different cable for every device.
What problem does MCP solve?#
Without a standard, connecting N AI applications to M services takes up to N times M integrations, each with its own format. With MCP, each application implements the client side once and each service implements the server side once. From then on, any of them can talk to any other.
The protocol only covers the exchange of context. How the application uses the model and runs the conversation is up to whoever builds it. If you have not yet seen how a model works, start with what an LLM is.
According to the documentation, MCP is already supported by assistants such as Claude and ChatGPT and by development tools such as Visual Studio Code and Cursor.
What are the parts of MCP?#
There are three roles:
- Host: the AI application the user opens, such as a chat assistant or a code editor.
- Client: a component inside the host that keeps a connection to one server. The host creates one client per server.
- Server: the program that provides context and functions. It can run on your machine or elsewhere.
An example from the documentation: Visual Studio Code is the host. When it connects to a Sentry server, it creates a client for that server; when it connects to a filesystem server, it creates another.
Messages use JSON-RPC 2.0, a remote call format. If you know REST APIs, the difference is that here the contract includes discovery: the client asks the server what it can do.
What does an MCP server offer?#
A server exposes up to three kinds of capability:
| Capability | What it is for | Example |
|---|---|---|
| Tools | Functions the model can run | Query a database, create an issue |
| Resources | Data that serves as context | File contents, a database schema |
| Prompts | Reusable message templates | "Review this pull request" |
Each kind has list methods (tools/list, for example) and, for tools, an execution method (tools/call). Because the client lists capabilities at runtime, a server can change what it offers without anyone rewriting the application.
Tools are the most used of the three. Each one has a name, a text description, and a JSON schema for its arguments. The model reads the description to decide when to call it, so a clear description matters as much as the code.
How do the client and server talk?#
The protocol has two layers: the data layer (the JSON-RPC messages) and the transport layer (how they travel). There are two standard transports:
- stdio: the client launches the server as a local process and exchanges messages over standard input and output. This is the transport for local servers, with no network.
- Streamable HTTP: each message is an HTTP POST to a single endpoint, such as
https://example.com/mcp. The reply arrives as a JSON object or an SSE stream. This is the transport for remote servers, which serve many clients.
Since the 2026-07-28 revision of the specification, the protocol has been stateless: every request carries the protocol version and the client's capabilities, and the server answers server/discover to announce what it supports. Earlier versions used an initialize handshake and sessions. The old HTTP+SSE transport is deprecated.
At the protocol level, a tool call is JSON like this (the _meta fields with version and capabilities are omitted):
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "weather_current",
"arguments": { "location": "San Francisco", "units": "imperial" }
}
}The reply carries a content list of content blocks, such as text, images, or resources. In practice you never write this JSON: you write a function and the SDK builds the messages.
How do you build a minimal MCP server?#
With the official Python SDK, a tool is a typed function with a docstring. Create the project and install the SDK:
uv init orders
cd orders
uv add "mcp[cli]"In orders.py:
from mcp.server import MCPServer
mcp = MCPServer("orders")
ORDERS = { # sample data, in place of a real database
"1001": "shipped",
"1002": "awaiting payment",
}
@mcp.tool()
async def order_status(number: str) -> str:
"""Look up the status of an order.
Args:
number: Order number, for example 1001
"""
return ORDERS.get(number, "order not found")
if __name__ == "__main__":
mcp.run(transport="stdio")Run uv run orders.py to start the server over stdio. To test without an AI application, use the MCP Inspector, the official debugging tool.
To connect it to Claude Desktop, add the server to the claude_desktop_config.json file, replacing the path with yours:
{
"mcpServers": {
"orders": {
"command": "uv",
"args": ["--directory", "/path/to/orders", "run", "orders.py"]
}
}
}Restart the app and the tool shows up. Over stdio, never write logs with print() to standard output: the protocol messages travel over it, and any extra text corrupts the conversation. Use stderr.
The official TypeScript SDK (@modelcontextprotocol/server) follows the same design: you register tools with a zod schema and serve over stdio.
What are the risks and limits?#
MCP gives the model the ability to act, and that calls for care. The specification recommends always keeping a human in the loop with the power to deny tool calls. The application should show the user which tools are exposed and ask for confirmation on sensitive operations.
- Too many permissions: a server with write access to your database can delete data if the model gets it wrong. Grant only the access it needs and prefer read-only tools whenever you can.
- Untrusted server: the specification tells clients to treat tool annotations as untrusted unless they come from a trusted server. Install only servers from sources you vet.
- Prompt injection: text from an email, web page, or issue can carry instructions that try to trick the model into calling tools you did not intend. Human approval on destructive actions is the simplest defense.
- Exposed remote server: validate the
Originheader, require authentication, and when running locally, listen only on127.0.0.1, as the specification recommends.
Not every project needs MCP. With a single application and three functions, declaring them directly in the model API is simpler. The protocol pays off when the same tools serve several clients.
How does MCP relate to other terms?#
- Function calling / tool use: the model's ability to ask for a function to run. MCP standardizes where functions come from and how the application runs them.
- Agent: a system where the model decides, in a loop, which tools to call. Agents often use MCP servers as a source of tools.
- REST API: an MCP server often wraps a REST API, turning it into tools the model understands.
If your tool will trigger paid model calls, also see how much an LLM API costs.
How to do this on Square Cloud#
A stdio server runs on the user's machine and needs no hosting. A remote server, over Streamable HTTP, is a web application like any other: a process that listens for HTTP and must be up whenever a client calls. On Square Cloud, it runs in an isolated, always-on container with no cold start and no sleep mode, on a *.squareweb.app subdomain with HTTPS. The proxy in front of applications passes SSE responses through without buffering, which matters when a tool streams its own progress.
To publish the orders server on the Python runtime, list mcp in a requirements.txt (at start, the platform runs pip install -r requirements.txt), swap the stdio transport for Streamable HTTP and make the server listen on 0.0.0.0, on the port in the PORT variable. That is the opposite of a local server, which listens only on 127.0.0.1: here the endpoint is public, so validating Origin and requiring authentication become your code's job. Tokens and keys go in the application's environment variables. A web application uses at least 512 MB of the plan's RAM pool, and Hobby starts at R$12.49 a month. The deploy walkthrough is in how to host an API.
On the model side, if you build your own agent (host and client), the AI Gateway can be the LLM that decides which tools to call. It is an OpenAI-compatible API for the cubic model, with function calling in the OpenAI format, up to 32 tools per request. The client turns each MCP tool (name, description and JSON schema) into a function definition; when the response comes back with tool_calls, it calls tools/call on the MCP server and returns the result in a role: "tool" message. The gateway is in beta, at no extra cost during the beta, and comes from the Standard plan, with up to 2.5M tokens a day and a context of up to 16k tokens, which tool definitions also count against. Limits and availability may change when the beta ends. For the server itself, see the API hosting page.
AI
Host AI apps in always-on containers
FAQs
Is MCP an API?
Not exactly. It is a protocol on top of JSON-RPC 2.0 that defines how a client discovers and calls a server's functions. Behind the scenes, the server can call REST APIs, databases, or files.
Which applications support MCP?
The official documentation lists assistants such as Claude and ChatGPT and development tools such as Visual Studio Code and Cursor. The specification is public at modelcontextprotocol.io.
What is the difference between MCP and function calling?
Function calling is the model's ability to ask for a function to be run. MCP standardizes where those functions come from, so one server works with many clients without rewriting the integration for each.
Do I need MCP to build an AI agent?
No. You can declare functions directly in the model API. MCP pays off when the same tools must work across several applications, or when you want to use ready-made servers.
Is an MCP server safe?
It depends on the server. A tool runs code with whatever access you give it, so use servers from trusted sources, grant minimal permissions, and keep a human approval step for actions that change data.
More in AI
See all 13 articles- How much does an AI chatbot cost to build and run?Running an AI chatbot costs model tokens, hosting, a database and, with RAG, extra context per message. See how to estimate the cost per conversation.
- How much does a RAG system cost? Embeddings, database and LLMA RAG system has three costs: embeddings, a vector database and the LLM. See the math for 1,000 questions a day, with hypothetical prices, and where the bill grows.
- How to build a Discord AI botBuild a Discord AI bot with discord.js: an /ask command, the API key in an environment variable, per-channel memory, Discord limits and how to host it.
- How to host an AI chatbotAn AI chatbot is an API that takes messages, calls a language model and streams the reply back. Here is the code and how to put it online.