Herramientas de IA para Programar

Cómo crear un servidor MCP con Claude Code: guía paso a paso (2026)

20 ago 202614 min de lectura

Construir un servidor MCP con Claude Code significa escribir un pequeño servicio que expone tools/recursos a través del Model Context Protocol y luego conectarlo directamente a Claude Code con claude mcp add. El camino tiene tres pasos: (1) diseñar y escribir tu tool en Python o TypeScript, (2) elegir un transporte (stdio es el predeterminado en local) y (3) conectarlo a Claude Code y probarlo. Hay dos maneras de hacerlo: escribirlo a mano para entender lo que de verdad ocurre, o dejar que Claude Code genere el esqueleto por ti. En esta guía recorro las dos.

· Por Jasmine, una dev que usa Claude Code a diario y que ya escribió a mano y puso en producción algunos servidores MCP internos para mi equipo.

¿Qué es un servidor MCP? (repaso rápido)

Un servidor MCP es un pequeño proceso que expone tres tipos de capacidad——tools (funciones que un agente puede llamar), resources (datos que puede leer) y prompts (plantillas de prompt reutilizables)——a un LLM a través del Model Context Protocol. Dicho de otro modo, es un "adaptador" estandarizado entre Claude Code y el mundo exterior: una API interna, una base de datos, el sistema de archivos o cualquier servicio al que quieras que Claude llegue de forma controlada.

Lo bueno de MCP es que es un estándar abierto: escribes el servidor una vez y lo usas en muchos hosts (Claude Code, Claude Desktop y otros clientes). Esta guía no va a profundizar en el concepto——eso corresponde al artículo qué es MCP. Aquí nos centramos en escribir tu propio servidor y conectarlo directamente a Claude Code, la parte que la documentación oficial suele dejar suelta.

¿Cuándo necesitas de verdad escribir tu propio servidor MCP?

Antes de escribir una sola línea de código, pregúntate: ¿alguien ya escribió este servidor? Muchas necesidades comunes ya tienen servidores oficiales o de la comunidad——GitHub, Playwright, Sentry, sistema de archivos y más. Conectar uno existente siempre es más rápido que construir uno nuevo.

SituaciónQué hacer
Trabajar con GitHub, controlar un navegador, leer errores de SentryUsa un servidor existente——solo claude mcp add
La API interna de tu empresa, que nadie ha envuelto todavíaEscribe tu propio servidor MCP
Una base de datos privada con un schema específicoEscribe el tuyo (controla las queries y los permisos)
Un flujo de trabajo de varios pasos que abarca varios sistemasEscribe el tuyo, empaquetado como un workflow
Solo necesitas leer unos pocos archivos localesUsa el servidor de sistema de archivos existente

Mi regla general: escribe tu propio servidor MCP cuando los datos o la lógica son tuyos y aún no existe un adaptador estándar. No reescribas algo que otras personas ya hacen bien.

Antes de empezar

Una lista de comprobación cortita para que no tropieces a mitad de camino:

  • Claude Code instalado y con la sesión iniciada (un plan Pro/Max o una clave de API, ambos funcionan).
  • Runtime: Node.js 18+ (para TypeScript) o Python 3.10+ (para Python).
  • Elige un SDK: FastMCP / el SDK de Python si te sientes a gusto en Python; el SDK de TypeScript (@modelcontextprotocol/sdk) si vives en Node.
  • Un objetivo concreto: por ejemplo, "una tool que busca un pedido en nuestra API interna." No empieces con un servidor genérico que lo hace todo.

Si Claude Code es nuevo para ti, lee primero qué es Claude Code para entender cómo ejecutar una sesión y conceder permisos.

Opción 1 — Escribir el servidor MCP a mano

Hacerlo manualmente una vez te ayuda a entender lo que realmente ocurre cuando Claude llama a una tool. Después de eso, puedes automatizar con libertad. Los cinco pasos de abajo van del diseño a una prueba que funciona.

Paso 1 — Diseña las tools en torno a flujos de trabajo, no a endpoints

El error más común es mapear cada endpoint REST uno a uno con una tool. El resultado es un agente que tiene que llamar a cinco tools para hacer una sola cosa, y pierde el hilo con facilidad. En su lugar, diseña de forma centrada en el agente:

  • Consolida operaciones por intención: una única tool get_order_summary devuelve todo de una vez, en lugar de obligar al agente a coser get_order + get_customer + get_items.
  • Devuelve una salida que una persona o un agente puedan leer: nombres de campo claros, no códigos internos.
  • Escribe mensajes de error que "enseñen" al agente: informa del error con una pista para arreglarlo, no solo un stack trace.

Estos principios provienen de las buenas prácticas integradas en la skill ak-mcp-builder——la parte que muchos tutoriales genéricos se saltan.

Paso 2 — Genera el esqueleto del proyecto e instala el SDK

Nombra las cosas con claridad para que resulten obvias más adelante: en Python usa {service}_mcp, en TypeScript usa {service}-mcp-server.

Python (FastMCP):

python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install "mcp[cli]" # or: pip install fastmcp
# server.py
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("orders_mcp")

if __name__ == "__main__":
 mcp.run() # defaults to the stdio transport

TypeScript (SDK de MCP):

npm init -y
npm install @modelcontextprotocol/sdk zod
npm install -D typescript @types/node
// src/index.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";

const server = new McpServer({ name: "orders-mcp-server", version: "1.0.0" });

const transport = new StdioServerTransport();
await server.connect(transport);

Paso 3 — Escribe tu primera tool (con un ejemplo ejecutable)

Una buena tool tiene tres partes: un input schema ajustado, una descripción clara (el agente la lee para saber cuándo llamar a la tool) y tool annotations que describen el comportamiento. Aquí tienes una tool de consulta de pedidos:

Python:

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("orders_mcp")

@mcp.tool(
 annotations={
 "readOnlyHint": True, # read-only, does not change data
 "idempotentHint": True, # same result when called again
 "openWorldHint": True, # calls an external system
 }
)
def get_order_summary(order_id: str) -> str:
 """Look up a summary of one order by its order ID.
 Use when the user asks about the status/total/customer of a specific order."""
 order = fetch_order(order_id) # calls your internal API
 if order is None:
 return f"Order '{order_id}' not found. Double-check the ID (format ORD-xxxxx)."
 return (
 f"Order {order['id']} | Customer: {order['customer']} | "
 f"Status: {order['status']} | Total: ${order['total']:,}"
 )

TypeScript (usando Zod para el input schema):

import { z } from "zod";

server.registerTool(
 "get_order_summary",
 {
 description: "Look up a summary of one order by its order ID.",
 inputSchema: { order_id: z.string().describe("Order ID, format ORD-xxxxx") },
 annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: true },
 },
 async ({ order_id }) => {
 const order = await fetchOrder(order_id);
 const text = order
 ? `Order ${order.id} | Customer: ${order.customer} | Status: ${order.status}`
 : `Order '${order_id}' not found.`;
 return { content: [{ type: "text", text }] };
 }
);

Salida de ejemplo cuando Claude llama a la tool: Order ORD-10231 | Customer: Alex Nguyen | Status: In transit | Total: $540. Una advertencia: las annotations son solo pistas para el host, no un mecanismo de seguridad——no confíes en readOnlyHint para bloquear escrituras.

Paso 4 — Elige un transporte (stdio / HTTP / SSE)

El transporte decide cómo habla el host con tu servidor. Elige según la situación en lugar de quedarte con el predeterminado a ciegas:

TransporteÚsalo cuandoVentajas / desventajas
stdioEl servidor corre en local, un cliente (Claude Code en tu máquina)El más simple, sin red · un solo cliente
HTTP (streamable)Servidor remoto, muchos clientes, desplegado en tu propia infraestructuraCompartible, escalable · debes encargarte de auth/OAuth
SSENecesitas enviar eventos en tiempo real (poco a poco reemplazado por streamable HTTP)Bueno para streaming · el enfoque más antiguo

Predeterminado para local + Claude Code: usa stdio. Solo pasa a HTTP cuando necesites compartir el servidor con varias personas o desplegarlo de forma remota.

Paso 5 — Ejecútalo y pruébalo del modo correcto

Aquí es donde mucha gente tropieza——y pocos tutoriales lo advierten:

  • El servidor es un proceso de larga duración. Ejecutar python server.py directamente parecerá que "cuelga" la terminal, porque está esperando entrada por stdio——eso es normal, no un bug. Para una comprobación rápida sin quedarte atascado, usa timeout 5s python server.py, ejecútalo en tmux / en un panel aparte, o usa un harness de eval.
  • Con stdio: nunca hagas log en stdout. stdout es el canal del protocolo——un print() perdido ahí rompe el stream JSON-RPC y el servidor "muere" de forma confusa. Haz log en stderr (Python: print(..., file=sys.stderr) o el módulo logging).
  • Comprueba primero que compila: Python python -m py_compile server.py; TypeScript npm run build.

La forma más fiable de probar es guiada por eval: escribe un script que llame a cada tool con entradas de ejemplo y haga asserts sobre la salida, ejecutándolo en un proceso hijo con un timeout. Así detectas bugs de schema y de protocolo de inmediato, en lugar de esperar a conectarlo a Claude Code y descubrir una tool que no devuelve nada en silencio.

Opción 2 — Deja que Claude Code escriba el servidor MCP por ti

Una vez que entiendes la estructura de la Opción 1, no necesitas volver a teclear boilerplate cada vez. Este es el divertido "ángulo meta": usar el propio Claude Code para escribir un servidor MCP para Claude Code.

Un patrón de prompt que me gusta, dividido en trozos para que el agente no se salga de la tarea:

Write a Python MCP server named orders_mcp using FastMCP.
- Tool get_order_summary(order_id) calls our internal API at BASE_URL (read from env).
- Tight input schema, clear description, readOnlyHint/idempotentHint annotations.
- Log to stderr, NOT stdout. Transport stdio.
Then write a test script that uses timeout so it does not hang, and explain how to wire it into Claude Code.

Claude Code generará el esqueleto del proyecto, escribirá la tool + el schema y, si lo pides, escribirá también el paso de prueba. Tu tarea principal es revisarlo——las partes repetitivas las maneja el agente. Consejo: pídele al agente que declare sus suposiciones (rutas, nombres de variables de entorno) antes de escribir, y haz que ejecute py_compile / npm run build él mismo para confirmar que el código compila ahí mismo en la sesión. Así obtienes un servidor que ya pasó una comprobación básica, en lugar de un montón de código sin probar.

Si construyes muchos servidores, vale la pena usar una skill lista en lugar de recordar cada buena práctica por tu cuenta. El Engineer Kit de AgentKit (la skill ak-mcp-builder) trae un proceso de construcción de servidores MCP en varias fases (research -> implement -> review -> eval) que empaqueta las buenas prácticas de diseño de tools y un harness de eval para probar——así no tienes que llevar en la cabeza todo el boilerplate y las trampas de stdio / larga duración de arriba. Para los detalles, mira qué hay dentro del Engineer Kit de AgentKit.

Una aclaración para evitar confusiones: "AgentKit" aquí es el kit de skills para Claude Code (agentkit.best, la CLI ak), que es distinto del producto "AgentKit" de OpenAI. Mi enfoque: hazlo a mano una vez para entenderlo y luego usa una skill para ganar velocidad.

Conectar el servidor MCP a Claude Code

Ahora que tienes un servidor, conéctalo a Claude Code. El comando central es claude mcp add.

Servidor stdio local——pasa el comando después del separador --:

claude mcp add orders -- python /path/to/server.py
# or a built TypeScript server:
claude mcp add orders -- node /path/to/dist/index.js

Servidor remoto (HTTP):

claude mcp add orders --transport http https://mcp.company.com/orders

Comprueba la conexión:

claude mcp list # shows: orders ✔ Connected
claude mcp get orders # view a server's full configuration

El alcance decide dónde está disponible el servidor: local (solo tú, solo en este proyecto), project (commiteado para todo el equipo), user (todos tus proyectos). Para un servidor compartido por el equipo, escribe a mano un .mcp.json en la raíz del repositorio y haz commit:

{
 "mcpServers": {
 "orders": {
 "command": "python",
 "args": ["server.py"],
 "env": { "BASE_URL": "https://api.internal.company.com" }
 }
 }
}

Después de editar el .mcp.json, acuérdate de reiniciar la sesión de Claude Code para que lo recargue.

Problemas comunes y cómo solucionarlos

SíntomaCausa comúnSolución
Failed to connectComando/ruta/URL incorrectosEjecuta claude mcp get <name> para inspeccionar; prueba el comando por separado
El servidor "muere" justo al arrancarLog en stdout, rompiendo el protocolo stdioMueve todo el log a stderr
Las tools no aparecen en ClaudeFalta una variable de entorno / clave de APIPásala con --env KEY=value o decláralas en .mcp.json
Timeout en la primera ejecución (npx descargando un paquete)La descarga de la dependencia tarda más que el timeout predeterminadoDefine MCP_TIMEOUT=60000 al arrancar
Edité el .mcp.json pero no cambió nadaLa sesión no recargó la configuraciónReinicia la sesión de Claude Code

Buenas prácticas para escribir servidores MCP

Cerrando con lo que vale la pena recordar (buena parte sacada de ak-mcp-builder):

  • Nombra las tools con el patrón {service}_{action}_{resource} (snake_case), con un prefijo de servicio para evitar colisiones cuando hay varios servidores conectados.
  • Soporta tanto JSON como Markdown en la salida——los agentes leen bien los datos estructurados, las personas leen la versión en Markdown con más facilidad.
  • Pagina las tools que devuelven muchos datos: usa limit, has_more, next_offset en lugar de devolver miles de filas.
  • Limita la longitud de la salida (regla general ~25.000 caracteres) y trunca con orientación ("N resultados más, usa offset...").
  • Haz que los mensajes de error sean accionables: di exactamente qué salió mal y cómo arreglarlo.
  • Seguridad: valida la entrada, mantén las claves de API en el entorno (nunca las hardcodees) y no filtres errores internos / stack traces al agente. Recuerda que las annotations son solo pistas, no un sustituto de un control de acceso real.

¿Quieres automatizar más tu flujo de desarrollo? Mira cómo crear una skill personalizada para Claude Code y usar subagents en Claude Code para repartir el trabajo de build/prueba.

Preguntas frecuentes (FAQ)

¿En qué lenguaje debería escribir un servidor MCP?

Las opciones más comunes son Python (FastMCP / SDK de Python) y TypeScript (@modelcontextprotocol/sdk). MCP tiene SDKs para otros lenguajes también, pero para Claude Code, Python o TS son las opciones más rápidas y con más ejemplos.

¿En qué se diferencia esto de conectarse a un servidor existente?

Conectarse a un servidor existente solo necesita claude mcp add apuntando a uno que otra persona ya escribió. Escribir tu propio servidor es para cuando necesitas exponer tu propia lógica/datos (una API interna, una BD) para los que nadie ha construido todavía un adaptador.

¿Puede Claude Code escribir un servidor MCP por sí mismo?

Sí. Describe la tool, el schema y el transporte que quieres, y Claude Code generará el esqueleto del proyecto, escribirá la tool e incluso un script de prueba. Tú solo lo revisas. La skill ak-mcp-builder empaqueta este proceso junto con las buenas prácticas.

¿Cómo despliego un servidor remoto (HTTP)?

Ejecuta el servidor con el transporte streamable HTTP en tu propia infraestructura y luego claude mcp add <name> --transport http <url>. Un servidor remoto necesita encargarse también de la autenticación (OAuth/token)——a diferencia de un servidor stdio local, que confía en tu máquina.

¿Necesito Claude Code Pro?

No se exige ningún plan específico. MCP funciona con Claude Code en cuanto inicias sesión——un plan Pro/Max o una clave de API, ambos funcionan. Escribir un servidor no cuesta nada más allá del uso del modelo que ya estás pagando.

¿Qué es ak-mcp-builder y es obligatorio?

ak-mcp-builder es una skill del Engineer Kit de AgentKit que construye servidores MCP mediante un proceso de varias fases con un harness de eval. No es obligatorio——puedes escribirlo todo a mano como en la Opción 1. Solo hace las cosas más rápidas y te ayuda a evitar las trampas de buenas prácticas cuando construyes muchos servidores.

Conclusión y próximos pasos

Para recapitular, hay dos maneras de crear un servidor MCP con Claude Code: escribirlo a mano (diseñar las tools en torno a flujos -> instalar el SDK -> escribir la tool -> elegir un transporte -> probar con timeout/stderr) para entenderlo a fondo, y dejar que Claude Code lo escriba por ti cuando necesitas velocidad. En cualquier caso, lo esencial es conectarlo a Claude Code con claude mcp add o .mcp.json y confirmar ✔ Connected. Mi consejo: hazlo a mano una vez para entenderlo y luego automatiza.

Como siguiente paso, prueba a convertir este proceso de construcción en tu propia skill personalizada. Y si quieres un proceso de construcción de servidores MCP estandarizado y listo para eval desde el primer momento, echa un vistazo al Engineer Kit de AgentKit — 20% de descuento, ahora $79.20 (la skill ak-mcp-builder).

Fuentes: Model Context Protocol - especificación y guía para construir un servidor (versión 2026-07-28); documentación de Claude Code - MCP y claude mcp add (v2.1.219). Verifica los comandos exactos antes de usarlos, ya que la CLI se actualiza rápidamente.

J

Jasmine

Autora · Jasmine Daily

La autora detrás de Jasmine Daily, anotando pensamientos, experiencias y momentos cotidianos. Honesta, sin prisa, imperfecta.

Jasmine Daily

Hay más esperando a ser leído.

Si este texto te llegó, explora algunas páginas más del diario.

Leer a continuación

Entradas relacionadas