Conceptos básicos del servidor MCP
8 ejemplos para empezar a crear servidores MCP: 5 básicos y 3 intermedios.
Prerrequisitos
- Python 3.10+ y el SDK oficial de Python para MCP:
pip install mcp. - O Node.js 18+ y el SDK oficial de TypeScript para MCP:
npm install @modelcontextprotocol/sdk. - Un cliente para comunicarse con tu servidor. Claude Desktop, Claude Code o un cliente personalizado creado con el SDK de Agente funcionan para pruebas locales a través de stdio.
- No se requiere ninguna configuración de red para los ejemplos siguientes. Todos se ejecutan a través de stdio, el transporte local estándar para el desarrollo.
Ejemplos básicos
1. Esqueleto mínimo de servidor
El servidor MCP más pequeño posible: crea una instancia y ejecútala a través de stdio.
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("demo-server")
if __name__ == "__main__":
mcp.run(transport="stdio")FastMCPes la clase de servidor de alto nivel en el SDK de Python; se encarga de la conexión y la negociación de capacidades por ti.- La cadena
"demo-server"es el nombre del servidor, que un cliente puede mostrar al listar servidores conectados. mcp.run(transport="stdio")inicia el bucle de eventos y se bloquea, leyendo solicitudes de stdin y escribiendo respuestas en stdout.- Este servidor no tiene herramientas todavía, un cliente puede conectarse y negociar, pero no hay nada que llamar.
2. Registro de una herramienta
Añade una herramienta invocable usando el decorador @mcp.tool().
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("weather-server")
@mcp.tool()
def get_weather(city: str) -> str:
"""Devuelve un resumen meteorológico breve para una ciudad."""
return f"Está soleado en {city}."
if __name__ == "__main__":
mcp.run(transport="stdio")- El decorador registra
get_weatheren el manifiesto de capacidades del servidor, por lo que aparece durante la negociación. - La anotación de tipo (
city: str) se convierte en el esquema de entrada de la herramienta; el cliente la utiliza para saber qué argumentos enviar. - La cadena de documentación se convierte en la descripción de la herramienta, que se muestra al cliente y a Claude al decidir si llamarla.
- Sin el decorador, esto sería solo una función de Python, invisible para cualquier cliente conectado.
3. Registro de un recurso
Expón contenido de solo lectura en una URI usando @mcp.resource().
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("config-server")
@mcp.resource("config://settings")
def get_settings() -> str:
return "theme=dark\ntimezone=UTC"- Los recursos son de solo lectura; un cliente los recupera por URI, no toman argumentos como las herramientas.
- El esquema de URI (
config://) es arbitrario, elige uno que describa lo que representa el recurso. - Usa recursos para datos que un cliente debería poder leer directamente, y herramientas para acciones que realizan trabajo o tienen efectos secundarios.
- Un error común es exponer datos de solo lectura como una herramienta cuando un recurso es más adecuado.
4. Registro de un prompt
Proporciona una plantilla de prompt reutilizable con @mcp.prompt().
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("prompt-server")
@mcp.prompt()
def summarize_request(topic: str) -> str:
return f"Por favor, resume las últimas actualizaciones sobre {topic} en tres puntos clave."- Los prompts son plantillas que el cliente puede recuperar y rellenar, no son datos ni una acción.
- Los argumentos de una función de prompt funcionan igual que los argumentos de las herramientas, definen el esquema de entrada de la plantilla.
- Los prompts son útiles para estandarizar solicitudes comunes en todos los clientes que se conectan a este servidor.
- Un servidor puede mezclar herramientas, recursos y prompts libremente; todos se registran de la misma manera, con un decorador diferente.
5. Ejecución del servidor localmente
Inicia el servidor como un subproceso que un cliente puede lanzar.
python server.py- A través de stdio, el cliente es responsable de iniciar este proceso; rara vez lo ejecutas de forma independiente en producción.
- Durante el desarrollo local, muchos clientes (como Claude Desktop) están configurados para lanzar este comando automáticamente cuando es necesario.
- Si el proceso se cierra inmediatamente, busca una excepción en el momento de la importación. Los errores durante el inicio a menudo parecen un "el servidor no responde" del lado del cliente en lugar de un traceback claro de Python.
- stdio es el transporte adecuado para el desarrollo local en una sola máquina. Múltiples clientes remotos requieren HTTP/SSE en su lugar.
Relacionado: Comparación de despliegue de MCP: stdio vs HTTP/SSE - cuándo ir más allá de stdio
Ejemplos intermedios
6. Un servidor con herramienta, recurso y prompt juntos
Combina los tres tipos de capacidades en un solo servidor, reflejando un despliegue real a pequeña escala.
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("tickets-server")
TICKETS = {"T-1": "Abierto: impresora sin conexión", "T-2": "Cerrado: problema de VPN"}
@mcp.tool()
def get_ticket(ticket_id: str) -> str:
"""Busca un ticket de soporte por ID."""
return TICKETS.get(ticket_id, "Ticket no encontrado.")
@mcp.resource("tickets://open")
def list_open_tickets() -> str:
return "\n".join(k for k, v in TICKETS.items() if v.startswith("Abierto"))
@mcp.prompt()
def triage_prompt(ticket_id: str) -> str:
return f"Revisa el ticket {ticket_id} y sugiere una próxima acción."
if __name__ == "__main__":
mcp.run(transport="stdio")get_ticketrealiza una búsqueda, por lo que es una herramienta.list_open_ticketsson datos de solo lectura, por lo que es un recurso.- Las tres capacidades se registran de forma independiente y aparecen juntas en el manifiesto que un cliente ve durante la negociación.
- Los servidores reales rara vez exponen solo un tipo de capacidad; la mayoría de las integraciones útiles combinan acciones y estado legible.
- Este diccionario
TICKETSen memoria está bien para una demostración; un servidor de producción lo respaldaría con una base de datos real.
7. Equivalente mínimo en TypeScript
El mismo patrón de registro de herramientas usando el SDK oficial de TypeScript.
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const server = new McpServer({ name: "weather-server", version: "1.0.0" });
server.tool(
"get_weather",
{ city: z.string() },
async ({ city }) => ({
content: [{ type: "text", text: `Está soleado en ${city}.` }],
})
);
await server.connect(new StdioServerTransport());McpServerdesempeña el mismo papel queFastMCP, gestiona la conexión y la negociación por ti.- Los esquemas
zoddefinen la forma de entrada de la herramienta, el equivalente en TypeScript de las anotaciones de tipo de Python. server.connect(new StdioServerTransport())es la versión del SDK de TypeScript demcp.run(transport="stdio").- Ambos SDK implementan el mismo protocolo, por lo que un cliente no puede saber si un servidor fue escrito en Python o TypeScript.
Relacionado: Creación de un servidor MCP con el SDK de TypeScript - guía completa del SDK de TypeScript
8. Verificación del ciclo de vida localmente
Una comprobación manual rápida de que tu servidor negocia correctamente antes de integrarlo en un cliente real.
npx @modelcontextprotocol/inspector python server.py- El Inspector MCP es una herramienta de propósito general para conectarse a cualquier servidor local y ejercitar manualmente sus herramientas, recursos y prompts.
- Realiza los mismos pasos de conexión y negociación que haría un cliente real, y luego te permite llamar a herramientas de forma interactiva.
- Ejecutar esto antes de apuntar un cliente real a tu servidor detecta errores de registro de forma temprana; una herramienta que falta en el manifiesto es obvia aquí.
- Esto es solo una ayuda de desarrollo, no forma parte del ciclo de vida de la solicitud en sí, solo una forma de observarlo.
Relacionado: Cómo los servidores MCP manejan las solicitudes - el ciclo de vida que esta inspección está comprobando | Prueba de servidores MCP antes del despliegue - pruebas automatizadas para los mismos manejadores
Versiones de la pila: Escrito contra la línea de modelos de Claude actual a partir de ~junio de 2026: Claude Fable 5, Claude Opus 4.8, Claude Sonnet 5 (el predeterminado) y Claude Haiku 4.5, y los SDK actuales de Python/TypeScript del Protocolo de Contexto de Modelo. Los nombres de los modelos, las versiones de los SDK y la especificación MCP evolucionan rápidamente: verifica los detalles actuales en platform.claude.com/docs y modelcontextprotocol.io antes de confiar en ellos.