FRENES

MCP y automatización

Crear su propio servidor MCP en 30 minutos

Por · · 6 min

Manos sobre un teclado frente a un editor de código desenfocado, junto a un cuaderno con un esquema de conexiones

Puede crear un servidor MCP con unas treinta líneas de Python y el SDK oficial: usted escribe funciones con anotaciones de tipo, y el SDK deduce el esquema de los parámetros y gestiona el protocolo. Calcule 30 minutos para tener un primer servidor con dos herramientas y un recurso, probarlo en Inspector y conectarlo a Claude, Cursor o VS Code. Este tutorial utiliza la versión 2 del SDK de Python, publicada el 28 de julio de 2026 (v2.3.0 a fecha del 2 de octubre de 2026).

Qué va a construir

Un servidor «Notes» que dará a su asistente de IA acceso de solo lectura a una carpeta de notas en Markdown:

  • una herramienta chercher_notes que devuelve las notas que contienen una palabra;
  • una herramienta lire_note que devuelve el contenido de una nota;
  • un recurso notes://liste con la lista de archivos.

Elegir el acceso de solo lectura tiene un motivo: es la regla básica para un primer servidor. Una herramienta que escribe, elimina o envía algo puede activarse por error, o por una inyección de prompt oculta en un documento que el agente haya leído.

Si estos términos son nuevos para usted, el artículo Servidor MCP: qué es y qué servidores conviene conocer explica los conceptos básicos. También encontrará la definición de servidor MCP en el glosario.

Requisitos previos

  • Python 3.11 o una versión posterior, como exige el SDK v2.
  • uv, el gestor de paquetes de Python recomendado por la documentación del SDK. También puede usar pip.
  • Una aplicación anfitriona compatible con MCP para la prueba final: Claude Desktop, Claude Code, Cursor o VS Code con GitHub Copilot.
  • Una carpeta con algunos archivos .md para hacer las pruebas.

Los tres componentes de un servidor MCP

La documentación del SDK de Python los distingue según quién decide utilizarlos:

ComponenteQuién lo activaEquivalente webEjemplo
Herramienta (tool)El modeloPetición POST: actúa y puede modificar datosBuscar en una base de datos, crear un ticket
Recurso (resource)La aplicación anfitrionaPetición GET: lee sin modificar nadaEl contenido de un archivo
PromptEl usuarioComando guardadoUn comando «/resumir»

El servidor nunca se comunica directamente con el modelo: el cliente MCP, integrado en la aplicación anfitriona, es quien le transmite las llamadas.

Paso 1: crear el proyecto

uv init serveur-notes
cd serveur-notes
uv add "mcp[cli]"

La opción [cli] instala el comando mcp (mcp dev, mcp run, mcp install), además del SDK. Si utiliza pip: pip install "mcp[cli]".

Paso 2: escribir el servidor

Cree el archivo server.py:

from pathlib import Path

from mcp.server import MCPServer
from mcp.server.mcpserver.exceptions import ToolError

# Carpeta expuesta en modo de solo lectura. No se puede acceder a nada fuera de ella.
NOTES = Path.home() / "notes"

mcp = MCPServer("Notes")


def _fichier(nom: str) -> Path:
    """Chemin d'une note, refusé s'il sort du dossier NOTES."""
    chemin = (NOTES / nom).resolve()
    if not chemin.is_relative_to(NOTES.resolve()) or chemin.suffix != ".md":
        raise ToolError(f"Note refusée : {nom!r}")
    if not chemin.is_file():
        raise ToolError(f"Aucune note nommée {nom!r}")
    return chemin


@mcp.tool()
def chercher_notes(mot: str) -> list[str]:
    """Liste les notes Markdown qui contiennent ce mot (sans tenir compte des majuscules)."""
    mot = mot.lower()
    return sorted(
        f.name for f in NOTES.glob("*.md")
        if mot in f.read_text(encoding="utf-8", errors="ignore").lower()
    )


@mcp.tool()
def lire_note(nom: str) -> str:
    """Renvoie le contenu complet d'une note, par exemple « reunion-lundi.md »."""
    return _fichier(nom).read_text(encoding="utf-8", errors="ignore")


@mcp.resource("notes://liste")
def liste() -> str:
    """Toutes les notes disponibles, une par ligne."""
    return "\n".join(sorted(f.name for f in NOTES.glob("*.md")))


if __name__ == "__main__":
    mcp.run()

Conviene fijarse en tres puntos:

  1. Las anotaciones de tipo definen el esquema. Basta con mot: str: el SDK genera el esquema JSON que el cliente muestra al modelo. Usted no tiene que escribir la validación ni el análisis de las peticiones.
  2. La docstring es la descripción que lee el modelo para elegir la herramienta. Redáctela con cuidado: de ella depende que el modelo invoque la herramienta en el momento adecuado.
  3. _fichier impide salir de la carpeta. Sin esta comprobación, un nombre como ../.ssh/id_rsa permitiría leer cualquier archivo de su cuenta. Es el fallo más frecuente de los servidores que acceden al disco.

Si viene de la versión 1 del SDK, tenga en cuenta que FastMCP ahora se llama MCPServer y que la importación mcp.server.fastmcp ya no existe. La guía de migración recoge los demás cambios.

Paso 3: probarlo en Inspector

uv run mcp dev server.py

El comando inicia MCP Inspector y muestra una dirección local que debe abrir en el navegador. Compruebe lo siguiente:

  • En la pestaña Tools, chercher_notes y lire_note aparecen con su descripción y un campo de entrada.
  • Al llamar a lire_note con ../secret.md, recibe el error «Note refusée».
  • En la pestaña Resources, notes://liste devuelve la lista de sus archivos.

Pruebe siempre el servidor por separado antes de conectarlo: aquí resulta mucho más fácil interpretar un error que a través de una aplicación anfitriona.

Paso 4: conectarlo a su asistente

Todas las aplicaciones anfitrionas siguen el mismo procedimiento: ejecutan el servidor como un proceso y se comunican con él mediante la entrada y la salida estándar, con el transporte stdio. Por tanto, basta con indicarles el comando de inicio, siempre con una ruta absoluta:

uv run --with "mcp[cli]" mcp run /chemin/absolu/vers/server.py

Claude Desktop — el SDK escribe la configuración por usted:

uv run mcp install server.py

Cierre Claude Desktop por completo, no solo la ventana, y vuelva a abrirlo.

Claude Code — basta con un comando:

claude mcp add notes -- uv run --with "mcp[cli]" mcp run /chemin/absolu/vers/server.py

Escriba /mcp en una sesión para comprobar que notes está conectado.

Cursor — archivo .cursor/mcp.json en la raíz del proyecto:

{
  "mcpServers": {
    "notes": {
      "command": "uv",
      "args": ["run", "--with", "mcp[cli]", "mcp", "run", "/chemin/absolu/vers/server.py"]
    }
  }
}

VS Code — archivo .vscode/mcp.json; la clave es servers y cada entrada declara su tipo:

{
  "servers": {
    "notes": {
      "type": "stdio",
      "command": "uv",
      "args": ["run", "--with", "mcp[cli]", "mcp", "run", "/chemin/absolu/vers/server.py"]
    }
  }
}

Estos comandos y archivos proceden de la página Connect to a real host de la documentación oficial. Para instalar un servidor ya existente, en lugar de uno propio, consulte Instalar un servidor MCP en Claude, ChatGPT o Cursor.

Paso 5: probarlo con una tarea real

Pídale a su asistente: «Busque en mis notas qué se decidió sobre el presupuesto y resúmalo». Debería llamar a chercher_notes con «presupuesto» y después a lire_note para leer los archivos encontrados. También debería pedirle autorización antes de cada llamada si su aplicación anfitriona está configurada para ello. Mantenga activada esta confirmación hasta haber observado el comportamiento del servidor durante varios días.

Problemas frecuentes

SíntomaCausa probableSolución
El servidor no aparece en la aplicación anfitrionaSe ha indicado una ruta relativa a server.pyUtilice la ruta absoluta y reinicie la aplicación
La aplicación anfitriona muestra «command not found: uv»La aplicación inicia el servidor con un PATH mínimoSustituya uv por su ruta absoluta (which uv o where uv)
Nada cambia después de modificar la configuraciónLa aplicación lee su configuración al iniciarseCierre la aplicación por completo y vuelva a abrirla
El servidor falla en la primera llamadaUn print() escribe en la salida estándar, reservada al protocolo cuando se usa stdioEnvíe los registros a la salida de error (sys.stderr) o utilice logging
ImportError: mcp.server.fastmcpEl código se escribió para el SDK v1Cambie la importación a from mcp.server import MCPServer

Ejecute también el comando de inicio manualmente: un servidor stdio que funciona correctamente no muestra nada y queda a la espera. Una traza de error o un cierre inmediato revelan el problema de fondo.

Para seguir avanzando

  • Compartirlo: uv run mcp run server.py --transport streamable-http publica el mismo servidor por HTTP en http://localhost:8000/mcp. Antes de exponerlo a Internet, añada autenticación —el SDK admite OAuth— y limite las acciones que puede realizar cada herramienta.
  • Probarlo automáticamente: el SDK proporciona un Client que se conecta directamente al objeto mcp en memoria, sin procesos ni puertos. Resulta práctico para las pruebas con pytest.
  • Publicarlo: el registro oficial de MCP incluye servidores públicos; nuestro directorio de servidores MCP los recoge junto con la actividad de sus repositorios y un nivel de riesgo.
  • Elegir uno en lugar de programarlo: quizá ya exista un servidor para lo que necesita. La guía Elegir un servidor MCP explica cómo comprobar que sigue recibiendo mantenimiento y que es seguro. El artículo MCP y skills maliciosos: qué revisar antes de instalar detalla los riesgos que conviene detectar.

Lista de comprobación antes de usarlo a diario

  • El servidor funciona por separado (mcp dev) y cada herramienta tiene una docstring clara
  • Las rutas, direcciones o consultas aceptadas se limitan a lo estrictamente necesario
  • Ninguna herramienta elimina, envía ni realiza pagos sin confirmación humana
  • No hay ningún secreto, como una clave de API o una contraseña, escrito en server.py: se proporcionan mediante variables de entorno
  • La ruta a server.py en la configuración de la aplicación anfitriona es absoluta
  • Ha completado el diagnóstico de seguridad de agentes de IA para revisar toda su configuración

Preguntas frecuentes

¿Hay que saber programar para crear un servidor MCP?

Necesita conocer los fundamentos de Python o TypeScript: escribir una función, instalar un paquete y ejecutar un script. El SDK oficial se encarga del protocolo, del esquema de los parámetros y de la validación: bastan unas treinta líneas para crear un servidor útil.

¿Python o TypeScript para un servidor MCP?

Ambos SDK son oficiales y los mantiene el proyecto Model Context Protocol. Elija el lenguaje de la herramienta que quiera exponer: Python para scripts de datos o automatización, y TypeScript si su código actual está en Node.js. El protocolo es el mismo; el cliente no percibe ninguna diferencia.

¿Pueden otras personas utilizar mi servidor MCP?

En local, con el transporte stdio, solo lo ejecuta su equipo. Para compartirlo, publique el mismo código mediante Streamable HTTP en una dirección web, con autenticación. El SDK proporciona el transporte, pero el alojamiento, el control de acceso y la seguridad siguen siendo responsabilidad suya.

¿Qué diferencia hay entre una herramienta y un recurso MCP?

Una herramienta es una función que el modelo decide invocar para realizar una acción o buscar información, como una petición POST. Un recurso es un dato que la aplicación carga en el contexto del modelo sin efectos secundarios, como una petición GET. Un tercer tipo, el prompt, es una plantilla de mensaje que el usuario activa por su nombre.

En la misma sección

Neutralidad. Ningún enlace de afiliación. Ningún editor paga por ser evaluado, puntuado o clasificado. Las evaluaciones las dirige François Chollet, neutrales y factuales, y cada dato está fechado y con su fuente. Cómo puntuamos