Cómo crear tu propio servidor MCP desde cero

Por Ricardo Gutierrez · · 22 min lectura

En este artículo

  1. Qué es un servidor MCP
  2. Arquitectura: tools, resources, prompts
  3. Setup del proyecto
  4. Tutorial: MCP de clima paso a paso
  5. Testing con MCP Inspector
  6. Publicar en npm
  7. Alternativa en Python
  8. Buenas prácticas
  9. Preguntas frecuentes

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.

Guía principal: Este artículo forma parte de la MCP: guía completa.

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:

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:

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

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 gratis

Curso completo: 108 módulos de IA aplicada

11 especializaciones por departamento. Dashboard con progreso. Quizzes y skills desbloqueables. Desde 399 EUR.

Ver precios Acceder al portal