npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ttpears/gitlab-mcp-server

v1.15.0

Published

GitLab MCP Server with GraphQL discovery

Readme

GitLab MCP Server

npm version npm downloads CI Container License: MIT

A community MCP server for GitLab — works with any GitLab tier (Free, Premium, Ultimate), no GitLab Duo required. PAT-based auth. Streamable HTTP and stdio transports.

npx @ttpears/gitlab-mcp-server

Choose your deployment

| You're running | Go to | |---|---| | Claude Code or another IDE/AI tool, just for you | Solo IDE | | LibreChat for a team with a service-account read token | LibreChat — service-account reads | | LibreChat where every operation should use the calling user's token | LibreChat — strict per-user |


Solo IDE

Claude Code (recommended)

claude mcp add gitlab \
  --env GITLAB_URL=https://gitlab.com \
  --env GITLAB_TOKEN=glpat-your-pat \
  -- npx -y @ttpears/gitlab-mcp-server

--scope controls where the configuration lives:

  • --scope local (default) — only this user, only this project
  • --scope user — shared across all of your projects
  • --scope project — written to .mcp.json in the project root, intended for team check-in

For team check-in, use a ${VAR} placeholder so the PAT itself stays out of git:

{
  "mcpServers": {
    "gitlab": {
      "command": "npx",
      "args": ["-y", "@ttpears/gitlab-mcp-server"],
      "env": {
        "GITLAB_URL": "https://gitlab.com",
        "GITLAB_TOKEN": "${GITLAB_TOKEN}"
      }
    }
  }
}

Each contributor exports GITLAB_TOKEN in their shell; Claude Code expands it on launch.

Cold start

If launching via npx adds noticeable latency, install once:

npm install -g @ttpears/gitlab-mcp-server

…and replace npx -y @ttpears/gitlab-mcp-server with gitlab-mcp-server in your config.

Claude Desktop

Add to claude_desktop_config.json:

{
  "mcpServers": {
    "gitlab": {
      "command": "npx",
      "args": ["-y", "@ttpears/gitlab-mcp-server"],
      "env": {
        "GITLAB_URL": "https://gitlab.com",
        "GITLAB_TOKEN": "glpat-your-pat"
      }
    }
  }
}

LibreChat — service-account reads

A read-only service token covers reads (so anyone in the workspace can ask questions). Each user supplies their own PAT for writes through LibreChat's customUserVars.

LibreChat's documented extension point is docker-compose.override.yml — the fragments below assume you're adding gitlab-mcp there alongside LibreChat's own api, mongodb, etc.

.env

GITLAB_URL=https://gitlab.example.com
GITLAB_READ_TOKEN=glpat-readonly-service-token   # read_api scope only

Use https://gitlab.com for SaaS GitLab; use your own host for self-hosted.

docker-compose.override.yml

services:
  gitlab-mcp:
    image: ghcr.io/ttpears/gitlab-mcp:1.14.0
    env_file:
      - .env
    networks:
      - librechat
    restart: unless-stopped

env_file reads GITLAB_URL and GITLAB_READ_TOKEN from .env. No port mapping needed — LibreChat's api container reaches gitlab-mcp over the shared librechat network. Add ports: ["8008:8008"] only if you need to hit it from the host (e.g. for curl http://localhost:8008/health).

Then:

docker compose -f docker-compose.yml -f docker-compose.override.yml up -d gitlab-mcp api

api is restarted alongside so it re-reads librechat.yaml.

librechat.yaml

mcpServers:
  gitlab:
    type: streamable-http
    url: http://gitlab-mcp:8008/
    startup: false                # don't connect until the user supplies their PAT
    initTimeout: 30000
    timeout: 120000
    headers:
      Authorization: "Bearer {{GITLAB_PAT}}"
      X-GitLab-Url: "{{GITLAB_URL_OVERRIDE}}"   # optional; lets a user point at a different GitLab
    customUserVars:
      GITLAB_PAT:
        title: "GitLab Personal Access Token"
        description: "Your GitLab PAT with api scope. Used for issues, MRs, and comments you create or edit."
      GITLAB_URL_OVERRIDE:
        title: "GitLab URL (optional)"
        description: "Leave blank to use the workspace default. Override only if your account is on a different GitLab instance."

initTimeout / timeout are forgiving defaults for slower internal networks and large schemas — drop them if SaaS GitLab feels snappy.

Server-side env vars use ${VAR}. Per-user vars use {{VAR}}. They are not interchangeable.


LibreChat — strict per-user

Every call must carry a user PAT. No service-account fallback. Reads as well as writes are gated on the user's token.

Add MCP Server (UI path — recommended)

  1. Host gitlab-mcp somewhere LibreChat can reach. For a quick standalone host:

    docker run -d --restart unless-stopped \
      -p 8008:8008 \
      -e GITLAB_URL=https://gitlab.example.com \
      --name gitlab-mcp \
      ghcr.io/ttpears/gitlab-mcp:1.14.0

    Or, when running alongside LibreChat in the same compose project, drop it into docker-compose.override.yml (no token env vars):

    services:
      gitlab-mcp:
        image: ghcr.io/ttpears/gitlab-mcp:1.14.0
        environment:
          GITLAB_URL: https://gitlab.example.com
        networks:
          - librechat
        restart: unless-stopped
  2. In LibreChat → MCP ServersAdd MCP Server:

    • URL: https://your-host/ (or http://gitlab-mcp:8008/ if same network)
    • Authentication: API Key → check User provides key → header format Bearer
    • Save
  3. Each user fills in their PAT through the MCP Tool Select Dialog when configuring an agent.

librechat.yaml equivalent

mcpServers:
  gitlab:
    type: streamable-http
    url: http://gitlab-mcp:8008/
    startup: false
    initTimeout: 30000
    timeout: 120000
    headers:
      Authorization: "Bearer {{GITLAB_PAT}}"
    customUserVars:
      GITLAB_PAT:
        title: "GitLab Personal Access Token"
        description: "Your GitLab PAT with api scope."

The container needs no env-configured token at all in this mode — every request is rejected unless Authorization: Bearer … is present.


Hosting for a remote LibreChat

The server speaks plain HTTP. For LibreChat-as-a-service or any cross-network deployment, terminate TLS at a reverse proxy. Common patterns:

  • Caddy — auto-TLS via Let's Encrypt:

    mcp.example.com {
      reverse_proxy gitlab-mcp:8008
    }
  • Traefik — Docker labels on the gitlab-mcp service.

  • Cloudflare Tunnel — no public IP needed; expose gitlab-mcp:8008 through the tunnel.

The Authorization and Mcp-Session-Id headers must pass through unchanged. Most defaults handle this fine.


How this differs from GitLab's official MCP server

GitLab ships an official MCP server (Beta) that requires Premium/Ultimate and GitLab Duo.

| | This server | GitLab official | |---|---|---| | GitLab tier | Free, Premium, Ultimate | Premium / Ultimate only | | GitLab Duo required | No | Yes | | Auth | Personal Access Token | OAuth 2.0 Dynamic Client Registration | | Transport | stdio + streamable HTTP | stdio + HTTP | | Multi-user | Per-call PAT or service-account fallback | OAuth per-user | | GraphQL schema discovery | Yes — introspect & run custom queries | No | | Repository browsing & file reading | Yes | No | | Update issues / MRs / notes | Yes | No (create only) | | Delete issues / notes | Yes | No | | CI/CD pipeline management | Yes | Yes | | MR diffs & commits | Yes | Yes | | Time tracking & timelogs | Yes | No | | MR reviewer & approval status | Yes | No | | Iteration / milestone tracking | Yes | No | | Project statistics dashboard | Yes | No | | Group member listing | Yes | No | | Semantic code search | No | Yes (requires additional setup) |

Choose this server for Free/CE, GraphQL flexibility, or LibreChat multi-user. Choose the official server for Premium+Duo with semantic code search, or if you prefer OAuth.


Tools

Search & Discovery

| Tool | Description | |------|-------------| | search_gitlab | Global search across projects, issues, and merge requests | | search_projects | Find repositories by name or description | | search_issues | Search issues globally or within a project (filter by assignee, author, labels, state) | | search_merge_requests | Find merge requests by username or within a project | | search_users | Find team members and contributors | | search_groups | Discover groups and organizations | | search_labels | Search labels in a project or group | | list_group_members | List group members with access levels | | browse_repository | Explore directory structure and files | | get_file_content | Read file contents for code analysis |

Read Operations

| Tool | Description | |------|-------------| | get_project | Detailed project information | | get_issues | List project issues with pagination | | get_merge_requests | List project merge requests with pagination | | get_merge_request_pipelines | Get CI/CD pipelines for a merge request | | get_pipeline_jobs | Get jobs for a specific pipeline | | get_merge_request_diffs | Get diff statistics for a merge request | | get_merge_request_commits | Get commits for a merge request | | get_notes | Get notes/comments on an issue or merge request | | list_milestones | List milestones with progress statistics | | list_iterations | List iterations/sprints (Premium/Ultimate) | | get_time_tracking | Get time estimate, spent, and timelogs | | get_merge_request_reviewers | Get MR approval and reviewer status | | get_project_statistics | Aggregate project stats dashboard | | get_user_issues | Get all issues assigned to a user | | get_user_merge_requests | Get MRs authored by or assigned to a user | | get_work_item | Fetch a work item (issue, task, epic, incident, OKR) by ID with full widget data | | list_work_items | List work items in a group or project, filtered by type and state | | list_broadcast_messages | List instance-wide broadcast messages | | get_broadcast_message | Get a specific broadcast message by ID | | list_my_events | Authenticated user's activity feed — pushes, MRs, comments, approvals | | list_user_events | Another user's public activity feed by username or ID | | list_project_events | Activity events for a specific project | | resolve_path | Resolve a path to a project or group | | get_available_queries | Discover available GraphQL operations | | execute_custom_query | Run custom GraphQL queries |

Write Operations (require user authentication)

| Tool | Description | |------|-------------| | create_issue | Create new issues | | create_merge_request | Create new merge requests | | create_note | Add a comment/note to an issue or merge request | | update_issue | Update title, description, assignees, labels, due date | | update_merge_request | Update title, description, assignees, reviewers, labels | | update_note | Edit the body of an existing comment | | delete_issue | Delete an issue (issue author or maintainer required) | | delete_note | Delete a comment (note author or maintainer required) | | manage_pipeline | Retry or cancel a CI/CD pipeline | | create_broadcast_message | Create a broadcast message (instance admin) | | update_broadcast_message | Update a broadcast message (instance admin) | | delete_broadcast_message | Delete a broadcast message (instance admin) |


Configuration

Environment variables

| Variable | Description | Default | |---|---|---| | GITLAB_URL | GitLab instance URL | https://gitlab.com | | GITLAB_TOKEN | Full-access fallback token (reads + writes) | — | | GITLAB_READ_TOKEN | Read-only fallback token (writes always rejected) | — | | GITLAB_MAX_PAGE_SIZE | Maximum items per page (1–100) | 50 | | GITLAB_TIMEOUT | Request timeout in milliseconds | 30000 | | GITLAB_MCP_PORT | HTTP server port | 8008 | | MCP_TRANSPORT | Transport mode (http for LibreChat) | stdio |

GITLAB_TOKEN and GITLAB_READ_TOKEN are mutually exclusive; setting both is a startup error.

Removed in 1.14.0

  • GITLAB_AUTH_MODE — the three-way enum is gone. Pick your deployment shape by which env var you set; see Choose your deployment.
  • GITLAB_SHARED_ACCESS_TOKEN — rename to GITLAB_TOKEN (full access) or GITLAB_READ_TOKEN (read-only).

Old env vars trigger a deprecation warning at startup and are otherwise ignored.


Troubleshooting

"This operation requires authentication" / "Write operation requires a user token":

  • For LibreChat: check the user filled in their PAT in the MCP Tool Select Dialog (or in their customUserVars).
  • For Claude Code: confirm GITLAB_TOKEN is set in the MCP server's env block.
  • If you set GITLAB_READ_TOKEN, write operations against it are rejected by design — supply per-call user creds for writes.

Connection issues with LibreChat:

  • type: streamable-http (not sse).
  • URL is the Docker service name (http://gitlab-mcp:8008/), not localhost, when LibreChat and gitlab-mcp share a Docker network.
  • docker logs gitlab-mcp shows session init and request lines.

Schema introspection failed:

  • GitLab 12.0+ with GraphQL API enabled.
  • Verify GITLAB_URL is reachable from the container.

Debug logging:

NODE_ENV=development GITLAB_TOKEN=glpat-... npm start

Health check (HTTP mode):

curl http://localhost:8008/health

Changelog

See CHANGELOG.md. Releases before 1.14.0 are in GitHub releases.

License

MIT