Documentación del conector MCP

Resumen

Qué es el servidor MCP, dónde está, cómo se autentica y todo lo que puede hacer.

Qué es MCP

El Model Context Protocol permite que un asistente de IA llame a herramientas reales en lugar de adivinar. Apunta un cliente al servidor MCP de Static.app y tu asistente podrá listar tus sitios, editar archivos y publicar un ZIP en lenguaje natural, con tu propia clave de API.

Todo lo que hace el servidor pasa por la API REST de Static.app, así que una acción MCP y una llamada a la API tienen exactamente los mismos efectos y permisos.

Incluido en todos los planes. Cualquier cuenta de Static.app, incluida la prueba de 7 días, puede crear una clave de API y conectarse. Los límites del plan se aplican a lo que crees. Consulta Precios. ¿Primera vez con MCP? Consulta qué hace el conector MCP de Static.app.

Endpoint

Un servidor alojado, transporte Streamable HTTP, JSON-RPC 2.0, según la especificación de MCP (2025-03-26).

POST https://mcp.static.app/mcp
EndpointMétodoFinalidad
/mcpPOST / GET / DELETEStreamable HTTP. POST envía JSON-RPC, GET abre un flujo de eventos opcional y DELETE cierra la sesión.
/uploadPOST / PUTPrepara un ZIP fuera de banda. Consulta Subida de archivos.
/sse + /messageGET / POSTTransporte SSE antiguo (2024-11-05), que se mantiene para los clientes configurados antes de que existiera /mcp. Solo con clave de API.

Autenticación

El servidor es multiusuario: no guarda credenciales propias, así que cada cliente trae las suyas. En /mcp hay dos formas de entrar:

  • Inicio de sesión OAuth. Los clientes que lo admiten (Claude, Claude Code, Codex, Cursor, VS Code, Gemini CLI) siguen el 401 del servidor hasta un inicio de sesión de Static.app, y tú haces clic en Authorize. No hay clave que copiar. Revoca el acceso cuando quieras en Cuenta → API / MCP.
  • Clave de API. Para los clientes que no pueden iniciar sesión y para el endpoint antiguo /sse. Crea una en Cuenta → API / MCP. Las claves empiezan por sk_.

Pasa la clave en una de estas dos cabeceras:

MétodoValorNotas
Cabecera AuthorizationAuthorization: Bearer sk_xxxxRecomendada.
Cabecera personalizadaX-API-Key: sk_xxxxPara clientes que no pueden establecer Authorization.
Mantén la clave en privado. Da acceso completo a tu cuenta. No la subas nunca al repositorio: guárdala en una variable de entorno y haz referencia a ella desde la configuración del cliente.

Todas las herramientas

Las herramientas se dividen en cuatro grupos. Todas se ejecutan en nuestros servidores y ninguna puede ver archivos de tu ordenador, así que el contenido viaja como argumentos o a través del endpoint de subida.

HerramientaGrupoQué hace
list_sitesSitiosLista todos los sitios de la cuenta.
get_siteSitiosObtiene un sitio por su PID.
get_site_filesSitiosLista los archivos de un sitio.
create_site_from_archiveSitiosCrea un sitio a partir de un ZIP.
update_site_from_archiveSitiosSustituye el contenido de un sitio con un ZIP.
download_site_archiveSitiosObtiene un enlace de descarga de todo el sitio.
download_site_filesSitiosObtiene un enlace de descarga de archivos seleccionados.
delete_siteSitiosElimina un sitio.
write_site_filesArchivosCrea o sustituye archivos a partir de contenido enviado en la propia llamada.
read_site_fileArchivosLee un archivo.
delete_site_filesArchivosElimina archivos o directorios.
create_uploadSubida de archivosReserva una URL de subida de un solo uso para un ZIP o un archivo suelto.
list_formsFormulariosLista los formularios de un sitio.
get_formFormulariosObtiene un formulario.
get_form_entriesFormulariosLista los envíos.
delete_form_entryFormulariosElimina un envío.

Identificador de sitio (pid)

Toda herramienta que toca un sitio recibe su identificador público de 10 caracteres, p. ej. 0aw4jtby1z, nunca el ID numérico de la base de datos. Ejecuta list_sites para ver los PID de tu cuenta.

Configuración

Conecta un cliente en un par de minutos. Todas las configuraciones de abajo apuntan al mismo endpoint, https://mcp.static.app/mcp, y solo cambian en cómo quiere escribirlo cada cliente. Los clientes que admiten OAuth abren un inicio de sesión de Static.app y no necesitan clave; el resto envía una clave de API en una cabecera.

Claude Code

Un solo comando añade el servidor para todos tus proyectos. Después ejecuta /mcp en Claude Code, elige static-app e inicia sesión en Static.app en tu navegador:

claude mcp add --transport http --scope user static-app https://mcp.static.app/mcp

Para usar una clave de API en lugar de iniciar sesión, guárdala en una variable de entorno y pásala como cabecera:

export STATIC_API_KEY=sk_xxxx
claude mcp add --transport http --scope user static-app https://mcp.static.app/mcp \
    --header "Authorization: Bearer $STATIC_API_KEY"

O añade al repositorio del proyecto un archivo .mcp.json. Con la cabecera, la clave se lee del entorno de cada persona, así que nunca llega al repositorio; sin la cabecera, cada persona inicia sesión:

{
    "mcpServers": {
        "static-app": {
            "type": "http",
            "url": "https://mcp.static.app/mcp",
            "headers": { "Authorization": "Bearer ${STATIC_API_KEY}" }
        }
    }
}

Claude Desktop

Claude Desktop añade el servidor como conector personalizado, sin archivo de configuración y sin clave. Abre Settings → Connectors, haz clic en Add custom connector, pega la URL y deja vacía la configuración avanzada (Advanced settings):

https://mcp.static.app/mcp

Claude abre un inicio de sesión de Static.app; haz clic en Authorize y ya estás conectado. El mismo conector funciona después en claude.ai y en la app móvil de Claude. En los planes Team y Enterprise, primero un Owner lo añade para la organización y luego cada persona se conecta.

Codex

Añade esto a ~/.codex/config.toml y luego inicia sesión desde la terminal con codex mcp login static-app:

[mcp_servers.static-app]
url = "https://mcp.static.app/mcp"

Para usar una clave de API en su lugar, léela de tu entorno:

[mcp_servers.static-app]
url = "https://mcp.static.app/mcp"
bearer_token_env_var = "STATIC_API_KEY"

Cursor

Añade esto a ~/.cursor/mcp.json para todos los proyectos, o a .cursor/mcp.json en un solo proyecto. Sin headers, Cursor abre un inicio de sesión de Static.app; con ellas, la clave se lee de tu entorno:

{
    "mcpServers": {
        "static-app": {
            "url": "https://mcp.static.app/mcp",
            "headers": { "Authorization": "Bearer ${env:STATIC_API_KEY}" }
        }
    }
}

Devin Desktop (antes Windsurf)

Añade esto a ~/.config/devin/mcp_config.json (en Windows, %APPDATA%\devin\mcp_config.json) y reinicia Devin Desktop. La primera vez que se conecta abre un inicio de sesión de Static.app:

{
    "mcpServers": {
        "static-app": {
            "url": "https://mcp.static.app/mcp",
            "transport": "http"
        }
    }
}

n8n y clientes personalizados

En n8n, añade un nodo MCP Client Tool a tu AI Agent, define Endpoint como https://mcp.static.app/mcp, deja Server Transport en HTTP Streamable y elige Bearer Auth con tu clave de API.

Cualquier otro cliente que hable MCP sobre Streamable HTTP funciona con la misma URL. Si admite OAuth, inicia sesión con Static.app; si no, envía la cabecera Authorization en cada petición, y listará las herramientas del índice de herramientas al conectarse.

¿Vas a crear el tuyo? Cada llamada es un POST de JSON-RPC a /mcp. initialize responde con una cabecera Mcp-Session-Id; devuélvela en cada petición posterior.

curl -i https://mcp.static.app/mcp \
    -H "Authorization: Bearer sk_xxxx" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json, text/event-stream" \
    -d '{
        "jsonrpc": "2.0",
        "id": 1,
        "method": "initialize",
        "params": {
            "protocolVersion": "2025-03-26",
            "capabilities": {},
            "clientInfo": { "name": "curl", "version": "1.0" }
        }
    }'

# HTTP/2 200
# mcp-session-id: mcp-session-f5df9141-...
Clientes antiguos. Un cliente que solo habla el transporte SSE antiguo todavía puede conectarse a https://mcp.static.app/sse con una clave de API (ahí no hay OAuth). Si tu cliente no puede usar ninguno de los dos, usa directamente la API REST . Ofrece las mismas funciones sin sesión.

Comprobar la conexión

Pide al asistente que liste tus sitios. Si las herramientas están bien conectadas, llamará a list_sites y responderá con dominios reales. Para comprobarlo a mano, confirma la sesión de antes y luego llama a una herramienta en ella:

curl https://mcp.static.app/mcp \
    -H "Authorization: Bearer sk_xxxx" \
    -H "Mcp-Session-Id: YOUR_SESSION_ID" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json, text/event-stream" \
    -d '{ "jsonrpc": "2.0", "method": "notifications/initialized" }'

curl https://mcp.static.app/mcp \
    -H "Authorization: Bearer sk_xxxx" \
    -H "Mcp-Session-Id: YOUR_SESSION_ID" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json, text/event-stream" \
    -d '{
        "jsonrpc": "2.0",
        "id": 2,
        "method": "tools/call",
        "params": { "name": "list_sites", "arguments": {} }
    }'

El resultado llega en la respuesta a ese POST.

Herramientas de sitios

Lista, inspecciona, publica y elimina sitios. Todas reciben el pid del sitio, no su ID numérico.

list_sites

Devuelve todos los sitios del espacio de trabajo activo.

TOOL list_sites

Argumentos

NombreTipoObligatorioDescripción
Sin argumentos.

Resultado de ejemplo

[
    {
        "pid": "xxxxxxxxxx",
        "slug": "example-site",
        "name": "Example Site",
        "domain": "example.staticdomains.app",
        "status": true,
        "full_url": "https://example.staticdomains.app",
        "created_at": "2025-01-15T10:00:00Z",
        "updated_at": "2025-02-01T12:30:00Z"
    }
]

Pregunta a tu asistente

"Show me all my Static.app sites."

get_site

Devuelve un sitio.

TOOL get_site

Argumentos

NombreTipoObligatorioDescripción
pidstringobligatorioIdentificador público, p. ej. 0aw4jtby1z.

get_site_files

Lista los archivos y directorios de un sitio, de forma recursiva desde la raíz.

TOOL get_site_files

Argumentos

NombreTipoObligatorioDescripción
pidstringobligatorioIdentificador público del sitio.

Resultado de ejemplo

{
    "status": "success",
    "current_path": "",
    "files": [
        { "name": "index.html", "path": "index.html", "is_dir": false, "size": 1234, "type": "html", "hash": "0123456789abcdef0123456789abcdef" },
        { "name": "images", "path": "images", "is_dir": true, "size": null, "type": "directory", "hash": null }
    ]
}

create_site_from_archive

Crea un sitio nuevo a partir de un archivo ZIP. Indica exactamente una fuente de archivo. Se prueban en el orden de abajo. El servidor no puede leer archivos de tu ordenador, así que el archivo llega a través de create_upload o desde una URL pública.

TOOL create_site_from_archive

Argumentos

NombreTipoObligatorioDescripción
upload_idstringopcionalPreferida. ID de create_upload una vez que el ZIP se ha enviado con PUT a su URL.
archive_urlstringopcionalURL desde la que descargar el ZIP.
archive_base64stringopcionalAlternativa heredada. Consulta Base64 (heredado).
namestringopcionalSubdominio deseado, p. ej. my-site. Si no, se genera uno aleatorio.

Resultado de ejemplo

{
    "status": "success",
    "pid": "xxxxxxxxxx",
    "slug": "my-site",
    "url": "https://my-site.staticdomains.app"
}

update_site_from_archive

Sustituye el contenido de un sitio con un ZIP nuevo. Para cambiar unos pocos archivos en lugar de todo el sitio, usa write_site_files.

TOOL update_site_from_archive

Argumentos

NombreTipoObligatorioDescripción
pidstringobligatorioSitio que actualizar.
upload_idstringopcionalPreferida. ID de create_upload.
archive_urlstringopcionalURL desde la que descargar el ZIP.
archive_base64stringopcionalAlternativa heredada.

download_site_archive

Empaqueta todo el sitio y devuelve un enlace de descarga.

TOOL download_site_archive

Argumentos

NombreTipoObligatorioDescripción
pidstringobligatorioSitio que descargar.

Resultado de ejemplo

{
    "status": "success",
    "url": "https://static.app/storage/zip/abcdef0123456789_download.zip"
}

download_site_files

Empaqueta los archivos seleccionados y devuelve un enlace de descarga.

TOOL download_site_files

Argumentos

NombreTipoObligatorioDescripción
pidstringobligatorioSitio del que descargar.
filesstringobligatorioMatriz JSON de rutas, p. ej. ["index.html", "css/style.css"].

delete_site

Elimina un sitio y todo lo que contiene. No se puede deshacer.

TOOL delete_site

Argumentos

NombreTipoObligatorioDescripción
pidstringobligatorioSitio que eliminar.

Herramientas de archivos

Lee, escribe y elimina archivos individuales sin volver a publicar todo el sitio.

write_site_files

Crea o reemplaza archivos concretos y deja intacto el resto del sitio. Envía el texto en la propia llamada; para imágenes y otros binarios, prepara el archivo con create_upload y pasa su upload_id. Los archivos que todavía no existen se crean, y las carpetas que faltan se crean por el camino.

TOOL write_site_files

Argumentos

NombreTipoObligatorioDescripción
pidstringobligatorioSitio en el que escribir.
filesstringobligatorioMatriz JSON de {path, content, encoding} o {path, upload_id}. Hasta 200 entradas, como máximo 20 con upload_id.
create_onlybooleanopcionalFalla con 409 en lugar de sobrescribir un archivo existente. Por defecto es false. No se puede combinar con upload_id.

Campos de la entrada de archivo

CampoTipoObligatorioDescripción
pathstringobligatorioRelativa a la raíz del sitio, p. ej. css/style.css. Se rechazan las rutas que salen del sitio.
contentstringuno de los dosEl contenido del archivo. Máx. 200 MB.
upload_idstringuno de los dosID de create_upload, una vez que el archivo se ha enviado con PUT a su URL. No cuesta tokens, sea cual sea su tamaño.
encodingstringopcionalPara content. "text" (por defecto) lo envía tal cual; "base64" es para binarios muy pequeños, ya que cada byte cuesta tokens.

Argumentos de ejemplo

{
    "pid": "xxxxxxxxxx",
    "files": "[{\"path\": \"index.html\", \"content\": \"<!doctype html><h1>Hello</h1>\"}, {\"path\": \"img/logo.png\", \"upload_id\": \"0e9837a760c5062279ea57107d8f0a1c\"}]"
}

Resultado de ejemplo

{
    "status": "success",
    "written": 2,
    "files": [
        { "name": "index.html", "path": "index.html", "size": 34, "hash": "0123456789abcdef0123456789abcdef" },
        { "name": "logo.png", "path": "img/logo.png", "size": 2048, "hash": "89abcdef0123456789abcdef01234567" }
    ],
    "errors": []
}
El contenido de texto viaja tal cual, así que HTML, CSS y JS no tienen sobrecarga de codificación. Los binarios van por upload_id; si se rechaza parte de un lote, los archivos preparados se quedan donde están para que puedas reintentarlo.

Errores

CódigoCuándo
409Se indicó create_only y todos los archivos ya existen.
422No se pudo escribir nada: extensión no admitida, ruta no válida o base64 incorrecto.

Pregunta a tu asistente

"Add a privacy.html page to site xxxxxxxxxx with a short placeholder policy."

"Change the heading colour in css/style.css on site xxxxxxxxxx to #6551E0."

read_site_file

Devuelve el contenido de un archivo. El texto llega tal cual; los binarios llegan codificados en base64 con encoding ajustado en consecuencia.

TOOL read_site_file

Argumentos

NombreTipoObligatorioDescripción
pidstringobligatorioSitio del que leer.
pathstringobligatorioRelativa a la raíz del sitio, p. ej. css/style.css.

Resultado de ejemplo

{
    "status": "success",
    "path": "css/style.css",
    "encoding": "text",
    "size": 14,
    "hash": "fedcba9876543210fedcba9876543210",
    "content": "body{margin:0}"
}

Errores

CódigoCuándo
400Falta path o apunta fuera del sitio.
404No se encuentra el sitio o el archivo.
413El archivo pesa más de 1 MB, así que usa en su lugar download_site_files.

delete_site_files

Elimina archivos o directorios. Los directorios se eliminan de forma recursiva.

TOOL delete_site_files

Argumentos

NombreTipoObligatorioDescripción
pidstringobligatorioSitio del que eliminar.
pathsstringobligatorioMatriz JSON de rutas, p. ej. ["old.html", "assets/legacy"].

Una nota sobre rutas locales

El servidor alojado se ejecuta en nuestra infraestructura y no comparte sistema de archivos contigo, así que no hay ninguna herramienta que reciba una ruta de tu ordenador. Todo lo que tenga que viajar lo hace como contenido o por HTTP:

Qué quieres hacerUsa
Cambiar o añadir un archivo de textowrite_site_files, enviando el contenido
Añadir una imagen, una fuente o un vídeocreate_upload, y luego write_site_files con upload_id
Publicar un ZIP que tienes en localcreate_upload, y luego upload_id
Publicar un ZIP que ya está onlinearchive_url

¿Alojas el servidor tú mismo? Define LOCAL_FILE_ACCESS=true y además expone upload_site_files y un argumento archive_path, que leen de la máquina en la que se ejecuta el servidor.

Subida de archivos

Cómo meter contenido en un sitio sin pagarlo dos veces: una en ancho de banda y otra en tokens.

Qué método usar

El servidor se ejecuta en remoto, así que nada se lee de tu disco. Dos preguntas deciden el resto: ¿cambias unos pocos archivos o sustituyes todo el sitio? ¿Tiene tu cliente una terminal?

SituaciónUsaCoste en tokens
Editar páginas y estilos, añadir un archivowrite_site_filesSolo el texto del propio archivo.
Añadir una imagen, una fuente o un vídeo a un sitiocreate_upload + write_site_filesNinguno. El archivo nunca entra en la conversación.
Sustituir todo un sitio con un ZIPcreate_upload + upload_idNinguno. El archivo nunca entra en la conversación.
El ZIP ya está alojado en algún sitioarchive_urlNinguno.
El cliente no tiene terminal ni hostingarchive_base64Aproximadamente 1,4 tokens por byte de ZIP.

create_upload

Reserva un espacio de un solo uso y devuelve una URL a la que enviar un archivo con PUT, más un comando curl listo para ejecutar. La URL no necesita clave de API. El archivo va directo de tu disco al servidor, así que su tamaño no cuesta nada de contexto. Publica un ZIP con él, o coloca un archivo suelto con write_site_files.

TOOL create_upload

Argumentos

NombreTipoObligatorioDescripción
file_namestringopcionalNombre del archivo. Por defecto es archive.zip.

Resultado de ejemplo

{
    "upload_id": "0e9837a760c5062279ea57107d8f0a1c",
    "upload_url": "https://mcp.static.app/upload/0e9837a760c5062279ea57107d8f0a1c",
    "file_name": "site.zip",
    "expires_at": "2026-08-25T12:57:32Z",
    "max_size": 204800000,
    "single_use": true
}

Después envía el archivo con PUT

curl -fsS -T site.zip https://mcp.static.app/upload/0e9837a760c5062279ea57107d8f0a1c

Después publícalo

{
    "pid": "xxxxxxxxxx",
    "upload_id": "0e9837a760c5062279ea57107d8f0a1c"
}
Un solo uso. Un espacio vacío se cierra a los 15 minutos. El archivo preparado se elimina en cuanto se publica y caduca a los 30 minutos en cualquier caso. Solo la clave de API que reservó un espacio puede publicarlo, así que una URL filtrada no puede cambiar un sitio.
100 MB para publicar. Un espacio admite hasta 200 MB, pero para crear o sustituir un sitio con un ZIP se aceptan archivos de hasta 100 MB. Mantén el ZIP por debajo de 100 MB, o añade los recursos grandes después con write_site_files.

Endpoint de subida

La herramienta es una comodidad, y cualquier cliente HTTP puede usar el endpoint directamente. POST recibe tu clave de API, prepara un archivo y devuelve un ID nuevo en un solo paso; PUT rellena un ID que entregó create_upload y no necesita clave.

POST https://mcp.static.app/upload
PUT https://mcp.static.app/upload/{upload_id}

Ejemplo de solicitud

curl -X POST --data-binary @site.zip \
    -H "Authorization: Bearer sk_xxxx" \
    "https://mcp.static.app/upload?file_name=site.zip"

Ejemplo de respuesta

{
    "status": "success",
    "upload_id": "0e9837a760c5062279ea57107d8f0a1c",
    "file_name": "site.zip",
    "size": 5000000,
    "sha256": "1df9cfae4840f7c4eef12dbd4691c043ce4e247130817053c55f1aa04eddd971",
    "expires_at": "2026-08-25T12:57:32Z"
}

Errores

CódigoCuándo
401POST sin clave de API.
404ID desconocido o caducado.
409Ya se subió contenido para este ID.
413El cuerpo supera el límite de 200 MB.
503El almacenamiento temporal está desactivado en el servidor. Usa archive_url en su lugar.

Base64 (heredado)

archive_base64 sigue funcionando y se comprueba en último lugar. Existe para clientes que no pueden hacer una petición HTTP por su cuenta, pero base64 añade un tercio sobre los bytes originales, y todos pasan por el modelo, así que un archivo de 2 MB cuesta unos 700.000 tokens. Se rechaza todo lo que pase de 1.048.576 caracteres (unos 750 KB de ZIP). Da preferencia a upload_id siempre que haya una terminal disponible.

# macOS
base64 -i site.zip | tr -d '\n'

# Linux
base64 -w 0 site.zip

Herramientas de formularios

Lee los formularios de un sitio y trabaja con sus envíos.

Aún no funciona. En el servidor alojado estas herramientas todavía no pueden leer formularios ni envíos, aunque tu cliente las liste. Por ahora usa el panel o la API REST para los envíos de formularios.

list_forms

Devuelve todos los formularios de un sitio.

TOOL list_forms

Argumentos

NombreTipoObligatorioDescripción
pidstringobligatorioIdentificador público del sitio.

get_form

Devuelve un formulario con sus campos.

TOOL get_form

Argumentos

NombreTipoObligatorioDescripción
pidstringobligatorioIdentificador público del sitio.
form_idstringobligatorioID del formulario.

get_form_entries

Devuelve los envíos de un formulario, los más recientes primero.

TOOL get_form_entries

Argumentos

NombreTipoObligatorioDescripción
pidstringobligatorioIdentificador público del sitio.
form_idstringobligatorioID del formulario.
limitnumberopcionalCuántos envíos devolver.
offsetnumberopcionalDesplazamiento para la paginación.

Pregunta a tu asistente

"Summarise the last 20 contact form submissions on site xxxxxxxxxx."

delete_form_entry

Elimina un envío.

TOOL delete_form_entry

Argumentos

NombreTipoObligatorioDescripción
pidstringobligatorioIdentificador público del sitio.
form_idstringobligatorioID del formulario.
entry_idstringobligatorioID del envío que eliminar.

Solución de problemas

Los fallos que se dan de verdad y qué significa cada uno.

401 Unauthorized

  • Comprueba que la clave está vigente y no se ha revocado en Cuenta → API / MCP.
  • La cabecera necesita el prefijo Bearer: Authorization: Bearer sk_xxxx.
  • En un archivo de configuración, confirma que la variable de entorno se ha resuelto de verdad: un ${STATIC_API_KEY} literal que llega al servidor se interpreta como una clave incorrecta.
  • Has iniciado sesión con OAuth y ahora recibes 401: la conexión se desconectó en Cuenta → API / MCP. Vuelve a iniciar sesión desde el cliente (/mcp en Claude Code, codex mcp login static-app en Codex).

"Site not found"

  • Pasa el PID (el ID público de 10 caracteres, como 0aw4jtby1z), no el ID numérico de la base de datos.
  • El sitio tiene que pertenecer a la cuenta de la clave. Ejecuta list_sites para ver cuáles pertenecen.
  • Cambiar de espacio de trabajo cambia qué sitios se ven.

Pasar una ruta de tu ordenador

El servidor alojado no comparte sistema de archivos contigo, así que una ruta como /Users/me/site.zip no significa nada para él. Un cliente antiguo que aún envíe archive_path recibe un error que explica qué usar en su lugar; uno que llame a upload_site_files recibe tool not found, porque esa herramienta no está registrada aquí en absoluto.

  • Cambiar archivos → write_site_files, con el texto en la propia llamada y los binarios por upload_id.
  • Publicar un archivo comprimido → create_upload, envía el ZIP con PUT y luego upload_id.
  • Archivo ya alojado → archive_url.
  • Si ejecutas el servidor tú mismo → LOCAL_FILE_ACCESS=true recupera las herramientas de rutas locales.

Las herramientas no aparecen

  • Reinicia el cliente después de editar su configuración MCP. La mayoría solo la lee al arrancar.
  • Claude Desktop registra el handshake: ~/Library/Logs/Claude/mcp*.log en macOS.
  • Cannot find module 'mcp-remote': usa npx -y mcp-remote, que lo instala al momento.
  • Una conexión sana lista las herramientas del índice de herramientas. Si salen menos, el cliente guardó en caché una sesión anterior.

Errores de conexión

  • La URL es exactamente https://mcp.static.app/mcp, y el cliente está configurado con Streamable HTTP (--transport http, "type": "http"), no con SSE.
  • Prueba el endpoint por separado: curl -i -X POST https://mcp.static.app/mcp. Sin credenciales responde 401 con una cabecera WWW-Authenticate que apunta a los metadatos de inicio de sesión, lo que demuestra que el servidor es accesible.
  • 404 en una petición que lleva Mcp-Session-Id: la sesión ha caducado o el servidor se ha reiniciado. Los clientes se reconectan solos; uno hecho a mano tiene que volver a enviar initialize.
  • ¿Sigues en el endpoint antiguo /sse? Mantiene una conexión abierta de larga duración, así que los proxies que almacenan las respuestas en búfer o cortan las conexiones inactivas la rompen. Cambia a /mcp.

Subida rechazada

CódigoSignificadoSolución
403Se intenta publicar un ID que pertenece a otra clave.Usa la misma clave que llamó a create_upload.
404ID desconocido o caducado.Los espacios vacíos duran 15 minutos y los llenos 30, y se eliminan una vez publicados. Reserva uno nuevo.
409Ya se subió contenido para este ID.Un espacio admite un solo archivo. Reserva otro para volver a subir.
413Supera el límite de 200 MB.Divide la publicación, o deja fuera los recursos grandes y añádelos con write_site_files.
503El almacenamiento temporal está desactivado en el servidor.Publica con archive_url, o pídenos que apuntemos UPLOAD_DIR a una ruta con permiso de escritura.
422No se pudo escribir nada.Revisa la matriz errors. Suele ser una extensión no admitida o una ruta que sale de la raíz del sitio.

Sigue sin funcionar

Las mismas operaciones están disponibles por HTTP, y reproducir un fallo con la API REST te dice si el problema es del cliente o de la cuenta. Si no es ninguno de los dos, contacta con soporte.