El problema de la integración
Toda aplicación de IA útil eventualmente necesita conectarse con el mundo exterior. Un asistente de programación necesita leer archivos y ejecutar comandos. Un agente de soporte al cliente necesita consultar una base de datos y actualizar tickets. Un asistente de investigación necesita buscar en la web y leer PDFs. Cada una de estas capacidades requiere una integración: código que cierra la brecha entre lo que el modelo quiere hacer y el sistema externo que realmente puede hacerlo.
Sin un protocolo estándar, cada una de estas integraciones es personalizada. Conectar un LLM a Slack requiere un adaptador a medida. Conectarlo a GitHub requiere uno completamente diferente. Una integración con PostgreSQL no comparte código ni convenciones con una integración de sistema de archivos. Si construyes una nueva aplicación de IA, tienes que escribir todos estos adaptadores desde cero, aunque alguien que construya una aplicación de IA diferente escribirá unos casi idénticos.
El problema de escalabilidad queda claro cuando cuentas las combinaciones. If you have $N$ AI models (or model hosts) and $M$ external tools, the naive approach requires $N imes M$ custom integrations. Each model provider writes a separate connector for cada herramienta, y cada proveedor de herramientas escribe un conector separado para cada modelo. Con 5 modelos y 20 herramientas, son 100 integraciones que construir y mantener. Con 50 modelos y 200 herramientas, son 10,000. Esta es la misma explosión combinatoria que el hardware enfrentó antes del USB: cada fabricante de periféricos tenía que construir un cable diferente para cada marca de computadora.
The Model Context Protocol (MCP) (Anthropic, 2024) resuelve esto de la misma manera en que USB resolvió el problema de los periféricos: definiendo una interfaz estándar . Los proveedores de herramientas implementan la especificación del servidor MCP una vez. Los hosts de modelos implementan la especificación del cliente MCP una vez. Y luego todo lo que habla MCP puede conectarse con todo lo demás que habla MCP. El problema de $N imes M$ se colapsa a $N + M$: cada host de modelo escribe un cliente, cada herramienta escribe un servidor, y todos interoperan.
MCP is an open protocol (specification) originalmente desarrollado por Anthropic y publicado como un estándar abierto. No es específico de Claude ni de ningún modelo en particular. Cualquier aplicación de IA puede implementar un cliente MCP, y cualquier herramienta o fuente de datos puede implementar un servidor MCP. El resto de este artículo explica exactamente cómo.
Arquitectura MCP: Clientes, servidores y hosts
MCP define tres roles distintos, cada uno con una responsabilidad clara. Comprender estos roles es esencial porque el poder del protocolo proviene de cómo se componen juntos.
The Host MCP es la aplicación con la que el usuario interactúa. Podría ser Claude Desktop, un IDE como Cursor, un chatbot personalizado o cualquier aplicación que quiera usar un modelo de IA mejorado con herramientas externas. El host es responsable de la experiencia del usuario: presenta resultados, maneja permisos y consentimiento, y decide a qué servidores MCP conectarse. De manera crucial, el host controla cuánto de las capacidades del servidor MCP se exponen realmente al modelo. Un host podría, por razones de seguridad, elegir no exponer ciertas herramientas incluso si el servidor las ofrece.
Dentro del host viven uno o más Clientes MCP . Cada cliente mantiene una conexión con estado uno a uno con un solo servidor MCP. Si el host quiere conectarse a tres servicios diferentes (digamos, GitHub, una base de datos PostgreSQL y una API de búsqueda web), crea tres instancias separadas de cliente MCP, una para cada servidor. El cliente maneja los detalles a nivel de protocolo: enviar solicitudes, recibir respuestas, gestionar el ciclo de vida de la conexión.
The Servidor MCP es la contraparte que expone capacidades. Cada servidor proporciona un conjunto específico de herramientas, recursos y prompts al cliente que se conecta a él. Un servidor MCP de GitHub expone operaciones de GitHub. Un servidor MCP de sistema de archivos expone lectura y escritura de archivos. El servidor no necesita saber nada sobre el modelo o el host — simplemente responde a solicitudes del protocolo.
┌─────────────────────────────────────────────┐
│ MCP Host (e.g. Claude Desktop, IDE, app) │
│ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ MCP Client │ │ MCP Client │ . . . │
│ │ (1:1) │ │ (1:1) │ │
│ └──────┬──────┘ └──────┬──────┘ │
└─────────┼────────────────┼──────────────────┘
│ │
JSON-RPC 2.0 JSON-RPC 2.0
(stdio/HTTP) (stdio/HTTP)
│ │
┌──────┴──────┐ ┌──────┴──────┐
│ MCP Server │ │ MCP Server │
│ (GitHub) │ │ (Postgres) │
└─────────────┘ └─────────────┘
La comunicación entre cliente y servidor usa JSON-RPC 2.0 , un protocolo ligero de llamada a procedimiento remoto que codifica solicitudes y respuestas como objetos JSON. La capa de transporte (cómo viajan realmente esos mensajes JSON) soporta dos modos: stdio (entrada/salida estándar) para servidores locales que se ejecutan como procesos hijos en la misma máquina, y Streamable HTTP para servidores remotos accesibles a través de la red. El transporte stdio es más simple (sin redes, sin autenticación) y es el más común para desarrollo local. Streamable HTTP se necesita cuando el servidor se ejecuta en una máquina diferente o detrás de una API en la nube.
El protocolo define tres primitivas principales que los servidores pueden exponer a los clientes:
- Herramientas: funciones que el modelo puede invocar para realizar acciones o calcular resultados. Crear un issue en GitHub, ejecutar una consulta SQL, enviar un mensaje — todas estas son herramientas. Las herramientas son controladas por el modelo : el modelo decide cuándo y cómo llamarlas, igual que las llamadas a funciones, pero las herramientas se descubren dinámicamente a través del protocolo en lugar de estar codificadas en la solicitud de API.
- Recursos: datos que el modelo puede leer para construir contexto. Contenidos de archivos, registros de bases de datos, documentación de APIs, archivos de registro — estos son recursos. A diferencia de las herramientas (que realizan acciones), los recursos son de solo lectura y típicamente son controlados por la aplicación : el host o el usuario decide qué recursos incluir en el contexto del modelo.
- Prompts: plantillas de prompt reutilizables que el servidor proporciona. Estas son controladas por el usuario — dan a los usuarios formas estandarizadas de interactuar con las capacidades de una herramienta. Por ejemplo, un servidor MCP de revisión de código podría exponer una plantilla de prompt "review_pull_request" que estructura la solicitud de revisión de una manera que el servidor sabe manejar bien.
Cómo funciona el descubrimiento de herramientas
In standard function calling (the kind we covered earlier in this track), the set of available tools is defined at API call time. You include a list of tool schemas in the request body, and the model can only call those specific tools during that conversation turn. If you want to change the available tools, you change the API request. The tool definitions are static — baked into each request by the application developer.
MCP flips this model. Instead of the application developer defining tools upfront, the
server declares its own tools at connection time
. When an MCP client connects to a server, it sends a
tools/list
request. The server responds with a complete list of every tool it offers, including names, descriptions, and full JSON Schema definitions for each tool's input parameters. The client then passes these tool definitions into the model's context, and the model can call any of them.
// 1. Client asks: "what tools do you have?"
// Request →
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list"
}
// 2. Server responds with tool schemas
// ← Response
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"tools": [
{
"name": "create_issue",
"description": "Create a new issue in a GitHub repository",
"inputSchema": {
"type": "object",
"properties": {
"repo": {
"type": "string",
"description": "Repository in owner/repo format"
},
"title": {
"type": "string",
"description": "Issue title"
},
"body": {
"type": "string",
"description": "Issue body (Markdown)"
}
},
"required": ["repo", "title"]
}
},
{
"name": "list_pull_requests",
"description": "List open pull requests for a repository",
"inputSchema": {
"type": "object",
"properties": {
"repo": {
"type": "string",
"description": "Repository in owner/repo format"
},
"state": {
"type": "string",
"enum": ["open", "closed", "all"],
"description": "Filter by PR state"
}
},
"required": ["repo"]
}
}
]
}
}
This dynamic discovery has a profound consequence: the model's capabilities can change without changing any code in the host application . Connect a new MCP server, and the model instantly gains access to whatever tools that server provides. Disconnect a server, and those tools disappear. The host application doesn't need to be redeployed or even restarted — it simply reflects whatever servers are currently connected.
When the model decides to call a tool, the flow is straightforward. The model generates a tool call (just like in standard function calling), the client routes it to the appropriate server via a
tools/call
request, the server executes the operation and returns a result, and the client feeds that result back to the model for the next generation step.
// 3. Model decides to call a tool → client sends:
// Request →
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "create_issue",
"arguments": {
"repo": "acme/webapp",
"title": "Fix login timeout bug",
"body": "Users report being logged out after 5 minutes..."
}
}
}
// 4. Server executes the action and returns the result
// ← Response
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"content": [
{
"type": "text",
"text": "Created issue #347 in acme/webapp"
}
]
}
}
The tool schemas use the same JSON Schema format as standard function calling, so the model's existing ability to generate structured tool calls transfers directly. The difference is purely in how the schemas arrive: pushed by the application developer in function calling, pulled from the server in MCP. Additionally, MCP tool definitions can carry annotations — metadata hints like whether the tool is read-only or destructive, which the host can use to make permission decisions (e.g., auto-approve reads but require user confirmation for writes).
Servers can also notify the client that their tool list has changed via a
notifications/tools/list_changed
message, prompting the client to re-fetch the tool list. This means a running server can add or remove tools on the fly — useful for servers that adapt their capabilities based on context (e.g., a database server that exposes different tools depending on which database you're connected to).
Recursos y contexto
Tools let the model do things . Resources let the model know things . While tools are about actions (create an issue, run a query, send a message), resources are about data — structured, read-only information that the server makes available for inclusion in the model's context. Think of resources as the model's reference library: documents it can consult to ground its responses in facts.
Every resource is identified by a
URI
(Uniform Resource Identifier) that follows a scheme specific to the server. A filesystem server might expose resources with URIs like
file:///home/user/docs/spec.md
. A GitHub server might use
github://acme/webapp/issues/347
. A database server might use
postgres://mydb/users/schema
. The URI scheme is up to the server, but the protocol provides a standard way to list, read, and subscribe to resources regardless of the scheme.
Servers expose resources in two ways.
Direct resources
are concrete items the server knows about and can enumerate via a
resources/list
request — the server returns a list of available resources with their URIs, names, descriptions, and MIME types.
Resource templates
are URI patterns with placeholders (like
github://acme/webapp/issues/{issue_number}
) that the client can fill in dynamically. Templates are useful when the set of possible resources is too large to enumerate (e.g., every possible database query).
// Client lists available resources
// Request →
{
"jsonrpc": "2.0",
"id": 3,
"method": "resources/list"
}
// ← Response
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"resources": [
{
"uri": "file:///project/README.md",
"name": "Project README",
"mimeType": "text/markdown"
},
{
"uri": "file:///project/src/config.json",
"name": "App configuration",
"mimeType": "application/json"
}
]
}
}
// Client reads a specific resource
// Request →
{
"jsonrpc": "2.0",
"id": 4,
"method": "resources/read",
"params": {
"uri": "file:///project/README.md"
}
}
// ← Response
{
"jsonrpc": "2.0",
"id": 4,
"result": {
"contents": [
{
"uri": "file:///project/README.md",
"mimeType": "text/markdown",
"text": "# My Project
This project implements..."
}
]
}
}
Resources can also be
subscribed to
. If the server supports it, the client can call
resources/subscribe
on a particular URI, and the server will send
notifications/resources/updated
whenever the underlying data changes. The client can then re-read the resource to get the latest version. This is useful for resources that change frequently, like log files, monitoring dashboards, or live database views.
This is where MCP intersects with the retrieval-augmented generation (RAG) patterns covered in the RAG Pipelines track. A resource server can function like a retrieval pipeline: the host asks the model what information it needs, the model specifies resources by URI, and the host reads them and includes their contents in the context. Alternatively, a more sophisticated MCP server could expose a search tool that takes a query and returns relevant document URIs, combining tool use and resource reading in a single flow. The protocol is flexible enough to support both patterns.
MCP en el mundo real
MCP's value is proportional to its adoption. A protocol is only useful if both sides implement it. So who's actually using MCP?
On the host side (applications that connect to MCP servers), adoption has been rapid. Claude Desktop was the first host with native MCP support, allowing users to connect local MCP servers and give Claude access to their filesystem, databases, and other tools. Claude Code (Anthropic's CLI agent) uses MCP extensively for IDE integration, file system access, and extensibility — users can add custom MCP servers to extend Claude Code's capabilities. Cursor and Windsurf (AI-powered IDEs) support MCP for connecting to external tools and services. The pattern is clear: any application that wants to give an AI model access to external capabilities can use MCP as the standard way to do it.
On the server side (tools and services that expose capabilities via MCP), the ecosystem is growing quickly. The official MCP servers repository hosts reference implementations for common services: filesystem access, GitHub, GitLab, Slack, Google Drive, PostgreSQL, SQLite, Puppeteer (browser automation), and many more. Community-maintained servers cover an even wider range: AWS services, Jira, Notion, Stripe, Twilio, and hundreds of others. Because MCP is an open spec, anyone can write a server for any service.
Connecting an MCP server to a host is typically done through a configuration file. Here's an example of what you might add to Claude Desktop's configuration to connect a filesystem server and a GitHub server:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/alice/projects",
"/Users/alice/documents"
]
},
"github": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-github"
],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "<your-token>"
}
}
}
}
Each entry specifies a command to launch the server process and (optionally) environment variables for authentication. The host launches these processes, establishes MCP connections over stdio, discovers each server's tools and resources, and makes them available to the model. Adding a new capability is as simple as adding a new entry to this configuration.
This is where the ecosystem effect kicks in. Once a tool has an MCP server, it works with every MCP-compatible host — not just Claude, but Cursor, Windsurf, and any future application that supports the protocol. And once a host supports MCP, it gains access to every MCP server in the ecosystem, without the host developer writing any tool-specific code. Write once, use everywhere. This is the same dynamic that made USB, HTTP, and LSP (the Language Server Protocol) so successful: the value of implementing the standard increases with every other participant who also implements it.
MCP vs integración directa de API
MCP is not the only way to connect a model to external tools. The simplest alternative is direct API integration : you write code that calls the GitHub API, parses the response, and formats it for the model. No protocol, no server, no discovery — just a function in your application that does the thing. So when should you use MCP, and when is direct integration the better choice?
The tradeoffs break down along several axes:
- Composability: MCP servers are composable by design. A host can connect to any combination of servers, and new servers can be added without changing the host. Direct integrations are tightly coupled to the host — adding a new tool means changing the application code.
- Reusability: an MCP server works with any MCP-compatible host. A direct integration works only in the application it was built for. If you're building a tool that should work across multiple AI applications, MCP is the clear choice.
- Discovery: MCP tools are discovered dynamically — the model learns what's available at runtime. Direct integrations are defined statically in code. Dynamic discovery is more flexible but adds a layer of indirection that can make debugging harder.
- Simplicity: for a single integration in a single application, MCP adds ceremony. You need a server process, a client, protocol negotiation, and JSON-RPC message handling. A direct API call might be 20 lines of code. The protocol overhead only pays off when you need the composability and reusability.
- Performance: MCP adds a communication layer (JSON-RPC over stdio or HTTP). For most tool calls this overhead is negligible (milliseconds), but for extremely high-throughput or latency-sensitive operations, a direct in-process function call will be faster.
When to use MCP:
- You're building a platform that needs to connect to many different tools (IDE, assistant app, orchestration framework).
- You're building a tool or service that should be accessible from many different AI applications.
- You want users to be able to extend your application's capabilities without modifying its source code.
- You want a separation of concerns between the AI application and the tool implementation (different teams, different repos, different deployment cycles).
When direct integration is fine:
- You have a single application with a small, fixed set of tools that won't change.
- The integration is performance-critical and you need to minimise overhead.
- The tool uses a proprietary protocol that doesn't map cleanly to MCP's request/response model.
- You're prototyping and want the fastest path to a working demo.
The trajectory of the ecosystem suggests MCP is becoming the default. As more hosts support MCP and more servers become available, the cost of not supporting it increases. If you build a tool without an MCP server, users of Claude Desktop, Cursor, Claude Code, and every other MCP host can't use it without custom work. If you build an AI application without an MCP client, your users can't connect the hundreds of existing MCP servers. The protocol isn't mandatory, but network effects are making it the path of least resistance — much as HTTP became the default for web services, not by mandate, but by ecosystemic gravity.
Quiz
Pon a prueba tu comprensión del Model Context Protocol.
¿Qué problema central resuelve MCP para la integración de herramientas de IA?
¿Cuál es la relación entre un cliente MCP y un servidor MCP?
¿En qué se diferencian las herramientas MCP de las herramientas estándar de llamadas a funciones?
¿Qué distingue los Recursos MCP de las Herramientas MCP?