MCP3 min de lectura
Crea tu propio servidor MCP en Python, paso a paso
Tutorial para crear un servidor MCP sencillo con el SDK oficial de Python, probarlo con MCP Inspector y conectarlo a Claude Desktop y Claude Code.
En resumen
- Prepara el proyecto. Instala uv, crea el proyecto y añade el SDK con uv add "mcp[cli]".
- Escribe el servidor. Crea un MCPServer y define cada herramienta como una función con @mcp.tool().
- Pruébalo con Inspector. Ejecuta npx @modelcontextprotocol/inspector para llamar a las herramientas a mano.
- Conéctalo. Añádelo a Claude Desktop en su archivo de configuración o a Claude Code con claude mcp add.
- Úsalo y mejóralo. Pide tareas en lenguaje natural y afina las descripciones de las herramientas.
Un servidor MCP es un pequeño programa que ofrece herramientas a cualquier aplicación de IA compatible: Claude, Claude Code, Cursor, ChatGPT y muchas más. Crear el tuyo es sorprendentemente sencillo. En este tutorial haremos un servidor de notas: el asistente podrá guardar notas y buscarlas en un archivo de tu ordenador.
Necesitas Python 3.10 o superior y algo de soltura con la terminal.
Paso 1: prepara el proyecto
La guía oficial usa uv, un gestor de proyectos de Python muy rápido:
# instalar uv (macOS y Linux)
curl -LsSf https://astral.sh/uv/install.sh | sh
uv init notas
cd notas
uv venv
source .venv/bin/activate
uv add "mcp[cli]"
En Windows, instala uv con powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex" y activa el entorno con .venv\Scripts\activate.
Paso 2: escribe el servidor
Crea notas.py:
from pathlib import Path
from mcp.server import MCPServer
mcp = MCPServer("notas")
ARCHIVO = Path.home() / "notas-mcp.txt"
@mcp.tool()
def guardar_nota(texto: str) -> str:
"""Guarda una nota de texto. Úsala cuando el usuario pida apuntar o recordar algo.
Args:
texto: El contenido de la nota.
"""
with ARCHIVO.open("a", encoding="utf-8") as f:
f.write(texto.replace("\n", " ") + "\n")
return "Nota guardada."
@mcp.tool()
def buscar_notas(palabra: str) -> str:
"""Busca notas guardadas que contengan una palabra.
Args:
palabra: Palabra o texto que buscar (no distingue mayúsculas).
"""
if not ARCHIVO.exists():
return "Todavía no hay notas."
halladas = [l.strip() for l in ARCHIVO.read_text(encoding="utf-8").splitlines() if palabra.lower() in l.lower()]
return "\n".join(halladas) or "No hay notas con esa palabra."
if __name__ == "__main__":
mcp.run(transport="stdio")
Tres detalles importan:
- El docstring es la descripción que verá el modelo. Explica qué hace la herramienta y cuándo usarla.
- Los tipos (
texto: str) se convierten en el esquema de parámetros. - Con transporte
stdio, no usesprint(): la salida estándar es el canal de comunicación con la app. Para registrar mensajes, usalogging, que escribe en la salida de errores.
Paso 3: pruébalo con MCP Inspector
Antes de conectarlo a nada, prueba las herramientas a mano con el Inspector oficial (necesita Node.js):
npx @modelcontextprotocol/inspector uv run notas.py
Se abre una interfaz en el navegador desde la que puedes ver las herramientas y llamarlas con los argumentos que quieras. Si algo falla aquí, fallará también en Claude.
Paso 4: conéctalo
En Claude Desktop, edita el archivo de configuración (en macOS, ~/Library/Application Support/Claude/claude_desktop_config.json; en Windows, %AppData%\Claude\claude_desktop_config.json):
{
"mcpServers": {
"notas": {
"command": "uv",
"args": ["--directory", "/RUTA/ABSOLUTA/A/notas", "run", "notas.py"]
}
}
}
Reinicia la app. En Claude Code, desde cualquier carpeta:
claude mcp add --transport stdio notas -- uv --directory /RUTA/ABSOLUTA/A/notas run notas.py
Usa siempre la ruta absoluta.
Paso 5: úsalo
Pide en lenguaje natural: «apunta que el lunes tengo dentista a las 10» y después «¿qué notas tengo sobre el dentista?». El asistente decidirá qué herramienta usar y te pedirá permiso antes de ejecutarla.
Si no elige bien, mejora las descripciones de las herramientas: es la palanca más importante. Lo explicamos en patrones de diseño de agentes.
Antes de compartirlo
- Valida las entradas: nunca ejecutes comandos ni rutas que vengan del modelo sin comprobarlas.
- Permisos mínimos: que el servidor solo pueda tocar lo que necesita, como aquí un único archivo.
- Secretos fuera del código: claves y tokens en variables de entorno.
- Lee las buenas prácticas de seguridad de MCP y nuestra guía de seguridad de agentes.
Preguntas frecuentes
¿Qué versión del SDK necesito?
La guía oficial actual usa Python 3.10 o superior y el SDK de MCP para Python 2.0 o superior, que expone la clase MCPServer. Tutoriales antiguos usan FastMCP, que corresponde a versiones anteriores.
¿Puedo hacerlo en TypeScript?
Sí, hay un SDK oficial de TypeScript con la misma idea. La guía oficial tiene la versión de cada lenguaje.


