Modal MCP

Un servidor MCP para gestionar aplicaciones, contenedores, volúmenes y secretos de Modal. También ayuda a desplegar y ejecutar aplicaciones de Modal directamente desde Claude Code y otros clientes MCP.

Documentación

Servidor MCP Modal

mcp-modal MCP server

PyPI

Un servidor MCP para gestionar Modal — aplicaciones, contenedores, volúmenes y secretos — y para desplegar y ejecutar aplicaciones Modal directamente desde Claude Code y otros clientes MCP.

Cada herramienta invoca tu CLI local de modal, por lo que opera con el perfil y las credenciales de Modal configurados en tu máquina. No hay tokens adicionales que gestionar.

Instalación

El servidor está publicado en PyPI como mcp-modal. No se necesita instalación manual — la forma recomendada de ejecutarlo es con uvx, que lo descarga y lo lanza bajo demanda. Solo tienes que apuntar tu cliente MCP al comando siguiente (consulta Configuración).

Iniciar sesión en Modal

Este servidor utiliza tus credenciales locales de Modal. Si aún no te has autenticado, ejecuta:

modal setup

Esto abre un navegador para iniciar sesión y guarda un token en ~/.modal.toml. ¿Ya has iniciado sesión en otro lugar? Compruébalo con modal profile current.

Configuración

Añade el servidor a Claude Code con la CLI de claude mcp:

claude mcp add mcp-modal -- uvx mcp-modal

O añádelo a un archivo .mcp.json en la raíz de tu proyecto:

{
  "mcpServers": {
    "mcp-modal": {
      "command": "uvx",
      "args": ["mcp-modal"]
    }
  }
}

Para fijar una versión específica, usa uvx mcp-modal@0.2.0.

Requisitos

  • Python 3.11 o superior
  • uv (proporciona uvx)
  • CLI de Modal 1.x configurada con credenciales válidas (modal setup)
  • Para el soporte de despliegue y ejecución de Modal:
    • El proyecto que se va a desplegar/ejecutar debe usar uv para la gestión de dependencias
    • modal debe estar instalado en el entorno virtual de ese proyecto

Seguridad

Este servidor invoca tu CLI local de modal usando las credenciales que haya en ~/.modal.toml. Algunas herramientas son potentes por diseño — si el cliente MCP que controla el servidor sufre una inyección de prompt (por ejemplo, mediante texto malicioso dentro de los registros que obtiene), estas son las vías de escalada y deben permanecer detrás de los avisos de aprobación de herramientas de tu cliente en lugar de estar aprobadas automáticamente:

  • deploy_modal_app / run_modal_app — ejecutan Python local arbitrario en el host (modal deploy importa el archivo de la aplicación; uv run resuelve e instala las dependencias del proyecto de destino).
  • put_modal_volume_file — puede leer cualquier archivo local (p. ej. ~/.ssh/id_rsa, ~/.modal.toml) y subirlo a un volumen en la nube (una primitiva de exfiltración de datos).
  • get_modal_volume_file con force=True — puede sobrescribir cualquier ruta local (p. ej. ~/.zshrc o un perfil de shell, una primitiva de persistencia).
  • exec_modal_container — ejecuta comandos arbitrarios dentro de un contenedor, por diseño.

Lista de permitidos de rutas locales opcional

Para contener las dos herramientas de volúmenes que tocan el sistema de archivos, establece la variable de entorno MCP_MODAL_ALLOWED_LOCAL_PATHS a una lista os.pathsep-separada de directorios (: en macOS/Linux). Cuando está establecida, put_modal_volume_file (su local_path) y get_modal_volume_file (su local_destination) se rechazan a menos que la ruta resuelta — después de expandir ~ y colapsar ../enlaces simbólicos — caiga dentro de una de esas raíces. El destino de descarga "-" (flujo a stdout) está exento porque no se escribe nada en el disco.

Cuando la variable está sin establecer (el valor predeterminado) no hay restricción, por lo que las configuraciones existentes no se ven afectadas. Configúrala en tu cliente MCP, p. ej.:

{
  "mcpServers": {
    "mcp-modal": {
      "command": "uvx",
      "args": ["mcp-modal"],
      "env": { "MCP_MODAL_ALLOWED_LOCAL_PATHS": "/Users/me/modal-workspace:/tmp/modal" }
    }
  }
}

Todas las herramientas también pasan nombres/rutas proporcionados por el usuario después de un separador de fin de opciones --, por lo que un valor que comienza con - siempre se trata como datos, nunca como una bandera de CLI de modal. Los valores de secretos entregados a create_modal_secret se redactan del comando mostrado, los registros y cualquier salida de error.

Herramientas compatibles

26 herramientas, agrupadas por área. Las herramientas con ámbito de cuenta aceptan un argumento opcional env para apuntar a un entorno de Modal específico; si se omite, usan el valor predeterminado del perfil (o MODAL_ENVIRONMENT).

Despliegue y ejecución

  1. Desplegar aplicación Modal (deploy_modal_app)

    • Despliega una aplicación Modal (modal deploy). Los endpoints web desplegados persisten, por lo que cualquier enlace en la salida está activo y se puede compartir (devueltos en urls).
    • Parámetros: absolute_path_to_app (obligatorio), env, name, tag, strategy (rolling/recreate), stream_logs
    • El directorio de la aplicación debe usar uv con modal instalado en su virtualenv.
  2. Ejecutar aplicación Modal (run_modal_app)

    • Ejecuta una función o punto de entrada local una vez y transmite su salida (modal run).
    • Parámetros: absolute_path_to_app (obligatorio), function_name, env, detach, timeout_seconds (predeterminado 120)
    • Devuelve una instantánea con truncated: true si la ejecución aún continúa al alcanzar el tiempo de espera. Pasa detach=True para mantener trabajos largos activos en Modal más allá del tiempo de espera.

¿Por qué no hay una herramienta modal serve? modal serve solo mantiene sus endpoints activos mientras el proceso de bloqueo se ejecuta — una herramienta MCP que devuelve los derribaría inmediatamente, entregando una URL muerta. Usa deploy_modal_app para un endpoint persistente y compartible.

Aplicaciones

  1. Listar aplicaciones Modal (list_modal_apps)

    • Lista las aplicaciones actualmente desplegadas/ejecutándose o detenidas recientemente. Úsalo para encontrar el nombre/ID de la aplicación para las otras herramientas de aplicaciones.
    • Parámetros: env
  2. Obtener registros de aplicación Modal (get_modal_app_logs)

    • Obtiene o transmite registros de una aplicación por nombre o ID (modal app logs).
    • Parámetros: app_identifier (obligatorio), timeout_seconds (predeterminado 30), env, since, until, tail, search, source (stdout/stderr/system), timestamps (prefija cada línea con su hora de pared), follow
    • Con follow=True, los registros se transmiten hasta que la aplicación se detiene o se alcanza timeout_seconds, devolviendo una instantánea con truncated: true.
    • Solo cubre los flujos de stdout/stderr/sistema; algunos fallos (p. ej. un bloqueo informado como "... salió con ...") son eventos del panel de Modal, no líneas de registro, y no aparecerán aquí.
  3. Detener aplicación Modal (stop_modal_app)

    • Detiene permanentemente una aplicación y termina sus contenedores (modal app stop).
    • Parámetros: app_identifier (obligatorio), env
  4. Revertir aplicación Modal (rollback_modal_app)

    • Redespliega una versión anterior de una aplicación (modal app rollback).
    • Parámetros: app_identifier (obligatorio), version (opcional — predeterminado a la versión anterior), env
  5. Obtener historial de aplicación Modal (get_modal_app_history)

    • Devuelve el historial de despliegue de una aplicación (modal app history). Úsalo para encontrar un version para la reversión.
    • Parámetros: app_identifier (obligatorio), env

Contenedores

  1. Listar contenedores Modal (list_modal_containers)

    • Lista los contenedores actualmente en ejecución (modal container list).
    • Parámetros: app_id (filtro opcional), env
  2. Obtener registros de contenedor Modal (get_modal_container_logs)

    • Obtiene o transmite registros para un ID de contenedor (modal container logs).
    • Parámetros: container_id (obligatorio), timeout_seconds (predeterminado 30), since, until, tail, search, source, timestamps, follow
    • Misma advertencia de solo stdout/stderr/sistema que la herramienta de registros de aplicaciones anterior.
  3. Ejecutar en contenedor Modal (exec_modal_container)

    • Ejecuta un comando dentro de un contenedor en ejecución (modal container exec --no-pty).
    • Parámetros: container_id (obligatorio), command (lista de argumentos, p. ej. ["python", "-c", "print('hi')"]), timeout_seconds (predeterminado 60)
  4. Detener contenedor Modal (stop_modal_container)

    • Termina un contenedor en ejecución (modal container stop).
    • Parámetros: container_id (obligatorio)

Búsqueda de registros

  1. Buscar registros Modal (search_modal_logs)
    • Busca en los registros de una aplicación o contenedor un patrón y devuelve cada coincidencia con las líneas circundantes — diseñado para depurar "¿dónde salió mal?". Los registros se obtienen una vez y se buscan localmente, por lo que (a diferencia del argumento search en las herramientas de registros) obtienes contexto, expresiones regulares, control de mayúsculas y recuentos de coincidencias, no solo la línea coincidente desnuda.
    • Parámetros: identifier (obligatorio — nombre/ID de aplicación o ID de contenedor), pattern (obligatorio), target (app/container, predeterminado app), regex, case_sensitive, context_lines (predeterminado 3), max_matches (predeterminado 50), since, tail (predeterminado a las últimas 1000 entradas), source (stdout/stderr/system), exclude (elimina líneas de ruido antes de buscar, p. ej. "queue put failed"), timestamps (predeterminado true — lleva la hora de pared de cada línea al resultado), timeout_seconds, env
    • Devuelve match_count y matches: bloques de contexto con marca de tiempo y número de línea donde las líneas coincidentes están prefijadas con >, p. ej. > 8: 2026-06-04T... ValueError: bad input. Informa excluded_lines cuando se usa exclude.
    • Solo busca los flujos de stdout/stderr/sistema; los fallos emitidos como eventos del panel de Modal (p. ej. "... salió con ...") devuelven 0 coincidencias incluso cuando el fallo es real.

Volúmenes — Archivos

  1. Listar volúmenes Modal (list_modal_volumes) — lista todos los volúmenes. Parámetros: ninguno.
  2. Listar contenido del volumen (list_modal_volume_contents) — volume_name, path (predeterminado /). Establece empty: true con un mensaje cuando el listado genuinamente no devuelve nada, para que un directorio vacío sea distinguible de un error o una ruta incorrecta.
  3. Copiar archivos (copy_modal_volume_files) — volume_name, paths (el último es el destino).
  4. Eliminar archivo (remove_modal_volume_file) — volume_name, remote_path, recursive.
  5. Subir archivo (put_modal_volume_file) — volume_name, local_path, remote_path, force.
  6. Descargar archivo (get_modal_volume_file) — volume_name, remote_path, local_destination, force. Usa - como destino para transmitir el contenido a stdout.

Volúmenes — Ciclo de vida

  1. Crear volumen (create_modal_volume) — crea un volumen persistente con nombre. Parámetros: volume_name, env.
  2. Eliminar volumen (delete_modal_volume) — elimina un volumen y todos sus datos (irreversible). Parámetros: volume_name, env.
  3. Renombrar volumen (rename_modal_volume) — Parámetros: old_name, new_name, env.

Secretos

  1. Listar secretos (list_modal_secrets)

    • Lista los secretos publicados (solo nombres y marcas de tiempo — los valores nunca se exponen).
    • Parámetros: env
  2. Crear secreto (create_modal_secret)

    • Crea un secreto a partir de pares clave/valor en línea o un archivo local (modal secret create). Los valores de los secretos se redactan del command devuelto.
    • Parámetros: secret_name (obligatorio), key_values (dict), from_dotenv (ruta), from_json (ruta), force, env. Proporciona al menos uno de key_values, from_dotenv o from_json.
  3. Eliminar secreto (delete_modal_secret) — Parámetros: secret_name, env.

Descubrimiento

  1. Obtener perfil Modal (get_modal_profile)

    • Muestra el perfil activo y todos los perfiles configurados. Úsalo para confirmar en qué espacio de trabajo/cuenta está autenticado el servidor. Parámetros: ninguno.
  2. Listar entornos Modal (list_modal_environments)

    • Lista los entornos en el espacio de trabajo actual; los nombres son argumentos env válidos para las otras herramientas. Parámetros: ninguno.

Formato de respuesta

Todos los tools devuelven respuestas en un formato estandarizado, con ligeras variaciones según el tipo de operación:

# JSON / list operations (apps, containers, volumes, secrets, history, ...):
{
    "success": True,
    "apps": [...]   # or "containers", "volumes", "secrets", "history", "environments"
}

# Action operations (deploy, stop, create, delete, rename, copy, put, get, rm):
{
    "success": True,
    "message": "Operation successful message",
    "command": "executed command string",
    "stdout": "command output",  # if any
    "stderr": "error output"     # if any
}

# Log / run / exec operations (snapshot-based):
{
    "success": True,
    "logs": "...",          # or "output" for run/exec
    "truncated": False,     # True when cut off at timeout_seconds
    "command": "executed command string"
}

# Error case (all operations):
{
    "success": False,
    "error": "Error message describing what went wrong",
    "command": "executed command string",
    "stdout": "command output",  # if available
    "stderr": "error output"     # if available
}

Licencia

Este proyecto está licenciado bajo la Licencia MIT; consulta el archivo LICENSE para más detalles.