En este artículo
Resumen rápido
Un servidor MCP es un programa que expone herramientas (tools) a Claude Code. Se crea en TypeScript o Python, no necesita servidor web, y se distribuye como paquete npm. En este tutorial construimos un MCP de clima completo desde cero.
Qué es un servidor MCP
Un servidor MCP (Model Context Protocol) es un proceso que expone capacidades a Claude Code. Piensa en él como un plugin: le das a Claude Code acceso a herramientas que no tiene por defecto.
Ejemplo: un MCP de clima permite a Claude Code consultar el tiempo actual. Un MCP de base de datos permite ejecutar queries SQL. Un MCP de Slack permite enviar mensajes.
Los conceptos clave del protocolo:
- Tools: Funciones que Claude Code puede ejecutar. Tienen nombre, descripción, parámetros JSON Schema y una función handler.
- Resources: Datos que Claude Code puede leer. URIs con contenido texto o binario.
- Prompts: Templates de prompts predefinidos que el usuario puede invocar.
Para entender mejor el ecosistema, lee la guía completa de MCP.
Arquitectura: tools, resources, prompts
Un MCP server tiene 3 tipos de capacidades:
Tools (lo más usado)
Las tools son funciones que Claude Code puede llamar. Cada tool tiene:
{
name: "get_weather",
description: "Obtener el clima actual de una ciudad",
inputSchema: {
type: "object",
properties: {
city: { type: "string", description: "Nombre de la ciudad" }
},
required: ["city"]
}
}
Resources
Los resources son datos estáticos o dinámicos que Claude Code puede leer. Ejemplo: un archivo de configuración, una lista de endpoints disponibles, documentación.
Prompts
Templates de prompts que el usuario puede invocar con argumentos. Ejemplo: un prompt "analyze-logs" que recibe un período y genera un análisis estructurado.
Setup del proyecto
# Crear proyecto
mkdir mcp-weather && cd mcp-weather
npm init -y
# Instalar dependencias
npm install @modelcontextprotocol/sdk zod
npm install -D typescript @types/node
# Configurar TypeScript
npx tsc --init --target ES2022 --module Node16 \
--moduleResolution Node16 --outDir dist \
--declaration true
Estructura del proyecto:
mcp-weather/
├── src/
│ └── index.ts # Entry point del servidor
├── package.json
└── tsconfig.json
Tutorial: MCP de clima paso a paso
Construimos un MCP server que consulta el clima actual usando la API gratuita de Open-Meteo (sin API key necesaria).
Paso 1: Crear el servidor
// src/index.ts
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",
version: "1.0.0",
description: "Consulta el clima actual de cualquier ciudad"
});
// Tool: get_weather
server.tool(
"get_weather",
"Obtener el clima actual de una ciudad",
{
city: z.string().describe("Nombre de la ciudad"),
units: z.enum(["celsius", "fahrenheit"])
.default("celsius")
.describe("Unidades de temperatura")
},
async ({ city, units }) => {
// Geocoding: ciudad -> coordenadas
const geoRes = await fetch(
`https://geocoding-api.open-meteo.com/v1/search?name=${encodeURIComponent(city)}&count=1`
);
const geoData = await geoRes.json();
if (!geoData.results?.length) {
return {
content: [{ type: "text", text: `Ciudad "${city}" no encontrada.` }]
};
}
const { latitude, longitude, name } = geoData.results[0];
// Clima actual
const unit = units === "fahrenheit" ? "fahrenheit" : "celsius";
const weatherRes = await fetch(
`https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}¤t=temperature_2m,wind_speed_10m,relative_humidity_2m&temperature_unit=${unit}`
);
const weather = await weatherRes.json();
const current = weather.current;
return {
content: [{
type: "text",
text: `Clima en ${name}: ${current.temperature_2m}°${unit === "celsius" ? "C" : "F"}, viento ${current.wind_speed_10m} km/h, humedad ${current.relative_humidity_2m}%`
}]
};
}
);
// Iniciar servidor
const transport = new StdioServerTransport();
await server.connect(transport);
Paso 2: Configurar package.json
{
"name": "mcp-weather",
"version": "1.0.0",
"type": "module",
"bin": { "mcp-weather": "dist/index.js" },
"scripts": {
"build": "tsc",
"start": "node dist/index.js"
}
}
Paso 3: Build y test
npm run build
Paso 4: Configurar en Claude Code
// ~/.claude/settings.json
{
"mcpServers": {
"weather": {
"command": "node",
"args": ["/ruta/a/mcp-weather/dist/index.js"]
}
}
}
Ahora puedes preguntar a Claude Code: "Qué tiempo hace en Madrid?" y usará tu MCP para responder.
Testing con MCP Inspector
MCP Inspector es una herramienta oficial para probar servers sin Claude Code:
npx @modelcontextprotocol/inspector node dist/index.js
Abre un dashboard web donde puedes:
- Ver todas las tools, resources y prompts registrados
- Ejecutar tools con parámetros de prueba
- Ver los JSON de request/response
- Detectar errores de schema o de ejecución
Publicar en npm
# Build final
npm run build
# Login en npm (primera vez)
npm login
# Publicar
npm publish
Una vez publicado, cualquiera puede usarlo con:
{
"mcpServers": {
"weather": {
"command": "npx",
"args": ["-y", "mcp-weather"]
}
}
}
Alternativa en Python
Si prefieres Python, el SDK oficial también está disponible:
pip install mcp
from mcp.server import Server
from mcp.server.stdio import stdio_server
app = Server("weather")
@app.tool()
async def get_weather(city: str, units: str = "celsius") -> str:
# ... lógica del clima
return f"Clima en {city}: ..."
async def main():
async with stdio_server() as (read, write):
await app.run(read, write)
import asyncio
asyncio.run(main())
El concepto es idéntico. Solo cambia la sintaxis.
Buenas prácticas
- Descripciones claras: Claude Code elige qué tool usar basándose en la descripción. Sé específico.
- Validación con Zod: Usa schemas estrictos para los parámetros. Previene errores.
- Errores informativos: Cuando algo falla, devuelve un mensaje útil, no un stack trace.
- Timeout: Las llamadas a APIs externas deben tener timeout. Claude Code espera pero no indefinidamente.
- Sin estado: Los MCP servers son stateless por defecto. No guardes estado entre llamadas salvo que lo necesites explícitamente.
- Seguridad: Nunca expongas credenciales en las respuestas. Lee seguridad en MCP.
Preguntas frecuentes
En qué lenguaje se crea un servidor MCP?
TypeScript (más popular, mejor docs) o Python. Ambos tienen SDK oficial de Anthropic.
Cuánto tiempo se tarda?
Un MCP básico con 2-3 tools: 1-2 horas. Con tests y publicación npm: medio día.
Necesito un servidor web?
No. Los MCP servers son procesos stdio locales. Sin puerto, dominio ni hosting.
Puedo publicar en npm?
Sí. Es un paquete npm normal. npm publish y listo.
Cómo testeo antes de usar?
Con MCP Inspector: npx @modelcontextprotocol/inspector node dist/index.js
De consumidor a creador de MCP
Aprende MCP desde cero en los módulos gratuitos de IAcademy. Del primer uso a crear tu propio servidor.
Empieza gratisCurso completo: 108 módulos de IA aplicada
11 especializaciones por departamento. Dashboard con progreso. Quizzes y skills desbloqueables. Desde 399 EUR.