FastMCP: La guía completa para crear servidores y clientes de MCP

FastMCP: La guía completa para crear servidores y clientes de MCP

Un completo tutorial sobre FastMCP 2.0, la forma rápida y "pythónica" de construir servidores y clientes basados en el Protocolo de Contexto del Modelo (MCP). Aprende a crear herramientas, recursos e instrucciones para tus aplicaciones LLM.

Lección 6 2025-07-03 07:21

Integración de FastMCP con el IDE Cursor

Integración de FastMCP con Cursor IDE

Cursor IDE ofrece un excelente soporte para servidores del Protocolo de Contexto de Modelo (MCP), lo que permite integrar sin problemas sus servidores FastMCP directamente en su flujo de trabajo de desarrollo. Esta guía le acompañará a través de la configuración y el uso de servidores FastMCP con Cursor.

¿Qué es MCP en Cursor?

Model Context Protocol (MCP) es un protocolo para conectar Cursor a herramientas y fuentes de datos externas. En lugar de explicar la estructura de su proyecto repetidamente, puede integrarse directamente con sus herramientas.

Cursor admite servidores MCP escritos en cualquier lenguaje que pueda imprimir en stdout o servir un punto final HTTP, lo que hace que FastMCP (Python) sea una opción perfecta.

¿Por qué usar FastMCP con Cursor?

La simplicidad y las potentes características de FastMCP lo hacen ideal para la integración con Cursor:

  • Desarrollo Rápido: Cree servidores MCP con mínimos preparativos.
  • Herramientas Completas: Cree herramientas sofisticadas con seguridad de tipo.
  • Acceso a Recursos: Proporcione datos contextuales a su asistente de IA.
  • Fácil Despliegue: Múltiples opciones de transporte para diferentes casos de uso.

Métodos de Transporte

Cursor admite tres métodos de transporte para servidores MCP:

Transporte Ejecución Despliegue Usuarios Entrada Autenticación
stdio Local Cursor gestiona Usuario único Comando de shell Manual
SSE Local/Remoto Despliegue como servidor Múltiples usuarios URL a punto final SSE OAuth
HTTP en streaming Local/Remoto Despliegue como servidor Múltiples usuarios URL a punto final HTTP OAuth

Para los servidores FastMCP, nos centraremos en el método stdio para el desarrollo y las pruebas locales.

Configuración de FastMCP con Cursor

Paso 1: Cree su servidor FastMCP

Primero, crearemos un servidor FastMCP simple que proporcione herramientas de desarrollo:

# cursor_dev_tools.py
import asyncio
import subprocess
from pathlib import Path
from fastmcp import FastMCP

# Crear el servidor MCP
mcp = FastMCP("Herramientas de Desarrollo de Cursor")

@mcp.tool()
def get_project_structure(max_depth: int = 2) -> str:
    """Obtiene la estructura del proyecto actual hasta la profundidad especificada."""
    try:
        result = subprocess.run(
            ["find", ".", "-type", "f", "-name", "*.py", "-o", "-name", "*.js", "-o", "-name", "*.ts", "-o", "-name", "*.json"],
            capture_output=True,
            text=True,
            cwd="."
        )
        files = result.stdout.strip().split('\n')

        # Organizar por directorio
        structure = {}
        for file in files:
            if file:
                parts = Path(file).parts
                current = structure
                for part in parts[:-1]:
                    if part not in current:
                        current[part] = {}
                    current = current[part]
                current[parts[-1]] = "file"

        return f"Estructura del Proyecto:\n{_format_structure(structure)}"
    except Exception as e:
        return f"Error al obtener la estructura del proyecto: {str(e)}"

def _format_structure(structure, indent=0):
    """Formatea el diccionario de estructura como un árbol."""
    result = []
    for key, value in structure.items():
        prefix = "  " * indent + "├── "
        if isinstance(value, dict):
            result.append(f"{prefix}{key}/")
            result.append(_format_structure(value, indent + 1))
        else:
            result.append(f"{prefix}{key}")
    return "\n".join(result)

@mcp.tool()
def run_command(command: str, working_dir: str = ".") -> str:
    """Ejecuta un comando de shell en el directorio especificado."""
    try:
        result = subprocess.run(
            command,
            shell=True,
            capture_output=True,
            text=True,
            cwd=working_dir,
            timeout=30
        )

        output = []
        if result.stdout:
            output.append(f"STDOUT:\n{result.stdout}")
        if result.stderr:
            output.append(f"STDERR:\n{result.stderr}")

        output.append(f"Código de retorno: {result.returncode}")
        return "\n\n".join(output)

    except subprocess.TimeoutExpired:
        return "El comando expiró después de 30 segundos"
    except Exception as e:
        return f"Error al ejecutar el comando: {str(e)}"

@mcp.tool()
def search_code(pattern: str, file_extension: str = "py") -> str:
    """Busca patrones de código en los archivos del proyecto."""
    try:
        result = subprocess.run(
            ["grep", "-r", "--include", f"*.{file_extension}", pattern, "."],
            capture_output=True,
            text=True
        )

        if result.returncode == 0:
            return f"Coincidencias encontradas para '{pattern}':\n\n{result.stdout}"
        else:
            return f"No se encontraron coincidencias para el patrón '{pattern}' en archivos *.{file_extension}"

    except Exception as e:
        return f"Error al buscar código: {str(e)}"

@mcp.resource("file://project-docs")
async def get_project_docs():
    """Proporciona documentación del proyecto y archivos README."""
    docs = []

    # Buscar archivos de documentación comunes
    doc_files = ["README.md", "README.rst", "docs/README.md", "CONTRIBUTING.md"]

    for doc_file in doc_files:
        path = Path(doc_file)
        if path.exists():
            try:
                content = path.read_text()
                docs.append(f"=== {doc_file} ===\n{content}\n")
            except Exception as e:
                docs.append(f"=== {doc_file} ===\nError al leer el archivo: {str(e)}\n")

    if not docs:
        docs.append("No se encontraron archivos de documentación en la raíz del proyecto.")

    return "\n".join(docs)

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

Paso 2: Configurar MCP en Cursor

Tienes dos opciones de configuración:

Opción A: Configuración específica del proyecto

Cree .cursor/mcp.json en la raíz de su proyecto:

{
  "mcpServers": {
    "fastmcp-dev-tools": {
      "command": "python",
      "args": ["cursor_dev_tools.py"],
      "env": {}
    }
  }
}

Opción B: Configuración global

Cree ~/.cursor/mcp.json en su directorio personal para acceso global:

{
  "mcpServers": {
    "fastmcp-dev-tools": {
      "command": "python",
      "args": ["/path/to/your/cursor_dev_tools.py"],
      "env": {}
    }
  }
}

Paso 3: Uso de variables de entorno

Para servidores que necesitan claves API o configuración:

{
  "mcpServers": {
    "fastmcp-api-server": {
      "command": "python",
      "args": ["api_server.py"],
      "env": {
        "API_KEY": "your-api-key-here",
        "DEBUG": "true"
      }
    }
  }
}

Uso de herramientas MCP en Cursor

Uso automático de herramientas

El Agente Compositor de Cursor utiliza automáticamente las herramientas MCP listadas en "Herramientas disponibles" cuando son relevantes. Sus herramientas FastMCP aparecerán en la interfaz de chat.

Invocación manual de herramientas

También puedes pedir herramientas específicas por su nombre: - "Usa la herramienta get_project_structure para mostrarme la estructura del proyecto". - "Ejecuta la herramienta search_code para encontrar todas las funciones asíncronas". - "Ejecuta run_command para instalar dependencias".

Aprobación y ejecución automática de herramientas

Por defecto, Cursor pide aprobación antes de usar herramientas MCP. Puedes:

  1. Aprobación manual: Haz clic en la flecha junto a los nombres de las herramientas para ver los argumentos y aprobar.
  2. Modo de ejecución automática: Habilita el "modo Yolo" para la ejecución automática de herramientas sin aprobación.

Características avanzadas de FastMCP para Cursor

Devolución de imágenes

Los servidores FastMCP pueden devolver imágenes que Cursor mostrará en el chat:

import base64
from fastmcp import FastMCP

mcp = FastMCP("Generador de Imágenes")

@mcp.tool()
def generate_diagram() -> dict:
    """Genera un diagrama simple y lo devuelve como imagen."""
    # Crea o genera tu imagen
    with open("diagram.png", "rb") as f:
        image_data = base64.b64encode(f.read()).decode()

    return {
        "content": [
            {
                "type": "image",
                "data": image_data,
                "mimeType": "image/png"
            }
        ]
    }

Proveedores de recursos complejos

Utilice el sistema de recursos de FastMCP para proporcionar datos contextuales enriquecidos:

@mcp.resource("file://git-status")
async def get_git_status():
    """Proporciona el estado actual del repositorio git."""
    try:
        # Obtener el estado de git
        status_result = subprocess.run(
            ["git", "status", "--porcelain"],
            capture_output=True,
            text=True
        )

        # Obtener los commits recientes
        log_result = subprocess.run(
            ["git", "log", "--oneline", "-10"],
            capture_output=True,
            text=True
        )

        return f"Estado de Git:\n{status_result.stdout}\n\nCommits Recientes:\n{log_result.stdout}"

    except Exception as e:
        return f"Error al obtener el estado de git: {str(e)}"

Depuración y solución de problemas

Visualización de registros MCP

Para depurar problemas del servidor MCP en Cursor:

  1. Abra el panel de Salida (⌘⇧U en Mac, Ctrl+Shift+U en Windows/Linux).
  2. Seleccione "Registros MCP" del menú desplegable.
  3. Busque errores de conexión, problemas de autenticación o fallas del servidor.

Problemas comunes

El servidor no arranca - Verifique que Python y su script estén en la ruta correcta. - Verifique la sintaxis de la configuración mcp.json. - Asegúrese de que todas las dependencias estén instaladas.

Las herramientas no aparecen - Reinicie Cursor después de los cambios de configuración. - Revise los registros MCP en busca de mensajes de error. - Verifique que su servidor FastMCP se ejecute correctamente desde la línea de comandos.

Errores de permiso - Asegúrese de que el script de Python tenga permisos de ejecución. - Verifique que Cursor tenga acceso a los directorios especificados.

Probando su servidor

Pruebe su servidor FastMCP de forma independiente:

# Ejecute su servidor directamente
python cursor_dev_tools.py

# Pruebe con las herramientas cliente de MCP
npx @modelcontextprotocol/inspector cursor_dev_tools.py

Mejores Prácticas de Seguridad

Al usar servidores FastMCP con Cursor:

  1. Verificar Fuentes: Use solo servidores MCP de desarrolladores de confianza.
  2. Revisar Código: Audite el código del servidor antes de la instalación, especialmente para proyectos sensibles.
  3. Limitar Permisos: Use claves API restringidas con los permisos mínimos requeridos.
  4. Variables de Entorno: Almacene secretos en variables de entorno, nunca los codifique directamente.
  5. Desarrollo Local: Use el transporte stdio para trabajo de desarrollo sensible.

Ejemplos del mundo real

Integración con el flujo de trabajo de desarrollo

# Servidor de herramientas de desarrollo mejorado
from fastmcp import FastMCP
import subprocess
import json

mcp = FastMCP("Herramientas de desarrollo avanzadas")

@mcp.tool()
def run_tests(test_pattern: str = "") -> str:
    """Ejecuta las pruebas del proyecto con filtrado de patrones opcional."""
    cmd = ["python", "-m", "pytest"]
    if test_pattern:
        cmd.extend(["-k", test_pattern])

    result = subprocess.run(cmd, capture_output=True, text=True)
    return f"Resultados de las pruebas:\n{result.stdout}\n{result.stderr}"

@mcp.tool()
def format_code() -> str:
    """Formatea el código Python usando black."""
    result = subprocess.run(
        ["black", ".", "--check", "--diff"],
        capture_output=True,
        text=True
    )

    if result.returncode == 0:
        return "El código ya está formateado correctamente"
    else:
        return f"Sugerencias de formato de código:\n{result.stdout}"

@mcp.tool()
def check_dependencies() -> str:
    """Verifica las dependencias del paquete obsoletas."""
    result = subprocess.run(
        ["pip", "list", "--outdated", "--format", "json"],
        capture_output=True,
        text=True
    )

    try:
        outdated = json.loads(result.stdout)
        if outdated:
            output = "Paquetes obsoletos:\n"
            for pkg in outdated:
                output += f"- {pkg['name']}: {pkg['version']} -> {pkg['latest_version']}\n"
            return output
        else:
            return "¡Todos los paquetes están actualizados!"
    except:
        return "Error al verificar las dependencias"

Herramientas de integración API

@mcp.tool()
def fetch_api_docs(api_url: str) -> str:
    """Obtiene la documentación de la API desde los puntos finales de OpenAPI/Swagger."""
    import requests

    try:
        response = requests.get(f"{api_url}/openapi.json", timeout=10)
        if response.status_code == 200:
            api_spec = response.json()
            return f"Documentación de la API para {api_url}:\n{json.dumps(api_spec, indent=2)}"
        else:
            return f"No se pudo obtener la documentación de la API: HTTP {response.status_code}"
    except Exception as e:
        return f"Error al obtener la documentación de la API: {str(e)}"

Próximos Pasos

Ahora que tiene FastMCP integrado con Cursor:

  1. Explore las herramientas disponibles: Consulte el directorio de herramientas MCP para servidores preconstruidos.
  2. Cree herramientas personalizadas: Cree herramientas específicas para su dominio para su flujo de trabajo de desarrollo.
  3. Comparta sus servidores: Considere publicar servidores FastMCP útiles para la comunidad.
  4. Despliegue en producción: Pase a transporte SSE o HTTP para la colaboración en equipo.

La combinación de la facilidad de desarrollo de FastMCP y la potente integración MCP de Cursor crea una experiencia de desarrollo asistida por IA sin interrupciones. ¡Empiece a construir herramientas que entiendan su base de código y flujo de trabajo específicos!

Preguntas frecuentes sobre solución de problemas

P: Mi servidor FastMCP no aparece en la lista de herramientas de Cursor R: Verifique que la sintaxis de su mcp.json sea correcta y reinicie Cursor. Verifique que el servidor se ejecute de forma independiente con python your_server.py.

P: Las herramientas se están llamando pero devuelven errores R: Revise los registros MCP en el panel de Salida de Cursor. Los problemas comunes incluyen dependencias faltantes o directorios de trabajo incorrectos.

P: ¿Cómo puedo deshabilitar un servidor temporalmente? R: Vaya a Configuración (⌘⇧J) → Funciones → Protocolo de Contexto del Modelo (MCP) y desactive el servidor sin eliminar la configuración.

P: ¿Puedo usar FastMCP con instalaciones remotas de Cursor? R: Para el desarrollo remoto, considere implementar su servidor FastMCP con transporte SSE o HTTP en lugar de stdio.

Con FastMCP y Cursor, ahora tiene una potente plataforma para crear herramientas de desarrollo asistidas por IA que comprenden sus necesidades y base de código específicas.