En la lección anterior escribiste una herramienta sap_consultar_pedido_compra dentro de tu aplicación. Funciona. Ahora el equipo de compras quiere lo mismo en Claude Code, el de finanzas en su agente de conciliación y alguien pregunta si se puede usar desde la app de Claude. Copiar la herramienta tres veces es la receta para tener tres versiones distintas dentro de seis meses.
Para eso existe el Model Context Protocol (MCP): escribes la integración una vez, como servidor MCP, y cualquier aplicación que hable MCP la usa. Es exactamente la pregunta de ejemplo de la guía oficial del dominio 8, y la idea que tienes que llevarte: MCP es la opción cuando la integración tiene que ser reutilizable y mantenerse aparte de cada aplicación.
Quién es quién en MCP
MCP es un estándar abierto. Los mensajes viajan en JSON-RPC 2.0 y hay tres papeles que el examen espera que distingas sin dudar:
- Host: la aplicación con la que habla el usuario. Claude Code, la app de escritorio de Claude, un IDE o tu propio agente.
- Cliente MCP: el componente dentro del host que mantiene la conexión con un servidor. Un host con cinco servidores tiene cinco clientes.
- Servidor MCP: el programa que expone capacidades (tu servicio de pedidos, Slack, una base de datos) de forma estándar.
Pasa por encima o toca un módulo
El servidor no sabe qué modelo hay detrás ni qué host lo usa: habla el protocolo y ya.
Un matiz que confunde: el modelo no se conecta a nada. El host descubre las herramientas del servidor, se las presenta a Claude como herramientas normales y, cuando Claude pide una, el cliente la ejecuta en el servidor y devuelve el resultado. Es el mismo ciclo tool_use y tool_result de la lección 4, con un protocolo estándar en medio.
Las tres primitivas del servidor
Un servidor puede exponer tres cosas. La diferencia clave es quién decide usarlas:
Tools
Funciones que Claude decide llamar: consultar_pedido, crear_incidencia. Llevan nombre, descripción y esquema de entrada. Pueden tener efectos: aquí van las aprobaciones y el mínimo privilegio.
Resources
Datos de solo lectura identificados por una URI (catalogo://proveedores, file:///…). El host decide si los adjunta al contexto. Sirven para dar contexto, no para actuar.
Prompts
Plantillas de mensaje que el usuario elige de un menú (en Claude Code aparecen como comandos con /). Rellena los argumentos y el mensaje entra en la conversación.
Hay además primitivas en sentido contrario, que el cliente ofrece al servidor: por ejemplo, pedir al host una generación del modelo (sampling) o pedir datos al usuario a mitad de una operación (elicitation). Basta con saber que existen y en qué dirección van.
Construir un servidor en Python
El SDK oficial de Python para MCP va por la versión 2, con soporte de la especificación 2026-07-28. Se instala con uv add "mcp[cli]" (o pip install "mcp[cli]") y la clase central es MCPServer. Si ves tutoriales con FastMCP, son de la versión 1, que sigue recibiendo parches de seguridad pero ya no es la línea estable.
Un servidor mínimo para pedidos de compra, con una herramienta, un recurso y un prompt:
import logging
from mcp.server import MCPServer
from mcp.server.mcpserver.exceptions import ToolError
from sap_cliente import leer_pedido, PedidoNoEncontrado # tu código: llama a una API publicada de SAP
logging.basicConfig(level=logging.INFO) # el logging por defecto escribe en stderr
mcp = MCPServer("sap-compras")
@mcp.tool()
def sap_consultar_pedido_compra(numero_pedido: str) -> dict:
"""Devuelve estado, proveedor, posiciones y fecha de entrega prevista de un
pedido de compra de S/4HANA. Úsala cuando el usuario dé un número de pedido
de 10 dígitos. No busca por proveedor ni por fecha. Solo lee datos."""
try:
return leer_pedido(numero_pedido)
except PedidoNoEncontrado:
raise ToolError(f"No existe el pedido {numero_pedido}. Pide al usuario que confirme los 10 dígitos.")
@mcp.resource("compras://politica-reclamaciones")
def politica_reclamaciones() -> str:
"""Política interna para reclamar retrasos a proveedores."""
return open("politica.md", encoding="utf-8").read()
@mcp.prompt()
def preparar_reclamacion(numero_pedido: str) -> str:
"""Prepara el borrador de reclamación por retraso de un pedido."""
return f"Revisa el pedido {numero_pedido} y redacta una reclamación según la política de compras."
if __name__ == "__main__":
mcp.run() # sin argumentos: transporte stdio
Fíjate en lo que no has escrito: ningún JSON Schema. El SDK lo saca de los tipos (numero_pedido: str) y la descripción, del docstring. Por eso todo lo que aprendiste sobre descripciones en la lección 4 aplica aquí igual: el docstring es la descripción que Claude lee.
Para probarlo sin ningún host, uv run mcp dev server.py abre el MCP Inspector, donde llamas a la herramienta, lees el recurso y renderizas el prompt a mano. Es tu primera herramienta de depuración.
El fallo número uno: escribir en stdout. Con el transporte stdio, la salida estándar es el canal del protocolo. Un print() de depuración mete texto en medio de los mensajes JSON-RPC y el host corta la conexión. Registra con logging, cuyo manejador por defecto escribe en stderr. Los otros dos clásicos: rutas relativas (el host arranca tu servidor desde su propio directorio) y no reiniciar el host tras cambiar su configuración.
Transportes: stdio o HTTP
La guía pregunta por «patrones de comunicación». Hoy hay dos transportes estándar que importan:
stdio
El host lanza tu servidor como proceso hijo
- Se comunican por stdin y stdout; no hay puerto ni red
- Ideal para herramientas personales o de una sola máquina
- Cada usuario necesita tu código y sus dependencias
- Credenciales por variables de entorno del proceso
Streamable HTTP
Tu servidor escucha en una URL
- Lo despliegas una vez y cualquiera con permiso se conecta
- Es el que se usa para servidores compartidos y en producción
- Admite autorización OAuth; también cabeceras con token
- Es el único que acepta el conector MCP de la Messages API
SSE, el transporte HTTP anterior, está obsoleto: úsalo solo si un servidor antiguo no ofrece otra cosa. Claude Code admite además WebSocket para servidores que empujan eventos.
El mismo objeto mcp sirve para los dos: uv run mcp run server.py --transport streamable-http lo publica por HTTP sin tocar el código de las herramientas.
Tu servidor MCP de pedidos funciona en tu portátil con Claude Code. Ahora quieres usarlo desde una aplicación en producción que llama a la Messages API con el conector MCP. ¿Qué tienes que cambiar?
Conectarlo a Claude: cuatro caminos
Camino 1: Claude Code. No hay fichero que editar a mano: lo registras con la CLI. Todo lo que va después de -- es el comando que lanza el servidor.
# Servidor local por stdio (ámbito local por defecto: solo tú, solo este proyecto)$ claude mcp add --env SAP_TOKEN=$SAP_TOKEN --transport stdio sap-compras -- uv run --with mcp[cli] mcp run /ruta/absoluta/server.py# Servidor remoto compartido con el equipo: se guarda en .mcp.json$ claude mcp add --transport http sap-compras --scope project https://mcp.miempresa.com/mcp$ claude mcp listsap-compras: https://mcp.miempresa.com/mcp (HTTP) - ✔ Connected
Dentro de la sesión, /mcp muestra el estado de cada servidor y sus herramientas.
Los ámbitos se preguntan: local (por defecto, en ~/.claude.json, solo tú y solo ese proyecto), project (en .mcp.json en la raíz del repo, para compartir por control de versiones) y user (en ~/.claude.json, en todos tus proyectos). Un servidor de .mcp.json recién clonado no se conecta solo: Claude Code pide aprobarlo antes.
Camino 2: Agent SDK. Se pasa en la opción mcp_servers de ClaudeAgentOptions, con el mismo formato (command y args para stdio, type: "http" y url para remoto). Sus herramientas se llaman mcp__<servidor>__<herramienta> y se autorizan en allowed_tools, por ejemplo mcp__sap-compras__*. Lo vemos en la lección 7.
Camino 3: Messages API. El conector MCP (beta, cabecera mcp-client-2025-11-20) conecta la API directamente a un servidor remoto sin que escribas un cliente: declaras el servidor en mcp_servers (URL, nombre y authorization_token si hace falta) y lo activas con un mcp_toolset en tools, donde puedes habilitar o deshabilitar herramientas concretas. Dos límites de examen: solo herramientas (ni resources ni prompts) y solo servidores HTTP públicos. Si necesitas un servidor local, resources o prompts, usas el SDK de MCP como cliente y los ayudantes del SDK de Anthropic (pip install "anthropic[mcp]") para convertir sus herramientas al formato de la API.
Camino 4: Apps de Claude. La app de escritorio lee claude_desktop_config.json, y en la web se añaden servidores remotos como conectores. Si tu empresa trabaja con SAP, recuerda que la vía buena es un servidor sobre APIs publicadas o BTP; tienes el contexto en Conexiones y en Claude y SAP.
Seguridad: un servidor MCP es código con tus credenciales
La guía mete MCP también en seguridad. Lo mínimo que tienes que aplicar:
- Secretos fuera del repo. En
.mcp.jsonusa expansión de variables (${SAP_TOKEN}o${VAR:-valor_por_defecto}) y deja el valor en el entorno de cada máquina. Nunca un token literal en un fichero que se commitea. - Mínimo privilegio en el servidor. El usuario técnico con el que el servidor llama a SAP solo puede leer pedidos si la herramienta solo lee. Las herramientas de escritura, separadas y con aprobación.
- Servidores de terceros = código no fiable. Instala solo servidores que conozcas: sus descripciones y resultados entran en el contexto de Claude y pueden llevar instrucciones inyectadas. Lo que devuelve una herramienta es dato, no orden.
- Controla el tamaño. Claude Code avisa cuando la salida de una herramienta MCP pasa de 10.000 tokens y la corta en 25.000 por defecto (
MAX_MCP_OUTPUT_TOKENSpara subirlo). Mejor diseñar herramientas que devuelvan solo lo útil. - Autenticación en remoto. Para servidores HTTP, OAuth o cabeceras con token; el host guarda el token, no el modelo.
Para el examen
Dominio · D8 Tools and MCPs (MCP Server Development y Agentic Customization) · D7 Security
Lo que tienes que dominar
- Host, cliente y servidor: un cliente por servidor dentro del host; mensajes JSON-RPC 2.0.
- Tools las decide el modelo, resources las adjunta la aplicación, prompts los elige el usuario.
- stdio para local (proceso hijo, nada en stdout); Streamable HTTP para compartido y producción; SSE obsoleto.
- Claude Code:
claude mcp add, ámbitos local, project (.mcp.json) y user. - Conector MCP de la API: beta, solo tools, solo servidores HTTP accesibles;
mcp_serversmásmcp_toolset. - Integración reutilizable entre varias aplicaciones y mantenida aparte: servidor MCP.
Donde se suele fallar
- Creer que el conector MCP de la API lanza servidores stdio locales o expone resources y prompts.
- Dejar tokens literales en
.mcp.jsonen lugar de${VAR}. - Pensar que el modelo se conecta al servidor: lo hace el cliente del host.
- Confundir un prompt MCP (plantilla que elige el usuario) con el system prompt.
Checklist para el examen
0 de 6 dominadosMarca lo que ya sabrías responder en el examen.
Ponte a prueba
Tipo test
6 preguntas sobre esta lección. Responde una a una; verás las soluciones al terminar.
Siguiente parada
Próxima lección: Claude Code para desarrollo y automatización. CLAUDE.md y su jerarquía, settings.json y permisos, subagentes, hooks que bloquean acciones destructivas, modo headless y Claude Code en CI.