Seguro has visto que Claude, ChatGPT o Cursor ya pueden leer tu Notion, dibujar en Excalidraw o crear tareas en una app que tú mismo programaste. Detrás de casi todo eso hay un mismo estándar: MCP (Model Context Protocol). Se menciona en todos lados, pero suele explicarse con mucha jerga y poca práctica.
En este artículo te cuento qué problema resuelve MCP, cómo está armado por dentro (host, client y server, y sus primitivas), cómo usarlo hoy desde Claude, ChatGPT y Cursor sin escribir código y cómo crear tu propio MCP para una aplicación. Al final, en la Parte 2, profundizamos en lo que en el video solo menciono de pasada.
El problema: la IA no ve tus datos
Cuando trabajas con un modelo de IA, el flujo básico tiene tres partes: escribes un prompt, el modelo lo procesa y te devuelve una respuesta. El modelo responde según su entrenamiento, pero no tiene acceso a tus cosas: tus correos de Gmail, tus transacciones de PayPal, tus documentos en Google Drive o los productos de tu tienda en Shopify.
Y eso es justo lo que más queremos: que la IA pueda consultar esos datos para responder "¿cuánto ingresé este mes en PayPal?", generar un reporte de ventas o crear productos nuevos en tu tienda.
Antes de MCP: APIs e integraciones propias
Conectar un modelo con otra plataforma ya era posible: combinas la API de la plataforma con el modelo y listo. El problema es que:
- Necesitas conocimientos técnicos y escribir código propio en algún lenguaje.
- Esa integración queda atada a una aplicación. Si pagas varios chats de IA, tendrías que repetir la integración en cada uno.
Es lo que se conoce como el problema M × N: M aplicaciones de IA por N herramientas dan M × N integraciones distintas. Con un protocolo común, cada aplicación implementa el estándar una vez y cada herramienta también, y todos se entienden (Wikipedia).
Qué es MCP
MCP es una forma estándar de conectar una aplicación de IA con plataformas externas. El modelo deja de depender de integraciones hechas a mano: se conecta a un MCP y este hace de intermediario con la plataforma.
Esto tiene dos ventajas muy prácticas:
- Usas la suscripción que ya pagas. Si tu chat (ChatGPT, Claude, Gemini o el que sea) soporta MCP, puedes usar desde ahí los datos de tus otras cuentas.
- Tus propias apps también pueden tener uno. Si desarrollas una aplicación para tu negocio, tu empresa o para ti, puedes crearle un MCP y cualquier IA compatible podrá usarla.
MCP como el USB de la IA
La comparación que vas a ver en todos lados es la del USB. Tu laptop se comunica con un teclado, un mouse o un celular por el mismo puerto, sin importar el fabricante, porque todos siguen el mismo estándar. MCP es la misma idea: de un lado las aplicaciones de IA (ChatGPT, Cursor, Claude) y del otro las plataformas (Gmail, Google Drive, Shopify…), todas hablando el mismo protocolo. Hoy casi todas las plataformas grandes ya ofrecen algún MCP.
De dónde sale MCP
MCP es relativamente nuevo. Anthropic lo presentó el 25 de noviembre de 2024 como un estándar abierto, con una especificación y SDKs para que cualquiera pudiera implementarlo (Anthropic). Otras empresas lo adoptaron rápido, y el 9 de diciembre de 2025 Anthropic lo donó a la Agentic AI Foundation, un fondo de la Linux Foundation que cofundó con OpenAI y Block (Anthropic). Ya no es "el protocolo de Anthropic": es un estándar de la industria.
Arquitectura: MCP host, client y server
Si vas a crear tus propios MCP, necesitas conocer sus tres piezas:
| Pieza | Qué es |
|---|---|
| MCP host | La aplicación de IA que usas (Claude, ChatGPT, Cursor…). Desde ahí se conecta a los servidores. |
| MCP client | Un proceso interno que lanza el host para manejar la comunicación. Hay uno por cada servidor conectado. |
| MCP server | El intermediario que expone lo que se puede hacer en una plataforma. Normalmente lo ofrece la propia plataforma; si creas uno, es para tu aplicación. |
En la práctica, el client es casi invisible: como cada host lanza su client (relación uno a uno), puedes pensar en el host y el client como una sola pieza. Siguiendo con la analogía, el host sería tu computadora, el server el dispositivo y MCP el estándar USB que los conecta.
Cuando le pides algo a tu chat, por ejemplo "crea un diagrama", el host revisa los MCP conectados, descubre si alguno tiene una herramienta para eso y la usa. Un MCP no hace de todo: solo expone las capacidades que la plataforma decidió ofrecer.
Tools, resources y prompts
Esas capacidades se llaman primitivas, y son tres:
- Tools (herramientas): las acciones. Detrás de cada tool hay código: consultar una base de datos, llamar a una API o ejecutar un comando.
- Resources (recursos): datos que la aplicación carga como contexto para que el modelo se entere de algo. Los tools ejecutan; los resources solo informan.
- Prompts: plantillas predefinidas por el MCP, que aparecen por ejemplo como un menú de opciones.
Un matiz sobre los prompts: en el video digo que el modelo decide cuándo cargarlos. Según la especificación, los prompts los elige el usuario (como un comando o una opción de menú); los tools los dispara el modelo y los resources, la aplicación. Lo vemos en detalle en la Parte 2.
Local o remoto: stdio y HTTP
Mucha gente piensa que un MCP es como una API: un servidor subido a la nube. Puede serlo, pero no es obligatorio: muchos MCP servers corren en tu propia máquina, junto a la aplicación de IA.
Por eso hay dos formas de transporte:
- stdio (entrada y salida estándar): para procesos locales, por ejemplo cuando quieres que el MCP maneje un programa de tu computadora.
- HTTP: igual que una aplicación web. Lo eliges cuando despliegas el MCP en la nube y lo van a usar varios usuarios de forma remota.
Autenticación con OAuth
Elegir HTTP trae una consideración extra: la autenticación. MCP no tiene un login propio: lo delega con OAuth. Si una consulta necesita permisos, el servidor responde con un 401, se abre la ventana de login de la plataforma (Google, GitHub o tu propia app) y el cliente obtiene un token que envía en cada petición.
MCP ahora es stateless
Hace poco el protocolo cambió: antes, host y server hacían un handshake inicial y mantenían una sesión con un ID. Desde la revisión 2026-07-28, MCP es stateless (sin estado): cada petición es independiente y lleva sus propias cabeceras, como en una aplicación web (changelog oficial).
Conectores: MCP sin escribir código
En las aplicaciones pensadas para usuarios no técnicos, los MCP aparecen con otro nombre: conectores.
- Claude (claude.ai): en el botón + → Conectores tienes los que ya instalaste y un directorio para explorar más: Figma (para pasar tus diseños a código), Slack, Notion, Microsoft 365 (OneDrive y Outlook) y muchos más. En el video lo conecto con Excalidraw y le pido "crea un diagrama explicativo en Excalidraw acerca de los MCP": Claude lo dibuja animado y luego puedo editarlo o pedirle cambios.
- ChatGPT: en la sección de complementos aparecen prácticamente las mismas aplicaciones. ChatGPT no hizo sus propias integraciones: se apoya en los mismos MCP que usan las demás plataformas.
- Cursor: en Customize → MCPs → Browse Marketplace tiene su propia galería. Al añadir el de Notion se instala como un plugin, me pide autenticarme con OAuth (el login es el de Notion, no del MCP) y después veo todas sus tools: buscar, subir y descargar archivos, crear páginas… Con "usando Notion MCP, crea una página con ideas de proyectos web para ganar dinero extra", la página aparece en mi cuenta de Notion sin tocar nada a mano.
Crea tu propio MCP para una app
Donde MCP se vuelve realmente útil para un desarrollador es al conectar tus propias aplicaciones. En el video hago esto:
- Con Claude Code creo una app sencilla: "crea un CRUD de tareas con Next.js y SQLite" (SQLite guarda todo en un archivo, así que no hace falta configurar una base de datos).
- Le pido: "crea un MCP server con stdio que permita hacer el CRUD del proyecto completo, y que genere tools, resources y prompts".
- El resultado es una carpeta
mcpdentro del proyecto. Funciona como un traductor: lo que pide el usuario se convierte en parámetros, que se validan con Zod (lo típico en MCP con TypeScript): título, id, etc. - Cada tool es una funcionalidad con nombre, descripción, los campos que espera y lo que devuelve: listar tareas (con filtros), obtener una, crear, actualizar, cambiar el estado y eliminar. Por dentro es código normal que devuelve un objeto con datos, igual que una API.
Configurarlo en Claude Code, Claude Desktop y Cursor
Claude Code te da el comando para registrarlo desde la terminal (también soportan MCP otras herramientas de terminal, como Codex). Para Claude Desktop puedes pedirle los pasos. Casi todos los programas usan el mismo formato: un JSON con la clave mcpServers, el nombre del servidor y el comando para ejecutarlo. Por ejemplo, para un servidor stdio:
{
"mcpServers": {
"tareas": {
"command": "node",
"args": ["/ruta/absoluta/al/proyecto/mcp/index.js"]
}
}
}
En Cursor está en Customize → MCP → añadir un MCP, que abre ese mismo archivo. Al guardarlo aparece el MCP "tareas" y, desde el chat, con "usando el MCP tareas, crea 10 tareas de ejemplo", Cursor detecta la herramienta y las crea: al refrescar la app, las tareas van apareciendo una a una. Lo mismo funciona desde Claude, ChatGPT o cualquier cliente compatible.
Dónde encontrar MCPs (y por qué no instalar cualquiera)
Además de los directorios de cada aplicación, hay repositorios como awesome-mcp-servers, con servidores de todo tipo: dibujo, data science, visualización de datos o la nube (AWS, Azure…). Y si ya pagas una plataforma web, revisa si tiene su propio MCP.
Eso sí, cualquiera puede crear un MCP, y no todos son oficiales. Antes de instalar uno, revisa quién es el autor y de dónde sale: podrías encontrarte con uno malicioso que robe información. Prefiere los que publica la misma plataforma que vas a conectar y los de los directorios oficiales, y no instales MCPs para todo.
Conclusión
- MCP es el estándar que conecta tus aplicaciones de IA con tus datos y tus apps, sin integraciones hechas a mano para cada chat.
- Funciona con un host (tu app de IA), un server (la plataforma) y tres primitivas: tools, resources y prompts, por stdio en local o por HTTP con OAuth en remoto.
- Puedes usarlo hoy con los conectores de Claude, ChatGPT y Cursor, y crear el tuyo para tu propia aplicación en pocos minutos.
¿Qué plataforma te gustaría conectar a tu IA con un MCP? Déjamelo en los comentarios del video. Y si quieres ver los MCP que más uso y en qué se diferencian de un CLI, mira CLI vs MCP.
Parte 2: MCP a fondo
Esta parte amplía lo que en el video solo menciono de pasada: quién dispara cada primitiva, cómo se define un tool, qué cambió en la revisión 2026-07-28 del protocolo, cómo funciona la autenticación por dentro y un servidor escrito a mano, sin pedírselo a un agente.
Quién dispara cada primitiva
Un servidor MCP expone tres tipos de capacidades. Las tres las define el servidor y el cliente las descubre pidiendo el listado (tools/list, resources/list, prompts/list). Lo que las distingue es quién decide cuándo se usan:
| Primitiva | Quién la dispara | Qué es | Ejemplo |
|---|---|---|---|
| Tools | El modelo | Acciones que el modelo invoca cuando las considera necesarias | Consultar una tabla, crear un issue, enviar un correo |
| Resources | La aplicación | Datos que el host carga como contexto. El modelo los lee, no los ejecuta | Un archivo, una tabla, un documento |
| Prompts | El usuario | Plantillas que el usuario ejecuta explícitamente | Un slash command o una opción de menú |
Las tres las publica el servidor. Lo que cambia es quién aprieta el gatillo.
El host, además de descubrir, filtra: puede no exponer ciertos tools al modelo, pedir confirmación antes de ejecutar, y el usuario puede desactivar herramientas individuales.
En la práctica, casi todo son tools
La mayoría de servidores del ecosistema exponen solo tools. Resources y prompts están en la especificación y son útiles, pero el ecosistema se concentró en tools, al punto de que las herramientas de conformance tratan hoy a un servidor "solo tools" como el caso típico.
Anatomía de un tool
Un tool tiene tres partes:
- Nombre:
agregar_tarea - Descripción: el texto que el modelo lee para decidir si lo llama
- Input schema: los parámetros, en JSON Schema
La descripción es un prompt. Un tool mal descrito no se usa nunca, o se usa mal.
¿Qué pasa cuando agregas un tool nuevo?
Del lado del servidor, agregar un tool es agregar una función. No tocas el cliente: ni Claude Desktop, ni Cursor, ni tu app, ni el modelo. Esa es la diferencia con el function calling manual.
Lo que no es automático es que un cliente que ya está corriendo se entere:
- El cliente descubre cuando pregunta. Si ya pidió el listado, trabaja con esa foto hasta volver a pedirlo.
- Notificaciones. El servidor puede enviar
notifications/tools/list_changedpara avisar que su lista cambió, si ambos lados lo soportan. - Caché. Desde la revisión 2026-07-28, los listados pueden llevar un TTL que el cliente usa como pista de frescura.
- En stdio, reiniciar es literal. Si el servidor es un proceso local, lo normal es reiniciar el host para que levante la versión nueva.
Qué cambió en la revisión 2026-07-28
Un protocolo stateless
Antes: cada conexión empezaba con un handshake initialize, y los servidores remotos rastreaban la sesión con el header Mcp-Session-Id. Si tenías varias instancias detrás de un balanceador de carga, necesitabas sticky routing o un almacén de sesiones compartido.
Ahora (2026-07-28): no hay handshake ni Mcp-Session-Id. Cada request es autocontenido y lleva su versión de protocolo, sus capacidades y su identidad dentro de _meta. Cualquier instancia puede atender cualquier request: un servidor MCP se despliega detrás de un balanceador como cualquier otro servicio HTTP.
Otros cambios del transporte:
- Headers de enrutamiento. Campos del cuerpo JSON-RPC se replican en headers (
Mcp-Method,Mcp-Name,Mcp-Protocol-Version,Mcp-Param-*), para que un API gateway pueda enrutar y observar el tráfico sin inspeccionar el cuerpo. server/discover. Devuelve versiones soportadas, capacidades e identidad del servidor en un solo request. El cliente puede llamarlo o ir directo a cualquier request y manejar un error de versión si aparece.- HTTP+SSE deprecado. El transporte anterior basado en Server-Sent Events queda en el registro de funcionalidades deprecadas.
Si tienes un servidor en producción, esto no es un cambio de versión: es una migración. Un gateway que enrutaba por
Mcp-Session-Idhay que reescribirlo sobreMcp-MethodyMcp-Name.
Primitivas deprecadas
La revisión 2026-07-28 deprecó formalmente tres primitivas que todavía aparecen en muchos tutoriales:
| Primitiva | Qué hacía | Por qué se deprecó / qué usar |
|---|---|---|
| Roots | El cliente le indicaba al servidor qué rutas del sistema de archivos eran relevantes | Nunca fue un mecanismo de control de acceso, aunque muchos la usaron como sandbox. Se recomienda pasar rutas por parámetros del tool, URIs de recursos o configuración del servidor |
| Sampling | El servidor le pedía al cliente que ejecutara una inferencia del modelo | Trasladaba el costo de la inferencia de forma poco explícita |
| Logging | El servidor enviaba logs al cliente por el protocolo | Deprecado junto a las anteriores |
Siguen funcionando, pero no deben usarse en implementaciones nuevas. Hay una ventana mínima de doce meses: la eliminación más temprana sería en la primera revisión publicada a partir del 28 de julio de 2027.
Autenticación en detalle
Con stdio, el único que puede hablarle al servidor eres tú: es un proceso que tú levantaste. Si el servidor necesita una API key, se la pasas por configuración.
Con HTTP, tu servidor tiene una URL y cualquiera en internet puede enviarle un request. En cuanto hay varios usuarios aparece la pregunta de siempre: quién es y a qué datos tiene derecho.
Tu servidor no hace login
MCP usa OAuth 2.1, y un servidor MCP es un resource server: valida tokens, no los emite. El login, el consentimiento y la emisión de tokens se delegan en un proveedor de identidad (Auth0, Clerk, WorkOS, Supabase Auth, etc.).
No siempre fue así: la revisión 2025-03-26 esperaba que el servidor MCP actuara como su propio servidor de autorización. La revisión 2025-06-18 lo separó.
El flujo
- El cliente llama al servidor sin token.
- El servidor responde 401 e indica dónde está su metadata de autenticación.
- El cliente la lee en
/.well-known/oauth-protected-resource(RFC 9728) y descubre qué servidor de autorización usar. - El usuario hace login con ese proveedor y el cliente obtiene un token.
- Cada request siguiente lleva el token, y el servidor lo valida.
Qué cambió en 2026-07-28
| Tema | Estado actual |
|---|---|
| Registro de clientes | Dynamic Client Registration (DCR) está deprecado en favor de Client ID Metadata Documents (CIMD): el client_id es una URL HTTPS que apunta a un JSON con la metadata del cliente. DCR ya había bajado de SHOULD a MAY en 2025-11-25; ahora además lleva advertencia de deprecación, con doce meses de compatibilidad. |
| Validación de issuer | Nueva (RFC 9207): obligatoria para clientes que reciben el parámetro iss. |
| Resource indicators | Sin cambios desde 2025-06-18 (RFC 8707): hay que rechazar tokens cuyo aud no incluya el URI de tu servidor, aunque la firma sea válida. |
Una regla que evita un problema serio: nunca reenvíes el token del cliente a una API externa. La especificación lo prohíbe porque produce el problema del confused deputy. Si tu servidor necesita llamar a otro servicio, obtiene sus propios tokens.
Ejemplo: un servidor de tareas escrito a mano
La regla para elegir un buen ejemplo: que haga algo que el modelo no puede hacer solo. Un servidor que suma dos números no demuestra nada, porque el modelo suma sin ayuda. Un servidor que lee y escribe un archivo en tu disco sí.
Vamos a crear un gestor de tareas que guarda todo en un tareas.json local, sin dependencias externas.
Probado con
@modelcontextprotocol/sdk1.30.0 y Node.js 22.
Setup
mkdir mcp-tareas && cd mcp-tareas
npm init -y
npm pkg set type=module
npm install @modelcontextprotocol/sdk zod
El servidor (index.js)
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import { readFile, writeFile } from "node:fs/promises";
import { fileURLToPath } from "node:url";
import path from "node:path";
// El archivo vive junto al servidor, sin importar desde dónde se ejecute
const ARCHIVO = path.join(path.dirname(fileURLToPath(import.meta.url)), "tareas.json");
async function leerTareas() {
try {
return JSON.parse(await readFile(ARCHIVO, "utf-8"));
} catch {
return [];
}
}
async function guardarTareas(tareas) {
await writeFile(ARCHIVO, JSON.stringify(tareas, null, 2));
}
const server = new McpServer({ name: "tareas", version: "1.0.0" });
server.registerTool(
"agregar_tarea",
{
description: "Agrega una tarea nueva a la lista de pendientes del usuario",
inputSchema: { titulo: z.string().describe("Descripción corta de la tarea") },
},
async ({ titulo }) => {
const tareas = await leerTareas();
const tarea = { id: tareas.length + 1, titulo, completada: false };
tareas.push(tarea);
await guardarTareas(tareas);
return { content: [{ type: "text", text: `Tarea #${tarea.id} creada: ${titulo}` }] };
}
);
server.registerTool(
"listar_tareas",
{ description: "Devuelve todas las tareas del usuario con su estado" },
async () => {
const tareas = await leerTareas();
return { content: [{ type: "text", text: JSON.stringify(tareas, null, 2) }] };
}
);
await server.connect(new StdioServerTransport());
Qué está pasando:
McpServeres el servidor;registerTooldeclara cada tool con su descripción y su schema (Zod).- Cada tool devuelve un objeto
contentcon el resultado que verá el modelo. StdioServerTransporthace que el servidor hable por entrada y salida estándar.
Cuidado con
console.log. En stdio, la salida estándar es el canal del protocolo. Cualquierconsole.logcorrompe los mensajes. Para depurar usaconsole.error, que va a stderr.
Instalarlo en Claude Desktop
Abre el archivo de configuración desde Configuración → Desarrollador → Editar configuración, o directamente:
| Sistema | Ruta |
|---|---|
| macOS | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Windows | %APPDATA%\Claude\claude_desktop_config.json |
Agrega el servidor con la ruta absoluta a tu index.js:
{
"mcpServers": {
"tareas": {
"command": "node",
"args": ["/ruta/absoluta/a/mcp-tareas/index.js"]
}
}
}
Guarda, cierra Claude Desktop por completo y vuelve a abrirlo. Los dos tools deberían aparecer en el panel de herramientas.
Prueba pidiendo: "Agrega una tarea para revisar el PR del login". Claude te pedirá permiso para ejecutar agregar_tarea. Después abre tareas.json en tu editor: la tarea está ahí.
La forma de instalar servidores locales en Claude Desktop ha ido evolucionando. Si algo no coincide, revisa la documentación oficial de Claude Desktop.
Agregar un tool sin tocar el cliente
Agrega un tercer tool al servidor:
server.registerTool(
"completar_tarea",
{
description: "Marca una tarea como completada usando su id",
inputSchema: { id: z.number().describe("Id de la tarea a completar") },
},
async ({ id }) => {
const tareas = await leerTareas();
const tarea = tareas.find((t) => t.id === id);
if (!tarea) {
return { content: [{ type: "text", text: `No existe la tarea #${id}` }], isError: true };
}
tarea.completada = true;
await guardarTareas(tareas);
return { content: [{ type: "text", text: `Tarea #${id} completada` }] };
}
);
Reinicia Claude Desktop y el tool aparece. No cambiaste ninguna configuración del cliente ni del modelo: el cliente lo descubrió.
Cuándo NO usar MCP
MCP resuelve un problema de interoperabilidad. Si no tienes ese problema, probablemente no lo necesitas.
| Situación | ¿MCP? |
|---|---|
| Una función interna que solo usa tu propia app con un solo modelo | No: function calling directo es más simple |
| Herramientas que quieres usar desde varios clientes (IDE, Claude Desktop, tu app) | Sí |
| Ofrecer tu producto o API para que cualquier agente lo use | Sí |
| Un prototipo rápido de una sola pantalla | Probablemente no |
Checklist de seguridad
- Revisa los servidores antes de instalarlos. Un servidor local corre con tus permisos.
- Las descripciones y resultados de los tools son texto que lee el modelo. Un servidor malicioso o un dato manipulado puede intentar prompt injection.
- Aplica mínimo privilegio. Credenciales de solo lectura cuando alcanza, bases de prueba para experimentar.
- No confíes en roots como sandbox. Nunca lo fueron.
- En servidores remotos, valida el
auddel token y no reenvíes tokens a servicios externos.
Resumen
| Concepto | Idea clave |
|---|---|
| Problema | Integraciones M × N, no reutilizables |
| MCP | Protocolo abierto sobre JSON-RPC 2.0; convierte M × N en M + N |
| Arquitectura | Host (autoridad) → un cliente por servidor → servidor (capacidades) |
| Primitivas | Tools (modelo), resources (app), prompts (usuario) |
| Deprecado en 2026-07-28 | Roots, sampling, logging, HTTP+SSE, DCR |
| Transporte | stdio para lo local; HTTP para lo remoto, ahora stateless |
| Autenticación | OAuth 2.1; tu servidor valida tokens, no los emite |
Si estás siguiendo un tutorial de MCP de hace un año, buena parte de lo que muestra ya no es la forma recomendada. Antes de implementar, revisa el changelog de la revisión vigente.
Fuentes
- Introducing the Model Context Protocol — Anthropic
- Donating the Model Context Protocol and establishing the Agentic AI Foundation — Anthropic
- Model Context Protocol — Wikipedia
- Documentación oficial de MCP
- awesome-mcp-servers
- Changelog de la especificación MCP 2026-07-28
- MCP 2026-07-28: protocolo stateless, MRTR y deprecación de Roots, Sampling y Logging — noze
- How MCP Authorization Actually Works — MojoAuth
- How an MCP client should tell your OAuth server who it is — WorkOS
- MCP glossary — Zuplo