Ir al contenido

Solución de problemas

GITLAB_TOKEN required

Invalid GITLAB_URL

401 Unauthorized

403 Forbidden

Conexión rechazada

No

No

No

El servidor no arranca

Mensaje de error?

Establece GITLAB_TOKEN
en el entorno o ~/.gitlab-mcp-server.env

Corrige GITLAB_URL
autogestionado

Regenera token
con scope api

Verifica scope api
del token

GitLab accesible?

Verifica GITLAB_URL
y red

Error TLS?

Puedes instalar cert CA?

Añade cert CA al almacén
de confianza del sistema

GITLAB_MCP_SKIP_TLS_VERIFY=true
como último recurso

Habilita debug logging
GITLAB_MCP_LOG_LEVEL=debug

SíntomaCausaSolución
GITLAB_TOKEN is required al inicioToken no establecidoEstablece GITLAB_TOKEN en el entorno o en ~/.gitlab-mcp-server.env; un .env en el directorio de trabajo no se lee, y si existe se nombra a nivel WARN al arrancar
GITLAB_URL is not a valid URL al inicioLa URL tiene sintaxis inválidaCorrige GITLAB_URL u omítela para usar https://gitlab.com en modo stdio
401 Unauthorized de la API de GitLabPAT inválido o expiradoGenera un nuevo token con scope api en GitLab → Preferences → Access Tokens
403 Forbidden en operaciones específicasEl token carece del scope requeridoAsegúrate de que el token tiene scope api (no solo read_api)
Conexión rechazada o timeoutInstancia de GitLab inaccesibleVerifica que GITLAB_URL es accesible: curl -s $GITLAB_URL/api/v4/version
SíntomaCausaSolución
x509: certificate signed by unknown authorityCertificado autofirmadoPrimero intenta añadir el certificado CA al almacén de confianza del sistema. Si no es posible, establece GITLAB_MCP_SKIP_TLS_VERIFY=true en el entorno o en ~/.gitlab-mcp-server.env, o --skip-tls-verify en modo HTTP; --auth-mode=oauth lo rechaza para una instancia que no sea loopback, así que ahí instala la CA (o apunta SSL_CERT_FILE a un bundle)
x509: certificate has expiredCertificado TLS expiradoRenueva el certificado en el servidor de GitLab, o usa GITLAB_MCP_SKIP_TLS_VERIFY=true temporalmente

Si el servidor no puede resolver el hostname de tu GitLab:

Ventana de terminal
# Verificar DNS desde la máquina que ejecuta el servidor MCP
nslookup gitlab.example.com
# o
dig gitlab.example.com +short

En contenedores Docker, asegúrate de que tu fichero compose o el comando docker run use --dns o una red personalizada con configuración DNS adecuada. Dentro de Kubernetes, revisa los logs de CoreDNS y resolv.conf en el pod.

El net/http de Go respeta las variables de entorno de proxy estándar. Establécelas antes de lanzar el servidor:

Ventana de terminal
export HTTPS_PROXY=http://proxy.corp.example.com:8080
export HTTP_PROXY=http://proxy.corp.example.com:8080
export NO_PROXY=localhost,127.0.0.1,.internal.corp
SíntomaCausaSolución
Timeout de conexión detrás de red corporativaProxy no configuradoEstablece HTTPS_PROXY / HTTP_PROXY
El proxy funciona con curl pero no con el servidorVars de entorno no exportadas al proceso del servidorPásalas en el bloque env del cliente, en ~/.gitlab-mcp-server.env, en environment: de Docker, o en los secretos de tu plataforma
GitLab interno enrutado a través de proxy externoFalta NO_PROXYAñade tu hostname de GitLab a NO_PROXY

Cuando se ejecuta el servidor MCP detrás de nginx, Caddy, o un balanceador cloud:

SíntomaCausaSolución
429 tras unos pocos inicios de sesión fallidos de personas distintasEl límite de fallos de autenticación (10 por dirección y minuto) ve la dirección del proxy, no la del clienteEstablece --trusted-proxy-header a la cabecera que tu proxy establece (ej. X-Forwarded-For, CF-Connecting-IP) y --trusted-proxies a la dirección del proxy; el limitador de tasa por llamada se indexa por token y no se ve afectado
Stream SSE desconectadoTimeout de lectura o de inactividad del proxy más corto que el silencio del streamSube el timeout de lectura del proxy; el keep-alive SSE de 25 segundos del servidor mantiene abierto un stream inactivo frente al valor por defecto de 60 segundos de nginx, así que lo corta un edge más estricto
502 Bad GatewayEl servidor aún no está escuchandoAñade un startup probe o reintento; el servidor necesita unos segundos para inicializarse en la primera petición
SíntomaCausaSolución
Solo aparecen dos herramientas: gitlab_find_action y gitlab_execute_actionEs lo esperado: dynamic es la superficie predeterminadaNo es un fallo. Pide lo que necesites en lenguaje natural: el asistente localiza la acción y su esquema y después la ejecuta. Si prefieres una lista de herramientas navegable, usa GITLAB_MCP_TOOL_SURFACE=meta o GITLAB_MCP_TOOL_SURFACE=individual
El cliente MCP muestra cientos de herramientas individuales en lugar de 34Superficie individual seleccionadaEstablece GITLAB_MCP_TOOL_SURFACE=meta para consolidar en meta-herramientas de dominio
Herramienta no encontrada en tools/listDesajuste de la superficie de herramientasEl modo individual usa gitlab_issue_create, el modo meta usa gitlab_issue con action: create, y el modo dinámico expone gitlab_find_action y gitlab_execute_action
unknown action en llamada a meta-herramientaParámetro de acción inválidoVerifica las acciones válidas en Resumen de Herramientas
json: unknown field "<nombre>" desde una meta-herramientaParámetro mal escrito u obsoleto en paramsLas meta-herramientas rechazan claves desconocidas. Usa los nombres exactos de la action elegida (p. ej. merge_request_iid, issue_iid, epic_iid, work_item_iid, snippet_id)
Herramientas enterprise faltantesCatálogo enterprise desactivadoEn modo stdio, establece GITLAB_MCP_TIER=premium o GITLAB_MCP_TIER=ultimate. En modo HTTP, configura --tier=premium/--tier=ultimate para forzar el catálogo o deja que la detección de licencia lo habilite cuando la instancia informe de un plan Premium o Ultimate. La variable deprecada GITLAB_ENTERPRISE=true sigue funcionando cuando GITLAB_MCP_TIER no está definida; no existe ningún flag --enterprise, usa --tier
SíntomaCausaSolución
the @jmrp.io/gitlab-mcp-server-linux-x64 package is not installedEn Alpine es intencionado: los paquetes de Linux declaran libc: glibc y los binarios publicados necesitan el cargador dinámico de glibc, así que npm los omite sobre musl. En una distribución con glibc significa que la instalación omitió las dependencias opcionales (--no-optional, o un lockfile resuelto en otro sistema)Sobre musl, usa la imagen de contenedor ghcr.io/jmrplens/gitlab-mcp-server (compilada contra musl) o compila desde el código fuente: la publicación no está rota. Sobre glibc, reinstala sin --no-optional, o borra node_modules y el lockfile y vuelve a instalar
Las actualizaciones nunca llegan al ejecutar con npxEl servidor no se actualiza a sí mismo, y el binario lo gestiona npmEs lo esperado. Actualiza con npm, o añade @latest a la spec de npx para que resuelva de nuevo en lugar de reutilizar su caché

El servidor no se actualiza a sí mismo, así que actualizar es lo que haga tu canal de instalación más un reinicio.

SíntomaCausaSolución
Sigue ejecutando la versión antigua tras actualizarEl proceso antiguo no se reinicióReinicia el servidor, o ejecuta gitlab-mcp-server --shutdown para terminar antes todas las instancias
No se puede reemplazar el binario (archivo bloqueado)Las instancias en ejecución mantienen el archivoEjecuta gitlab-mcp-server --shutdown para terminar todas las instancias y después reemplázalo
SíntomaCausaSolución
401 Unauthorized con WWW-Authenticate: BearerCabecera de token faltante o vacíaEnvía la cabecera PRIVATE-TOKEN o Authorization: Bearer <token> con cada solicitud. El cuerpo JSON nombra las dos cabeceras aceptadas
400 Bad Request con no server available en texto planoUna versión anterior a la 2.6.6 recibió una solicitud que no pudo enrutarNo es una caída ni lo emite este proyecto — viene del SDK de MCP cuando la selección de servidor no encuentra ninguno. Actualiza: esos casos ahora son 401, 400, 429 y 503 con cuerpo JSON-RPC
400 Bad Request que menciona GITLAB-URLLa cabecera GITLAB-URL de la solicitud no es una URL analizableEnvía una URL absoluta como https://gitlab.example.com, u omite la cabecera si el servidor arranca con --gitlab-url
400/403 indicando que el despliegue no sirve esa instancia de GitLab--gitlab-url nombra más de una instancia, así que publica una lista de instancias permitidasEnvía en GITLAB-URL una de las instancias que publica el servidor; omitir la cabecera también se rechaza (400), nunca se resuelve a la primera instancia. En modo OAuth el error las enumera —es la misma lista que su metadata RFC 9728 ya sirve sin autenticar— y responde 403 antes de usar el token en ningún sitio. El modo legacy responde 400 y no las nombra: no publica documento de metadata y llega a este rechazo antes de validar la credencial, así que pregunta al operador
429 Too Many Requests con Retry-AfterMás de 10 autenticaciones fallidas desde una misma IP en un minutoEspera a que pase la ventana y reintenta con un token válido. Tras un proxy inverso, configura --trusted-proxy-header y --trusted-proxies para que el límite cuente las IP reales
503 Service UnavailableLa instancia de GitLab no era alcanzable al construir la sesión de ese tokenRevisa GITLAB-URL / --gitlab-url y la accesibilidad de la instancia; el servidor registra el error subyacente
Desalojo del pool demasiado frecuenteDemasiados tokens únicosAumenta --max-http-clients (por defecto: 100)
Sesiones expirando inesperadamenteTimeout de inactividad MCP muy cortoAumenta --session-timeout (por defecto: 30m); solo se aplica con --stateless=false, el transporte sin estado por defecto no tiene sesión que expirar
Las sesiones MCP caen cada ~2 min / keepalive ping failed; closing sessionUn --http-idle-timeout bajo (o un timeout del proxy) está cerrando streams SSE de larga duraciónPor defecto --http-idle-timeout=0 desactiva el cierre por inactividad de la capa HTTP; si has puesto un valor bajo, súbelo o usa 0. Detrás de un proxy inverso, aumenta también su timeout de lectura/inactividad
SíntomaCausaSolución
401 Unauthorized con token OAuth válidoToken expirado o rechazado por GitLabRe-autoriza a través del flujo OAuth; verifica que la aplicación OAuth de GitLab siga activa
Alta latencia en la primera solicitud tras expirar la cachéRe-validación del token contra la API de GitLabComportamiento esperado — aumenta --oauth-cache-ttl (por defecto: 15m, máx: 2h) para reducir la frecuencia de validación
404 en /.well-known/oauth-protected-resourceModo OAuth no habilitado, o --public-url lleva una rutaInicia el servidor con --auth-mode=oauth. Cuando --public-url tiene una ruta, el documento se mueve a la ruta derivada (ver Modo servidor HTTP) y la ruta escueta responde 404 a propósito
El cliente no inicia el flujo OAuthEl cliente no soporta OAuth 2.1Envía un token de acceso personal como Authorization: Bearer <glpat-...> — se verifica igual que un token OAuth
401 al enviar PRIVATE-TOKEN en modo OAuthEl modo OAuth es solo Bearer, por diseñoMueve el token a Authorization: Bearer <token>; PRIVATE-TOKEN solo se acepta en --auth-mode=legacy
Operaciones fallan con scope mcp insuficienteDCR fallback asignó scope mcp en lugar de apiConfigura clientId explícitamente en la configuración del cliente MCP. Ver Modo servidor HTTP
SíntomaCausaSolución
Resultados de listas truncadosLímite predeterminado de per_pagePasa los parámetros per_page (máx 100) y page para paginar
nextPage faltante en la respuestaÚltima página alcanzadaNo hay más resultados — este es el comportamiento esperado
SíntomaSolución
“Tool not found” en Copilot ChatVerifica el panel de Salida → MCP Logs para errores. Verifica la ruta de .vscode/mcp.json
El servidor no aparece en el estado MCPEjecuta Ctrl+Shift+PMCP: List Servers para verificar la configuración
“Permission denied” al inicioEjecuta chmod +x /ruta/al/gitlab-mcp-server (Linux/macOS)
El servidor se reinicia repetidamenteVerifica MCP Logs por GITLAB_URL o GITLAB_TOKEN faltantes
Espera indefinidamente a initialize y Docker muestra modo HTTPAñade -i a los argumentos de docker run para que el contenedor reciba una tubería por la que hablar y deduzca stdio (JSON-RPC por stdin/stdout, sin necesidad de puerto), y haz docker pull de la imagen si es anterior a la versión que hizo de --transport auto su comando. Como alternativa, ejecuta el contenedor en modo HTTP con -p 8080:8080 y una instancia a la que servir (-e GITLAB_URL=https://gitlab.com, sin la cual termina con --gitlab-url is required in HTTP mode), y configura el cliente MCP como HTTP apuntando a http://host:8080/mcp — esto solo funciona si el servidor está en marcha y el puerto es accesible.

Habilita el registro detallado para diagnosticar problemas:

  1. Establece el nivel de log a debug:

    Ventana de terminal
    # Modo stdio
    GITLAB_MCP_LOG_LEVEL=debug ./gitlab-mcp-server 2>debug.log
    # Modo HTTP (logs mezclados con la salida del servidor)
    GITLAB_MCP_LOG_LEVEL=debug ./gitlab-mcp-server --http --gitlab-url=https://gitlab.com 2>debug.log
  2. Reproduce el problema ejecutando la misma operación que falló.

  3. Examina los logs — los logs de depuración incluyen:

    • Cada llamada a herramienta con parámetros de entrada
    • Detalles de solicitud/respuesta de la API de GitLab
    • Eventos de validación de token (solo los últimos 4 caracteres)
    • Operaciones del pool de sesiones (modo HTTP)

Si no puedes resolver un problema:

  1. Habilita el registro de depuración (GITLAB_MCP_LOG_LEVEL=debug) y captura la salida
  2. Revisa las GitHub Issues para problemas conocidos
  3. Abre una nueva issue con:
    • Versión del servidor (gitlab-mcp-server --version o revisa los logs de inicio)
    • Sistema operativo y arquitectura
    • Nombre y versión del cliente MCP
    • Logs de depuración redactados (elimina cualquier token o dato sensible)
    • Pasos para reproducir el problema

Preguntas frecuentes

¿Por qué mi cliente MCP muestra cientos de herramientas?

El cliente usa la superficie de herramientas individual, que registra una herramienta por operación de GitLab. Establece GITLAB_MCP_TOOL_SURFACE=meta para consolidarlas en 34 meta-herramientas de dominio, o usa la superficie dinámica predeterminada, que expone solo gitlab_find_action y gitlab_execute_action. Los nombres de herramientas también difieren por superficie: el modo individual usa gitlab_issue_create, el modo meta usa gitlab_issue con action: create, y el modo dinámico usa find y execute.

¿Cómo soluciono errores 401 o 403 de GitLab?

Un 401 Unauthorized significa que el Personal Access Token es inválido o ha expirado — genera un nuevo token con el scope api en GitLab → Preferences → Access Tokens. Un 403 Forbidden en operaciones específicas significa que el token carece del scope requerido; asegúrate de que tiene el scope api, no solo read_api. Si el servidor no arranca con GITLAB_TOKEN is required, establece GITLAB_TOKEN en el entorno del cliente o en ~/.gitlab-mcp-server.env (un .env en el directorio de trabajo no se lee).

¿Por qué faltan las herramientas Enterprise?

El catálogo Enterprise/Premium está desactivado. En modo stdio, establece GITLAB_MCP_TIER=premium o GITLAB_MCP_TIER=ultimate. En modo HTTP, establece --tier=premium o --tier=ultimate para forzar el catálogo, o deja que la detección de licencia lo habilite cuando la instancia informe de un plan Premium o Ultimate. La variable deprecada GITLAB_ENTERPRISE=true sigue funcionando cuando GITLAB_MCP_TIER no está definida; no existe ningún flag --enterprise, usa --tier. Las herramientas Enterprise también requieren una licencia Premium o Ultimate en la instancia conectada.

¿Cómo habilito el registro de depuración?

Establece GITLAB_MCP_LOG_LEVEL=debug y redirige stderr a un archivo — por ejemplo GITLAB_MCP_LOG_LEVEL=debug ./gitlab-mcp-server 2>debug.log — y luego reproduce la operación fallida. Los logs de depuración incluyen cada llamada a herramienta con parámetros de entrada, detalles de solicitud y respuesta de la API de GitLab, eventos de validación de token (solo los últimos 4 caracteres) y operaciones del pool de sesiones HTTP. Los logs van a stderr y los mensajes JSON-RPC van a stdout, así que redirige siempre stderr para no mezclar ambos.