Línea de comandos
Sinopsis
Sección titulada «Sinopsis»gitlab-mcp-server [flags]gitlab-mcp-server --probe [flags] [target]Sin flags, el servidor sirve stdio y lee su configuración del entorno, de ~/.gitlab-mcp-server.env y del fichero que nombren --env-file o GITLAB_MCP_ENV_FILE. Si se arranca a mano en un terminal interactivo y GITLAB_URL o GITLAB_TOKEN siguen sin definir tras leer esos ficheros, imprime lo que necesita y espera; consulta Primer arranque sin configuración.
Sintaxis de los flags
Sección titulada «Sintaxis de los flags»Los flags los analiza el paquete flag estándar de Go, que decide algunas cosas que conviene saber:
- Un flag admite uno o dos guiones:
-httpy--httpson el mismo flag. Esta página escribe dos. - El valor va tras
=o tras un espacio (--http-addr=:9090o--http-addr :9090). Un flag booleano solo toma valor tras=:--stateless=falsedesactiva el modo sin estado, mientras que--stateless falselo pone atruey termina los flags en la palabrafalse. - El análisis se detiene en el primer argumento que no es un flag, así que el destino de
--probeva al final: nada de lo que venga después se lee como flag. - Una duración usa la sintaxis de Go:
90s,30m,1h30m.0no necesita unidad, y cualquier otro número sin unidad se rechaza. - Un flag que el binario no define, o un valor que su tipo no puede analizar, detiene el programa antes de que haga nada: el analizador imprime el error y su propia lista alfabética de todos los flags, y el código de salida es
2. La ayuda completa es--help.
Qué flags lee cada transporte
Sección titulada «Qué flags lee cada transporte»Un servidor stdio construye su configuración a partir del entorno. De los flags, lee los generales, los respaldados por variables de entorno y los de telemetría; los flags del modo HTTP solo los lee un servidor que sirve HTTP. (--tool-search lee --tool-surface y --tier, y --probe lee --tls-cert, pero ambos terminan antes de elegir transporte.)
Una ejecución stdio que recibe un flag del modo HTTP lo ignora y lo dice una vez al arrancar, en WARN, nombrando cada flag junto con la variable que stdio lee en su lugar cuando la hay: --max-request-body-bytes, por ejemplo, nombra GITLAB_MCP_STDIO_MAX_LINE_BYTES, que acota ese mismo mensaje en stdio. Cuando --transport=auto eligió stdio, un flag para el que stdio no tiene ningún ajuste (el listener, el pool, la puerta de autenticación) se nombra en INFO, porque esa línea de comandos se escribió para cualquiera de los dos transportes; un flag para el que stdio tiene variable sigue en WARN.
Cuando ignorar el flag costaría más que un ajuste, una ejecución stdio se niega a arrancar, sale con 1 y nombra el ajuste que hay que usar, también con --transport=auto e incluso si esa variable ya pide lo mismo:
--read-onlyo--safe-modeatrue, o un--exclude-toolsque nombre algo: ignorarlo serviría lo que pide retirar. FijaGITLAB_MCP_READ_ONLY,GITLAB_MCP_SAFE_MODEoGITLAB_MCP_EXCLUDE_TOOLSen su lugar.- Un
--gitlab-urlque no nombra la instancia a la que conecta la ejecución stdio: stdio conecta a la que nombreGITLAB_URL,https://gitlab.comsi no está definida, y enviaría allíGITLAB_TOKEN. FijaGITLAB_URLa la instancia en su lugar. Un--gitlab-urlque nombra esa misma instancia, se escriba como se escriba, solo se nombra: se comparan en forma canónica, así quehttps://GitLab.example.com:443/nombrahttps://gitlab.example.com.
Un valor que no pide nada (--read-only=false, un --exclude-tools vacío) solo se nombra, como cualquier otro flag ignorado.
En modo HTTP, los ajustes se resuelven en tres capas, de mayor a menor prioridad: un flag pasado explícitamente, después su variable de entorno y después el valor predeterminado integrado. Un flag pasado con el mismo valor que su predeterminado cuenta como pasado, así que una variable perdida no puede desplazar una línea de comandos deliberada.
En las tablas siguientes, la columna Variable nombra la variable de entorno que un flag escribe (los flags respaldados por variables de entorno) o a la que recurre cuando no se pasa (cualquier otro flag que tenga una); ninguna significa que el flag no tiene equivalente en el entorno. La columna Predeterminado es el valor con el que se registra el flag; cuando está vacío y representa algo, la descripción dice qué.
Flags generales
Sección titulada «Flags generales»| Flag | Tipo | Predeterminado | Variable | Descripción |
|---|---|---|---|---|
-h, --help | bool | false | ninguna | Imprime la ayuda completa: todos los flags agrupados por lo que configuran, las variables de entorno y ejemplos de configuración JSON. Las dos grafías imprimen el mismo texto |
--version | bool | false | ninguna | Imprime gitlab-mcp-server <version> (commit: <commit>) y termina |
--shutdown | bool | false | ninguna | Termina todas las demás instancias en marcha de este binario y sale; consulta Modo de apagado |
--probe | bool | false | ninguna | Pregunta al /health de la instancia en marcha y sale con 0 cuando responde 200: es el HEALTHCHECK de la imagen de contenedor. Un destino opcional tras los flags (una URL, unix:<path> o host:port) se sondea en lugar del listener descubierto; consulta Modo sonda |
--tool-search | string | (vacío) | ninguna | Busca en el catálogo canónico de acciones y termina; consulta Búsqueda de herramientas. Lee --tool-surface y --tier si se pasan, y si no GITLAB_MCP_TOOL_SURFACE y GITLAB_MCP_TIER. No necesita credenciales de GitLab |
--env-file | string | (vacío) | Fija GITLAB_MCP_ENV_FILE | Un fichero dotenv que se carga además de ~/.gitlab-mcp-server.env. Es el mismo ajuste que GITLAB_MCP_ENV_FILE, y prevalece sobre ella. Usa una ruta absoluta: una relativa sigue al cliente al directorio en el que arranque el servidor, y el arranque lo avisa |
--transport | string | (vacío) | ninguna | Transporte que se sirve: stdio, http o auto. Vacío deja la decisión a --http; si se dan ambos, gana --transport y lo dice al arrancar. auto lee el descriptor de fichero 0 y sirve HTTP solo cuando la entrada estándar es el dispositivo nulo, que es lo que da un contenedor arrancado sin -i, y stdio en cualquier otro caso. Cualquier otro valor sale con 2 |
--http | bool | false | ninguna | Sirve HTTP en lugar de stdio |
Una ejecución que recibe más de uno de los flags de un solo uso ejecuta el primero de -h/--help, --version, --shutdown, --probe y --tool-search, en ese orden, e ignora el resto. Un --transport no válido se rechaza antes que cualquiera de ellos, --help incluido.
Flags respaldados por variables de entorno
Sección titulada «Flags respaldados por variables de entorno»Siete ajustes que antes solo se fijaban con una variable de entorno tienen un flag cada uno, para que una sola línea de comandos pueda configurar todo el servidor. Un flag pasado escribe su variable antes de que nada lea la configuración, así que cada ajuste conserva un único lector y un flag pasado explícitamente gana a una variable exportada. Un flag que no se pasa no escribe nada, y por eso los siete se registran con un valor predeterminado vacío: decide la variable, o el valor predeterminado integrado que se indica abajo. Los dos transportes leen los siete.
| Flag | Tipo | Predeterminado | Variable | Descripción |
|---|---|---|---|---|
--log-level | string | (vacío) | Fija GITLAB_MCP_LOG_LEVEL | Verbosidad del registro: debug, info, warn (o warning) o error. Sin definir, o con cualquier otro valor, registra en info |
--client-compat | string | (vacío) | Fija GITLAB_MCP_CLIENT_COMPAT | Compatibilidad de respuesta por cliente: off la desactiva, y cualquier otra cosa, sin definir incluido, significa auto. Consulta Compatibilidad de clientes |
--upload-max-file-size | string | (vacío) | Fija GITLAB_MCP_UPLOAD_MAX_FILE_SIZE | Mayor fichero local que acepta una herramienta de subida o de lectura de ficheros: un número de bytes, o un número con sufijo KB, MB o GB en mayúsculas o minúsculas (múltiplos de 1024). Sin definir significa 2GB, y el techo es 1 TB. En stdio, un valor que no se puede analizar, o que supera el techo, impide arrancar; en modo HTTP se registra en WARN y el servidor usa 2GB o el techo en su lugar |
--yolo-mode | string | (vacío) | Fija GITLAB_MCP_YOLO_MODE | 1, true o yes omite la confirmación de las acciones destructivas en todas las superficies: sin pregunta en las superficies meta e individual, y sin necesidad de confirm: true en la dinámica por defecto (consulta Acciones destructivas); cualquier otro valor la mantiene. Cuando la variable está definida decide ella, y AUTOPILOT solo se consulta cuando no lo está, así que --yolo-mode=false anula un AUTOPILOT=true heredado |
--description-substitutions | string | (vacío) | Fija GITLAB_MCP_DESCRIPTION_SUBSTITUTIONS | Pares viejo=nuevo separados por comas que se aplican en orden a cada descripción y título listados, para validadores estrictos de gateways MCP (la barra invertida escapa \,, \= y \\). Un valor mal formado impide arrancar. Consulta Compatibilidad de clientes |
--allow-private-instances | string | (vacío) | Fija GITLAB_MCP_ALLOW_PRIVATE_INSTANCES | true permite que un destino que no eligió quien opera este servidor sea una dirección privada, de loopback, CGNAT, de enlace local, local única o no especificada: una instancia que alguien nombró en la cabecera GITLAB-URL con --allow-any-gitlab-url, o un salto de redirección que salió del host de la instancia configurada. Una dirección nombrada en --gitlab-url o GITLAB_URL nunca se comprueba, y las direcciones de metadatos de la nube siguen rechazadas diga lo que diga. Consulta Destinos salientes |
--pprof-addr | string | (vacío) | Fija GITLAB_MCP_PPROF_ADDR | Sirve los manejadores de perfilado de Go (net/http/pprof) en esta dirección, en un listener propio que arranca antes que el transporte, para poder tomar un perfil de CPU del arranque. Solo se acepta localhost o una IP de loopback (127.0.0.1:6060, [::1]:6060, localhost:6060); cualquier otro host se rechaza al arrancar, porque un perfil de heap es una copia de la memoria del proceso y los manejadores no piden credencial. Vacío no sirve nada |
--allow-private-instances lee su valor como un booleano de Go (true, 1, t), y cualquier otra cosa significa false; la decisión detrás de la exención es el ADR-0022.
GITLAB_TOKEN no tiene flag. Un token en la línea de comandos es visible para cualquier usuario de la máquina con ps, queda en la contabilidad de procesos y acaba en el historial del shell, así que el entorno es la única forma de dárselo a un servidor stdio; en modo HTTP cada cliente envía el suyo en una cabecera de la petición. La clave de seudonimización de la telemetría, GITLAB_MCP_TELEMETRY_IDENTITY_KEY, no tiene flag por el mismo motivo.
Flags de telemetría
Sección titulada «Flags de telemetría»Estos cuatro los leen los dos transportes: un despliegue stdio es justo el caso que le importa a quien vigila su propia máquina. La telemetría está desactivada por defecto, y el endpoint, las credenciales, el muestreo y el agrupado salen de las variables estándar OTEL_EXPORTER_OTLP_*, que leen los propios exportadores. Consulta OpenTelemetry.
| Flag | Tipo | Predeterminado | Variable | Descripción |
|---|---|---|---|---|
--telemetry | bool | false | GITLAB_MCP_TELEMETRY | Exporta trazas, métricas y logs de OpenTelemetry por OTLP. OTEL_SDK_DISABLED=true lo veta diga lo que diga el flag. Un pipeline de telemetría que no arranca se registra, y el servidor sigue sirviendo |
--telemetry-identity | string | none | GITLAB_MCP_TELEMETRY_IDENTITY | Qué registra la telemetría sobre quién hizo una llamada: none no registra a nadie, pseudonymous un resumen HMAC por proceso que correlaciona las llamadas de una persona sin nombrarla, full el id y el nombre de usuario de GitLab. Un valor que no reconoce se registra en ERROR y no se registra nada sobre quien llama. Consulta Registrar quién hizo la llamada |
--telemetry-identity-rotation | string | (vacío) | GITLAB_MCP_TELEMETRY_IDENTITY_ROTATION | Cuánto vive una clave de seudonimización generada, p. ej. 24h. Vacío o 0 la mantiene lo que dure el proceso, y 30 días (720h) es el techo; un valor que no se puede analizar o que lo supera se registra en ERROR y no se registra nada sobre quien llama. Se ignora, con un aviso al arrancar, cuando GITLAB_MCP_TELEMETRY_IDENTITY_KEY está definida |
--telemetry-tool-name | string | auto | GITLAB_MCP_TELEMETRY_TOOL_NAME | Si gen_ai.tool.name es una dimensión de métrica: auto la mantiene en las superficies dinámica y meta y la quita en la individual, donde un millar de herramientas agotaría el límite de cardinalidad del SDK; on y off la fuerzan. Un valor que no reconoce se registra y se lee como auto |
Flags del modo HTTP
Sección titulada «Flags del modo HTTP»Los 42 flags siguientes solo los lee un servidor que sirve HTTP; lo que hace con ellos una ejecución stdio se describe en Qué flags lee cada transporte. Se agrupan como los agrupa --help.
Listener y transporte
Sección titulada «Listener y transporte»| Flag | Tipo | Predeterminado | Variable | Descripción |
|---|---|---|---|---|
--http-addr | string | :8080 | ninguna | Dirección de escucha. host:port escucha por TCP (localhost:8080, :9090, 127.0.0.1:8080); un valor que contiene un separador de ruta (/run/gitlab-mcp.sock) escucha en un socket unix, lo que elimina el tramo de red hasta un proxy de la misma máquina en vez de cifrarlo. Consulta Escuchar en un socket unix o con TLS |
--http-socket-mode | string | (vacío) | ninguna | Modo de permisos, en octal, para un socket unix indicado en --http-addr: de 0001 a 0777, con o sin prefijo 0o. Vacío significa 0660, que deja conectar al propietario y al grupo y a nadie más, así que un proxy inverso llega al servidor compartiendo grupo con él |
--tls-cert | string | (vacío) | ninguna | Fichero de certificado PEM. Sirve HTTPS en el propio listener, para un despliegue cuyo proxy no comparte máquina. Requiere --tls-key, y cada uno se rechaza sin el otro. El par se carga al arrancar, así que una errata falla ahí; después, los dos ficheros se comprueban en cada handshake y se releen cuando cualquiera cambia, de modo que una rotación no necesita reinicio, y un par que no carga conserva el certificado anterior con un aviso. TLS 1.2 es el mínimo |
--tls-key | string | (vacío) | ninguna | Fichero de clave privada PEM que corresponde a --tls-cert |
--stateless | bool | true | ninguna | HTTP streamable sin sesiones (SEP-2567), la única forma en que se sirve el protocolo 2026-07-28 por HTTP: sin Mcp-Session-Id, cada POST autónomo, GET y DELETE respondidos con 405. --stateless=false restaura las sesiones con estado heredadas y avisa al arrancar. Consulta Modo sin estado |
--json-response | bool | false | ninguna | Responde con cuerpos application/json en lugar de text/event-stream (SSE). Un cuerpo JSON lleva una respuesta y ninguna otra trama, así que las notificaciones de progreso se descartan con --stateless y solo llegan a un cliente con estado por un stream GET que mantenga abierto; el arranque avisa siempre que se activa el flag |
--max-request-body-bytes | int64 | 0 | ninguna | Mayor cuerpo de petición HTTP streamable, en bytes; 0 usa el valor predeterminado del SDK (4 MiB). Un cuerpo mayor se rechaza con 413, y un valor negativo al arrancar. En stdio, ese mismo mensaje lo acota GITLAB_MCP_STDIO_MAX_LINE_BYTES |
--session-timeout | duration | 30m | GITLAB_MCP_SESSION_TIMEOUT | Timeout de sesión MCP inactiva, como mucho 24h. Solo se aplica con --stateless=false, porque con el transporte sin estado por defecto la sesión de cada POST termina con su respuesta. Una sesión que ningún cliente borra ocupa una de las plazas de sesión del proceso hasta que caduca, y con 0 hasta que el pool desaloja su credencial, de lo que avisa el arranque |
--http-idle-timeout | duration | 0 | ninguna | Timeout de conexión inactiva del servidor HTTP. 0 desactiva el cierre por inactividad, así que --session-timeout es la vida efectiva; un valor positivo recicla antes las conexiones inactivas, y uno negativo se rechaza |
Conexión con GitLab
Sección titulada «Conexión con GitLab»| Flag | Tipo | Predeterminado | Variable | Descripción |
|---|---|---|---|---|
--gitlab-url | list | (vacío) | GITLAB_URL | URL de la instancia de GitLab. Obligatoria en modo HTTP, por el flag o por GITLAB_URL, salvo que se pase --allow-any-gitlab-url: un despliegue que no ha dicho a qué GitLab sirve haría sus peticiones al host que nombre quien llama en GITLAB-URL, con el token que esa persona aporte. Repetible, o separada por comas (la variable admite la misma lista): publicar varias las lista todas en el campo authorization_servers de RFC 9728 y convierte GITLAB-URL en una elección obligatoria entre ellas, porque elegir por quien llama enviaría su token a una instancia que nunca nombró; un valor que nombre cualquier otra se rechaza, no se ignora. Consulta Publicar más de una instancia |
--allow-any-gitlab-url | bool | false | ninguna | Arranca sin publicar ninguna instancia y deja que GITLAB-URL nombre cualquier host. La respuesta vuelve a quien llama, así que esto convierte el servidor en un proxy para cualquiera que alcance el listener: es para el despliegue local de un único usuario en el que quien opera es quien llama, y se rechaza salvo que --http-addr escuche en una dirección de loopback o en un socket unix. Avisa al arrancar incluso ahí, y no tiene variable a propósito, para que un despliegue que lo usa lo diga en su propia línea de comandos. No amplía a qué pueden resolver esos hosts: una instancia nombrada por quien llama en una dirección privada, de loopback o de enlace local sigue necesitando --allow-private-instances. Un --gitlab-url pasado junto a él gana, y entonces no cambia nada |
--skip-tls-verify | bool | false | GITLAB_MCP_SKIP_TLS_VERIFY | Omite la verificación del certificado TLS al llamar a GitLab (saliente; sin relación con --tls-cert). --auth-mode=oauth lo rechaza para cualquier instancia que no sea loopback, porque los tokens bearer se reenvían allí en cada llamada: instala la CA en el almacén de confianza del sistema, o apunta SSL_CERT_FILE a un paquete de certificados, en su lugar |
--tier | string | (vacío) | GITLAB_MCP_TIER | Fuerza el nivel de licencia: free (o ce), premium o ultimate, usado tal cual sin comprobar la licencia. Vacío lo detecta por entrada del pool de token y URL, a partir de la licencia de la instancia y después de los planes de los namespaces, con free como último recurso y un aviso cuando la instancia es una compilación Enterprise Edition. La variable solo puede fijar un nivel, nunca deshacerlo |
--ignore-scopes | bool | false | GITLAB_MCP_IGNORE_SCOPES | Omite el filtro de scopes y la reducción a solo lectura y registra todas las herramientas que permita el nivel. Los scopes del token se siguen leyendo, así que uno que no lleva ni read_api ni api se sigue rechazando, y la concesión de un token de grano fino sigue decidiendo lo que se le muestra |
Superficie de herramientas y modos de protección
Sección titulada «Superficie de herramientas y modos de protección»| Flag | Tipo | Predeterminado | Variable | Descripción |
|---|---|---|---|---|
--tool-surface | string | (vacío) | GITLAB_MCP_TOOL_SURFACE | Catálogo de herramientas: dynamic, que es lo que sirve el valor vacío, meta o individual. Consulta Resumen de herramientas |
--capability-surface | string | full | GITLAB_MCP_CAPABILITY_SURFACE | Recursos y prompts: full, o minimal, que conserva el manifiesto gitlab://tools y deja fuera los recursos opcionales de datos de GitLab, las guías de flujo de trabajo y los prompts |
--meta-param-schema | string | opaque | GITLAB_MCP_META_PARAM_SCHEMA | Estrategia del esquema de entrada de las meta-herramientas: opaque, compact (unas 8,7 veces el tamaño de opaque) o full (unas 18,3 veces). Solo afecta a los esquemas de las meta-herramientas; la forma exacta de llamada de cada acción sigue disponible en gitlab://tools/{id} |
--embedded-resources | bool | true | GITLAB_MCP_EMBEDDED_RESOURCES | Incrusta la URI canónica gitlab:// del recurso en los resultados de las herramientas de tipo get; false la omite |
--exclude-tools | string | (vacío) | GITLAB_MCP_EXCLUDE_TOOLS | Nombres de herramienta, de grupo o IDs canónicos de acción, separados por comas, que se retiran en todas las superficies y de los recursos, suscripciones, prompts y completados de argumentos que devuelven los mismos objetos. Las mismas grafías alcanzan las utilidades independientes (gitlab_interactive, interactive.issue_create, discover_project.resolve). Una entrada que no nombra nada es un aviso, no un rechazo, que se escribe la primera vez que se construye cada catálogo, y el nivel y la reducción por scopes del token forman parte de lo que es un catálogo, así que puede repetirse |
--read-only | bool | false | GITLAB_MCP_READ_ONLY | Retira todas las acciones que modifican; las lecturas siguen funcionando en todas las superficies. Gana a --safe-mode cuando se activan los dos |
--safe-mode | bool | false | GITLAB_MCP_SAFE_MODE | Intercepta todas las acciones que modifican y responde con una tarjeta de vista previa, que nombra la acción (la herramienta en la superficie individual) y muestra en JSON los argumentos que habría enviado, en lugar de ejecutarla; las lecturas siguen funcionando |
Autenticación
Sección titulada «Autenticación»| Flag | Tipo | Predeterminado | Variable | Descripción |
|---|---|---|---|---|
--auth-mode | string | legacy | GITLAB_MCP_AUTH_MODE | legacy (la cabecera PRIVATE-TOKEN, o Authorization: Bearer) u oauth (verificación bearer de RFC 9728), que exige un --gitlab-url https para cada instancia publicada (http solo en loopback) y un --public-url válido. Consulta Modo OAuth |
--public-url | string | (vacío) | GITLAB_MCP_PUBLIC_URL | Origen accesible desde fuera de este despliegue (scheme://host[:port][/path]): https (http solo para un host de loopback), sin fragmento y sin barra final. Obligatoria con --auth-mode=oauth, donde es el identificador de recurso protegido de RFC 9728 y de ella se deriva la URL de metadatos. Opcional en modo legacy, donde su origen se añade a los orígenes de confianza |
--oauth-cache-ttl | duration | 15m | GITLAB_MCP_OAUTH_CACHE_TTL | Cuánto se guarda en caché la identidad de un token OAuth verificado, de 1m a 2h; solo se usa con --auth-mode=oauth. La caché guarda como mucho 10.000 identidades sea cual sea el TTL, y cuando está llena descarta una caducada o, si no la hay, la usada hace más tiempo |
--oauth-client-uid | string | (vacío) | GITLAB_MCP_OAUTH_CLIENT_UID | uids de aplicaciones OAuth de GitLab, separados por comas, cuyos tokens admite este despliegue. Vacío admite cualquier credencial que acepte la instancia; ponerlo rechaza también los tokens de acceso personal, que no pertenecen a ninguna aplicación. Sustituye a la vinculación de audiencia, que GitLab no ofrece; consulta el ADR-0019 |
--revalidate-interval | duration | 15m | GITLAB_MCP_SESSION_REVALIDATE_INTERVAL | Cada cuánto se revalida contra GitLab una credencial del pool, como mucho 24h. 0 detiene la comprobación periódica, pero una entrada cuya credencial tenga más de 1h se reconstruye igualmente, lo que repite la sonda y termina cualquier sesión con estado que tenga |
--resource-documentation | string | (vacío) | ninguna | URL https publicada como resource_documentation de RFC 9728. Apúntala a una página que describa tu propia aplicación OAuth (su client ID y sus URI de redirección registradas), para que un cliente que llega desde un desafío 401 encuentre lo que necesita: RFC 9728 no define ningún campo para un identificador de cliente, así que esta es la única forma sancionada de llevar a un cliente hasta uno. Vacío publica la página Aplicación OAuth de este proyecto |
--resource-policy-uri | string | (vacío) | ninguna | URL https publicada como resource_policy_uri de RFC 9728: tu página sobre lo que hace este despliegue con los datos a los que llega con los tokens que acepta. Vacío omite el campo, el valor correcto para un despliegue sin esa página, porque un campo opcional ausente es mejor que un enlace roto en una pantalla de consentimiento |
--resource-tos-uri | string | (vacío) | ninguna | URL https publicada como resource_tos_uri de RFC 9728: tus condiciones de servicio. Vacío omite el campo |
Las tres URLs --resource-* se comprueban al arrancar en cualquiera de los dos modos, porque se publican en cuanto se activa OAuth: cada una debe ser una URL https absoluta, o http en un host de loopback.
Límites y pool
Sección titulada «Límites y pool»| Flag | Tipo | Predeterminado | Variable | Descripción |
|---|---|---|---|---|
--max-http-clients | int | 100 | GITLAB_MCP_MAX_HTTP_CLIENTS | Máximo de entradas (token, URL de GitLab) que guarda el pool, de 1 a 10000. Acota entradas, no las sesiones ni las llamadas que retienen: esas las acota el proceso según su límite de descriptores, 192 llamadas retenidas y 96 sesiones con estado a la vez bajo un límite duro de 1024, y ningún flag mueve ninguno de los dos. Consulta Peticiones retenidas a la vez |
--pool-idle-timeout | duration | 1h | GITLAB_MCP_POOL_IDLE_TIMEOUT | Recupera una entrada de credencial del pool tras este tiempo sin usarse, como mucho 24h; 0 mantiene las entradas hasta que el límite de tamaño las desaloje. Una entrada con una suscripción viva nunca está inactiva según esta medida |
--action-timeout | duration | 65m | GITLAB_MCP_ACTION_TIMEOUT | Cancela una acción que siga en marcha tras este tiempo, como mucho 24h; 0 lo desactiva. El timeout se aplica también en stdio, donde la variable es la única forma de fijarlo. Está por encima de la espera más larga que ofrece cualquier acción (una espera de pipeline se limita a 3600 s), así que termina un manejador que ninguna otra cosa acota y no una espera legítima, y acota también una transferencia de ficheros |
--drain-delay | duration | 0 | GITLAB_MCP_DRAIN_DELAY | Tras SIGTERM, mantiene el listener abierto y responde /health con 503 draining durante este tiempo antes de cerrarlo, para que un balanceador que sondea /health saque antes la instancia de la rotación. 0 cierra al instante, y el máximo es 5m. Ponlo al menos en un intervalo de sondeo; consulta Verificación de salud |
--rate-limit-rps | float | 10 | GITLAB_MCP_RATE_LIMIT_RPS | Límite de tasa por credencial, en peticiones por segundo, sobre toda llamada que llega a GitLab (tools/call, resources/read, resources/subscribe, subscriptions/listen, prompts/get), más completion/complete en un bucket propio con diez veces la tasa y el burst, y tools/list en un bucket propio que se rellena diez veces más despacio, con el mismo burst. Un listado se cobra además primero, en las herramientas que lleva, a un bucket que comparte todo el proceso: 3000 herramientas por segundo con 48000 disponibles, no configurable. 0 los desactiva todos, y el máximo es 1000. Stdio ignora el flag y lo dice: allí el interruptor es GITLAB_MCP_RATE_LIMIT_RPS, que por defecto vale 0. Consulta Limitación de tasa |
--rate-limit-burst | int | 40 | GITLAB_MCP_RATE_LIMIT_BURST | Tamaño del token bucket, como mucho 10000. Mientras --rate-limit-rps está por encima de 0 debe ser al menos 1 |
--auth-failure-limit | int | 10 | GITLAB_MCP_AUTH_FAILURE_LIMIT | Autenticaciones fallidas que una dirección puede producir dentro de --auth-failure-window antes de quedar bloqueada el resto de la ventana, de 0 a 100000. 0 desactiva este presupuesto en lugar de bloquear al primer fallo. Consulta Presupuestos de autenticación |
--auth-failure-window | duration | 1m | GITLAB_MCP_AUTH_FAILURE_WINDOW | Ventana en la que cuenta el presupuesto de fallos, y el paso con el que se construye la escalada de credenciales distintas: una ventana, después diez, después sesenta. Como mucho 24h; 0 desactiva los dos presupuestos, porque sin ella la escalada no tiene paso |
--auth-distinct-token-limit | int | 50 | GITLAB_MCP_AUTH_DISTINCT_TOKEN_LIMIT | Credenciales distintas que una dirección puede tener rechazadas dentro de --auth-distinct-token-window antes de quedar bloqueada, cada vez durante más tiempo, de 0 a 100000; 0 desactiva este presupuesto. Una persona tiene un token y una flota tras un NAT tiene uno cada máquina, así que solo un ataque de rociado de credenciales alcanza este recuento. Una credencial que el pool ya tiene se sigue sirviendo desde una dirección bloqueada |
--auth-distinct-token-window | duration | 10m | GITLAB_MCP_AUTH_DISTINCT_TOKEN_WINDOW | Ventana en la que cuenta el presupuesto de credenciales distintas, como mucho 24h; 0 desactiva ese presupuesto |
--trusted-origins | string | (vacío) | GITLAB_MCP_TRUSTED_ORIGINS | Orígenes absolutos (scheme://host[:port]; una IP sirve para un despliegue local), separados por comas, autorizados a hacer peticiones cross-origin desde un navegador. * acepta cualquier origen y desactiva la protección. Vacío no añade ninguno, aunque el origen de --public-url es de confianza de todos modos. Una entrada mal formada impide arrancar. Consulta Protección cross-origin |
--trusted-proxy-header | string | (vacío) | ninguna | Cabecera HTTP que lleva la dirección real del cliente tras un proxy inverso (p. ej. CF-Connecting-IP, X-Forwarded-For, X-Real-IP), para que los presupuestos de autenticación carguen a quien llama y no al proxy. Solo se cree en una conexión desde una dirección de --trusted-proxies, que exige |
--trusted-proxies | string | (vacío) | ninguna | Direcciones o rangos CIDR, separados por comas, de los proxies inversos cuya --trusted-proxy-header se cree (p. ej. 127.0.0.1,10.0.0.0/8). Desde cualquier otro par la cabecera se ignora y se carga al propio par, así que quien llega directamente al listener no puede elegir la dirección contra la que cuentan sus fallos. Con X-Forwarded-For el valor se lee desde la derecha, saltando los saltos que están en la lista, así que el primer salto que no está en ella es el cliente; un salto que no es una dirección carga al par. Obligatoria junto a --trusted-proxy-header, y se rechaza sin ella |
Modos de funcionamiento
Sección titulada «Modos de funcionamiento»Modo stdio (por defecto)
Sección titulada «Modo stdio (por defecto)»El servidor lee su configuración del entorno y habla JSON-RPC por la entrada y la salida estándar, que es como lo ejecutan clientes MCP como VS Code, Claude Desktop y Cursor. Los ajustes que define este proyecto se llaman GITLAB_MCP_<NAME>; GITLAB_URL, GITLAB_TOKEN y todas las variables OTEL_* conservan su nombre sin prefijo, y GITLAB_URL vale por defecto https://gitlab.com, así que solo hace falta para una instancia autogestionada.
# Configuración desde el entornoexport GITLAB_TOKEN="glpat-xxxxxxxxxxxxxxxxxxxx"gitlab-mcp-server
# Configuración desde ~/.gitlab-mcp-server.env, o desde un fichero nombrado en GITLAB_MCP_ENV_FILEgitlab-mcp-serverUn .env en el directorio actual no se lee: ese directorio pertenece al repositorio que abrió el cliente, no a quien opera el servidor. Si existe, se nombra en WARN al arrancar. Las grafías que tenían las variables antes de 2.8.0 no las lee nada desde 3.1.0: una que siga definida se nombra al arrancar con la variable a la que hay que renombrarla, y GITLAB_READ_ONLY, GITLAB_SAFE_MODE y EXCLUDE_TOOLS impiden el arranque, porque ignorar una serviría lo que retiraba. La referencia de variables de entorno tiene la regla completa.
Modo HTTP
Sección titulada «Modo HTTP»El servidor escucha en un endpoint HTTP, y cada cliente envía su propio token de GitLab en cada petición, en la cabecera PRIVATE-TOKEN o como Authorization: Bearer, así que no hace falta GITLAB_TOKEN al arrancar. La instancia no es opcional: nombra la que sirve este despliegue, o las varias, con --gitlab-url o GITLAB_URL. Publicar varias convierte la cabecera GITLAB-URL en una elección obligatoria entre ellas, y no publicar ninguna solo es posible con --allow-any-gitlab-url. Consulta Modo servidor HTTP para el despliegue en sí.
# Una instancia (todos los clientes usan la URL fija; reemplázala para GitLab autogestionado)gitlab-mcp-server --http --gitlab-url=https://gitlab.comgitlab-mcp-server --http --gitlab-url=https://gitlab.com --http-addr=localhost:9090gitlab-mcp-server --http --gitlab-url=https://gitlab.com --max-http-clients=50 --session-timeout=1hgitlab-mcp-server --http --gitlab-url=https://gitlab.com --auth-mode=oauth --public-url=https://mcp.example.com --oauth-cache-ttl=15m
# HTTP streamable sin estado (el predeterminado) con respuestas JSON planasgitlab-mcp-server --http --gitlab-url=https://gitlab.com --json-response
# Sesiones con estado heredadas con un tope de 1 MiB en el cuerpo de la peticióngitlab-mcp-server --http --gitlab-url=https://gitlab.com --stateless=false --max-request-body-bytes=1048576
# Varias instancias (la cabecera GITLAB-URL pasa a ser obligatoria y debe nombrar una de ellas)gitlab-mcp-server --http --gitlab-url=https://gitlab.com,https://gitlab.example.comPrimer arranque sin configuración
Sección titulada «Primer arranque sin configuración»Si se arranca a mano en un terminal, o con doble clic, en modo stdio y GITLAB_TOKEN o GITLAB_URL siguen sin definir tras leer los ficheros dotenv (basta con que falte una), el servidor imprime en stderr qué es y qué necesita, espera a que se pulse Enter y sale con 0. La espera importa en Windows, donde un programa de consola abierto con doble clic cierra su ventana en cuanto termina, así que un mensaje impreso justo antes de terminar es un mensaje que nadie lee.
Un cliente MCP nunca llega a esa pantalla: un cliente conecta tuberías, no un terminal, que es la prueba que usa el servidor. Sustituyó a un asistente de configuración interactivo que escribía ~/.gitlab-mcp-server.env; la configuración MCP vive en el propio JSON del cliente, que es donde la pone Primeros pasos.
Búsqueda de herramientas
Sección titulada «Búsqueda de herramientas»--tool-search busca en el catálogo canónico de acciones, no en las herramientas registradas de un servidor, y termina. El catálogo es el mismo en todas las superficies (la superficie dinámica por defecto registra solo dos herramientas), así que las acciones encontradas también lo son; la superficie solo decide cómo nombra cada fila la llamada. No necesita credenciales de GitLab y no hace ninguna petición.
- La consulta se divide por espacios, y cada término debe aparecer, sin distinguir mayúsculas, en el ID canónico de una acción, su nombre de herramienta individual, su nombre de meta-herramienta, su descripción, sus alias o sus etiquetas.
- La superficie y el nivel salen de
--tool-surfacey--tiersi se pasan, y si no deGITLAB_MCP_TOOL_SURFACEyGITLAB_MCP_TIER, leídas de los mismos ficheros dotenv que lee el servidor, así que un despliegue stdio busca lo que sirve. Sin ninguno de los dos, el nivel esfree, así que una acción que solo sirve un nivel superior necesita--tier. - Una superficie o un nivel que no se pueden analizar salen con
1.
Los resultados van a stdout, ordenados por ID canónico, bajo una línea que dice cómo llamar a una acción listada en esa superficie:
Found <n> action(s) matching "issue list" (tier free, dynamic surface):Call gitlab_execute_action with {"action": "<ACTION>", "params": {...}}. TOOL is the name the individual surface would register.
ACTION TOOL DESCRIPTIONACTION es el ID canónico, que es lo que recibe gitlab_execute_action en la superficie dinámica. TOOL es el nombre de la herramienta individual en las superficies dinámica e individual, o la meta-herramienta del grupo seguida de action=<name> en la superficie meta; - marca una acción que la superficie individual no registra. DESCRIPTION se corta en 80 caracteres. Una consulta que no coincide con nada imprime No actions found matching con la consulta, el nivel y la superficie.
Modo de apagado (shutdown)
Sección titulada «Modo de apagado (shutdown)»--shutdown termina todas las demás instancias en marcha de este binario y sale. Está pensado para actualizadores externos, como pe-agnostic-store, que detienen los servidores en marcha antes de reemplazar el binario en disco.
gitlab-mcp-server --shutdown- Lista los procesos de la máquina y se queda con los que tienen su mismo nombre, una vez quitados de ambos un sufijo de plataforma como
-linux-amd64y una extensión.exe, dejándose fuera a sí mismo. - Si no encuentra ninguno, sale con
0sin escribir nada. - Envía a cada uno una terminación ordenada:
SIGTERMen Unix,TerminateProcessen Windows. - Comprueba cada 200 ms, durante un máximo de cinco segundos, si han terminado.
- Mata a la fuerza los que sigan en marcha cuando pasan los cinco segundos.
- Sale con
0. Solo un fallo al listar los procesos sale con1.
Escribe estas líneas en stderr:
shutdown: found N running instance(s), al encontrarlasshutdown: all instances terminated, cuando no queda ninguna en marchashutdown: force-killed M instance(s), cuando hubo que matar algunashutdown: error listing processes: <error>, cuando falló el listado
Modo sonda (probe)
Sección titulada «Modo sonda (probe)»--probe es el HEALTHCHECK de la imagen de contenedor (cada 30 s, con un timeout de cinco segundos). Pregunta al /health de la instancia en marcha y sale con 0 cuando responde 200, sin que haya que decirle dónde escucha esa instancia.
# Lo que ejecuta la imagen: encuentra el servidor en este contenedor y sondea su listenergitlab-mcp-server --probe
# Sondear un listener conocido: una URL, un socket unix, o host:portgitlab-mcp-server --probe --tls-cert=/etc/ssl/mcp.crt https://127.0.0.1:8443gitlab-mcp-server --probe unix:/run/gitlab-mcp/server.sockgitlab-mcp-server --probe 127.0.0.1:9090Sin destino:
- Encuentra las demás instancias de este binario con la misma búsqueda que usa
--shutdown, y se salta las invocaciones de sonda, apagado, versión y ayuda y cualquier proceso cuya línea de comandos no puede leer. - Lee
--http-addr,--tls-cert,--transporty--httpde la línea de comandos de cada instancia, empezando por el pid más bajo. Un argumento tras un--suelto no se lee, porque tampoco era un flag para ese proceso. - Resuelve
--transport autocomo lo hizo el servidor, leyendo el descriptor de fichero 0 de la instancia en procfs:/dev/nullsignifica HTTP, y cualquier otra cosa stdio. Donde no se puede leer procfs, se supone HTTP y decide la conexión. - Una instancia que sirve stdio no tiene nada que sondear y se da por sana mientras está en marcha.
- Una instancia HTTP se sondea donde escucha. Un host sin especificar, como
:8080,0.0.0.0:8080o[::]:8080, se alcanza en127.0.0.1, a una ruta se conecta como socket unix, y--tls-certsignifica HTTPS. Un listener TLS se verifica fijando el certificado: debe presentar justo el certificado que nombra su--tls-cert, que la sonda lee del mismo fichero y usa como única raíz de confianza, así que un certificado autofirmado en una dirección de loopback se puede sondear sin fiarse de lo que responda ahí. - La primera instancia, por orden de pid, que sirve stdio o responde
200da la sonda por sana. Si ninguna lo hace, o no hay ninguna instancia en marcha, sale con1.
Un destino dado tras los flags se sondea en su lugar: una URL http:// o https:// (su ruta, o /health si no nombra ninguna), unix:<path> o una ruta suelta para un socket unix, o host:port para HTTP plano. Un destino https:// se fija al --tls-cert de la propia sonda, que debe ir antes del destino, y sin él recibe la verificación estándar contra las raíces del sistema. Un destino que no es ninguna de estas cosas sale con 2.
Cada intento está acotado a tres segundos, y la ejecución entera a cuatro, dentro del timeout de cinco segundos de la imagen: los intentos van uno tras otro, así que dos listeners inalcanzables a tres segundos cada uno lo superarían y la sonda moriría sin veredicto. La sonda nunca pasa por un proxy, y escribe una línea en stderr, con el prefijo probe:, que dice qué instancia respondió o por qué no respondió ninguna. Un listener que escucha en el puerto 0 no se puede descubrir, porque la línea de comandos dice 0; dale a la sonda la dirección que indica el log del servidor.
Ejemplos
Sección titulada «Ejemplos»# Imprimir la versióngitlab-mcp-server --version
# Mostrar la ayuda completa con todos los flags, las variables y ejemplos de configuración JSONgitlab-mcp-server --help
# Arrancar el servidor stdio (lee ~/.gitlab-mcp-server.env para lo que falte en el entorno)gitlab-mcp-server
# Arrancar el servidor HTTP en otro puertogitlab-mcp-server --http --gitlab-url=https://gitlab.com --http-addr=:9090
# Varias instancias (los clientes eligen una con la cabecera GITLAB-URL)gitlab-mcp-server --http --gitlab-url=https://gitlab.com,https://gitlab.example.com --http-addr=:8080
# Despliegue local de un único usuario: ninguna instancia publicada, GITLAB-URL puede nombrar cualquier hostgitlab-mcp-server --http --allow-any-gitlab-url --http-addr=127.0.0.1:8080
# GitLab autogestionado con certificado autofirmado y un timeout de sesión más largogitlab-mcp-server --http --gitlab-url=https://gitlab.example.com --skip-tls-verify --session-timeout=2h
# Una herramienta por accióngitlab-mcp-server --http --gitlab-url=https://gitlab.com --tool-surface=individual
# La superficie dinámica con la superficie reducida de recursos y promptsgitlab-mcp-server --http --gitlab-url=https://gitlab.com --tool-surface=dynamic --capability-surface=minimal
# Encontrar las acciones que listan issues, en la superficie que esté configuradagitlab-mcp-server --tool-search "issue list"
# Buscar en el catálogo Ultimate desde un despliegue Freegitlab-mcp-server --tier=ultimate --tool-search "epic"
# Terminar todas las instancias en marcha (lo usan los actualizadores externos)gitlab-mcp-server --shutdown
# Verificación de salud del contenedor: sondear la instancia en marcha donde escuchagitlab-mcp-server --probeConsulta Herramientas dinámicas para ver qué registra la superficie por defecto y cómo llegan al catálogo gitlab_find_action y gitlab_execute_action.
Códigos de salida
Sección titulada «Códigos de salida»| Código | Significado |
|---|---|
0 | Un final normal: un apagado por señal (SIGINT o SIGTERM), --version, -h/--help, un --tool-search completado, --shutdown haya encontrado o no algo que detener, un --probe que obtuvo respuesta o encontró una instancia que sirve stdio, y la pantalla de primer arranque una vez pulsado Enter |
1 | Un error de configuración (entre ellos, una ejecución stdio que recibe --read-only, --safe-mode o --exclude-tools pidiendo retirar algo o un --gitlab-url que nombra otra instancia, y una ejecución HTTP que no nombra ninguna instancia sin --allow-any-gitlab-url), un error en el que se detiene el servidor, un --tool-search cuya superficie o nivel no se pueden analizar, un --shutdown que no pudo listar los procesos, o un --probe al que nadie respondió |
2 | Un flag que el binario no define o un valor que su tipo no puede analizar, --transport con un valor distinto de stdio, http o auto, o --probe con un destino que no es una URL, una ruta de socket ni host:port |
Páginas relacionadas
Sección titulada «Páginas relacionadas»- Configuración: las opciones que fijan la mayoría de despliegues y cómo se combinan.
- Referencia de variables de entorno: todas las variables que lee el servidor.
- Modo servidor HTTP: el despliegue HTTP, su autenticación y sus límites.
- Primeros pasos: el primer arranque, paso a paso.