Crear un servidor MCP personalizado
Instalar servidores MCP públicos está bien para aprender. Pero el salto útil llega cuando expones tus propias herramientas: buscar en tu documentación, validar un repo, consultar una base interna o crear un informe acotado.
Objetivos de aprendizaje
- Diseñar un servidor MCP mínimo con tools estrechas.
- Separar lógica de negocio, validación y transporte MCP.
- Probarlo antes de conectarlo a Claude Code, Hermes u otro cliente.
En cristiano: servidor MCP custom. Es un pequeño servicio que expone herramientas a una app de IA mediante el protocolo MCP. El agente no recibe acceso total: recibe funciones concretas con argumentos definidos.
Terminal
# Estructura mínima
mcp-debug/
server.py
pyproject.toml
tests/
test_tools.py
# Tool útil:
# run_lint(project_path) -> ejecuta solo comandos permitidos
# search_docs(query) -> busca en una carpeta concreta Idea clave. Tu primera tool debe leer o verificar. No empieces con borrar, publicar, enviar emails o tocar producción.
Terminal
from mcp.server.fastmcp import FastMCP
from pathlib import Path
import subprocess
mcp = FastMCP("aulafy-debug-tools")
ROOT = Path("/Users/me/proyectos").resolve()
def safe_path(path: str) -> Path:
target = Path(path).resolve()
if ROOT not in target.parents and target != ROOT:
raise ValueError("Path fuera del workspace permitido")
return target
@mcp.tool()
def list_markdown_files(path: str) -> list[str]:
base = safe_path(path)
return [str(p.relative_to(base)) for p in base.rglob("*.md")][:100]
@mcp.tool()
def run_lint(path: str) -> str:
base = safe_path(path)
result = subprocess.run(
["npm", "run", "lint"],
cwd=base,
text=True,
capture_output=True,
timeout=120,
)
return result.stdout[-6000:] + result.stderr[-3000:]
if __name__ == "__main__":
mcp.run() Cuidado. Si aceptas `command: string` y lo pasas a una shell, has creado una puerta peligrosa. Usa listas de comandos permitidos, timeouts y rutas validadas.
Checklist antes de conectar un agente
- La tool rechaza rutas fuera del workspace.
- Hay timeout y límite de salida.
- No acepta comandos arbitrarios.
- Registra argumentos, decisión y resultado.
- Tiene pruebas con inputs maliciosos.
Comprueba que funciona. Prueba tres ataques: `../.env`, una ruta inexistente y un repo sin `package.json`. El servidor debe fallar claro y sin filtrar secretos.
Guardar y reabrir el proyecto.
Un MCP custom bueno es aburrido: pocas tools, validación fuerte, logs claros y permisos mínimos. Eso lo hace útil en proyectos reales.