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

mcp-server-extended-gitlab

v1.0.6

Published

A server exposing GitLab REST APIs as Model-Context-Protocol (MCP) tools.

Readme

MCP Server Extended GitLab

A small server exposing selected GitLab REST API endpoints as tools for the Model-Context-Protocol. It is built with TypeScript and tested with Jest.

| 🔖 Version | npm | |-----------|-----------------------------------------------| | 🛠 Build | npm run build | | 🧪 Tests | npm test | | 📄 License| MIT |


✨ Features

  • TypeScript 5 with strict compiler options.
  • Express 5 server scaffold.
  • GitLab integration for merge requests, branches, commits, discussions, issues and file content.
  • TDD-first workflow – Jest + ts-jest preconfigured.
  • Hot reload in development via nodemon.
  • Built on the mcp-framework for tools and transports.
  • Server-Sent Events transport for streaming MCP responses.

🚀 Quick Start

npm install

npm test

npm run build

npm start
# -> http://localhost:3000/health  => {"status":"ok"}

Environment Variables

Set the following variables to connect to your GitLab instance:

GITLAB_BASE_URL=https://gitlab.example.com/api/v4
GITLAB_TOKEN=your-private-token
# optionally limit exposed tools
# use a comma-separated list
# TOOLS_INCLUDE=projects,merge_requests
# or exclude certain tools
# TOOLS_EXCLUDE=pipelines
# TOOLS_INCLUDE takes precedence if both are set

Filtering Available Tools

By default the server loads all GitLab tools. To restrict the available set you can provide an include or exclude list:

  • Environment variables – set TOOLS_INCLUDE or TOOLS_EXCLUDE to a comma- separated list. If both are defined, TOOLS_INCLUDE wins.

    TOOLS_INCLUDE=projects,merge_requests npm run start:mcp
    # or
    TOOLS_EXCLUDE=pipelines npm run start:mcp
  • Programmatic API – pass includes or excludes to createMcpServer():

    import { createMcpServer } from 'mcp-server-extended-gitlab';
    
    const server = await createMcpServer({ includes: ['projects', 'merge_requests'] });
    await server.start();
  • Config file – supply a JSON file when creating the server. Use the configPath option pointing to a file like:

    {
      "includes": ["projects", "merge_requests"]
    }
    const server = await createMcpServer({ configPath: 'mcp.config.json' });

Use this when embedding the server in another application. Remember that the include list overrides the exclude list if both are supplied.


📂 Project Structure

├── src
│   ├── createApp.ts         # Express factory with GitLab routes
│   ├── bootstrapServer.ts   # initializes and bootstraps the server
│   └── server.ts            # production entry (npm start)
├── tests                    # Jest test suites
├── dist                     # compiled JS output
├── jest.config.js           # Jest/ts-jest settings
├── tsconfig.json            # TypeScript compiler options
└── package.json             # scripts & deps

Available GitLab Routes

The server exposes the following endpoints:

| Method | Endpoint | | ------ | -------- | | GET | /projects | | GET | /projects/search?q=<query> | | GET | /projects/:id | | GET | /projects/:id/merge_requests | | GET | /projects/:id/merge_requests/:iid | | GET | /projects/:id/merge_requests/:iid/discussions | | POST | /projects/:id/merge_requests | | PUT | /projects/:id/merge_requests/:iid/merge | | PUT | /projects/:id/merge_requests/:iid/close | | PUT | /projects/:id/merge_requests/:iid/reopen | | PUT | /projects/:id/merge_requests/:iid/rebase | | GET | /projects/:id/merge_requests/:iid/changes | | GET | /projects/:id/merge_requests/:iid/discussions/:discussion_id | | POST | /projects/:id/merge_requests/:iid/discussions/:discussion_id/notes | | POST | /projects/:id/merge_requests/:iid/discussions | | DELETE | /projects/:id/merge_requests/:iid/discussions/:discussion_id | | PUT | /projects/:id/merge_requests/:iid/discussions/:discussion_id | | PUT | /projects/:id/merge_requests/:iid/discussions/:discussion_id/resolve | | GET | /projects/:id/merge_requests/:iid/notes/:note_id | | POST | /projects/:id/merge_requests/:iid/notes | | PUT | /projects/:id/merge_requests/:iid/notes/:note_id | | DELETE | /projects/:id/merge_requests/:iid/notes/:note_id | | PUT | /projects/:id/merge_requests/:iid | | GET | /projects/:id/files/<path>?ref=<branch> | | POST | /projects/:id/files/<path> | | PUT | /projects/:id/files/<path> | | DELETE | /projects/:id/files/<path>?branch=<branch>&commit_message=<msg> | | GET | /projects/:id/files?path=<path>&ref=<branch> | | GET | /projects/:id/branches | | POST | /projects/:id/branches | | GET | /projects/:id/branches/:branch | | DELETE | /projects/:id/branches/:branch | | GET | /projects/:id/commits | | GET | /projects/:id/repository/commits/:commit_id/discussions | | GET | /projects/:id/repository/commits/:commit_id/discussions/:discussion_id | | POST | /projects/:id/repository/commits/:commit_id/discussions | | POST | /projects/:id/repository/commits/:commit_id/discussions/:discussion_id/notes | | PUT | /projects/:id/repository/commits/:commit_id/discussions/:discussion_id/notes/:note_id | | DELETE | /projects/:id/repository/commits/:commit_id/discussions/:discussion_id/notes/:note_id | | GET | /projects/:id/pipelines | | GET | /projects/:id/pipelines/:pipeline_id | | POST | /projects/:id/pipelines | | POST | /projects/:id/pipelines/:pipeline_id/cancel | | POST | /projects/:id/pipelines/:pipeline_id/retry | | DELETE | /projects/:id/pipelines/:pipeline_id | | GET | /projects/:id/pipelines/:pipeline_id/jobs | | GET | /projects/:id/pipelines/:pipeline_id/artifacts | | GET | /projects/:id/releases | | GET | /projects/:id/releases/:tag | | POST | /projects/:id/releases | | PUT | /projects/:id/releases/:tag | | DELETE | /projects/:id/releases/:tag | | GET | /projects/:id/tags | | GET | /projects/:id/tags/:tag | | POST | /projects/:id/tags | | DELETE | /projects/:id/tags/:tag | | GET | /projects/:id/issues | | POST | /projects/:id/issues | | GET | /projects/:id/issues/:issue_id | | PUT | /projects/:id/issues/:issue_id | | PUT | /projects/:id/issues/:issue_id/close | | PUT | /projects/:id/issues/:issue_id/reopen | | GET | /projects/:id/issues/:issue_id/discussions | | GET | /projects/:id/issues/:issue_id/discussions/:discussion_id | | POST | /projects/:id/issues/:issue_id/discussions | | POST | /projects/:id/issues/:issue_id/discussions/:discussion_id/notes | | PUT | /projects/:id/issues/:issue_id/discussions/:discussion_id/notes/:note_id | | DELETE | /projects/:id/issues/:issue_id/discussions/:discussion_id/notes/:note_id | | GET | /projects/:id/snippets/:snippet_id/discussions | | GET | /projects/:id/snippets/:snippet_id/discussions/:discussion_id | | POST | /projects/:id/snippets/:snippet_id/discussions | | POST | /projects/:id/snippets/:snippet_id/discussions/:discussion_id/notes | | PUT | /projects/:id/snippets/:snippet_id/discussions/:discussion_id/notes/:note_id | | DELETE | /projects/:id/snippets/:snippet_id/discussions/:discussion_id/notes/:note_id | | POST | /groups | | GET | /groups/:id | | DELETE | /groups/:id | | GET | /groups/:id/members | | GET | /groups/:id/epics | | GET | /groups/:id/epics/:epic_id/discussions | | GET | /groups/:id/epics/:epic_id/discussions/:discussion_id | | POST | /groups/:id/epics/:epic_id/discussions | | POST | /groups/:id/epics/:epic_id/discussions/:discussion_id/notes | | PUT | /groups/:id/epics/:epic_id/discussions/:discussion_id/notes/:note_id | | DELETE | /groups/:id/epics/:epic_id/discussions/:discussion_id/notes/:note_id |

GitLab's documentation notes that the epic discussions API is deprecated and may be removed in a future release.


🏗 Building & Deployment

npm run build      # run "tsc && mcp-build" to compile and prepare ./dist
npm start          # run compiled server

MCP Client Integrations

This server can be used by any Model‑Context‑Protocol desktop application.

Running the server

Start the server using the SSE transport so that clients can connect:

npm run start:mcp

It listens on port 3000 (or PORT). Ensure GITLAB_BASE_URL and GITLAB_TOKEN are configured. Use TOOLS_INCLUDE or TOOLS_EXCLUDE to control which tools are loaded.

Claude Desktop

  1. Launch the server as shown above.
  2. Edit your Claude Desktop configuration file:
    • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
    • Windows: %APPDATA%/Claude/claude_desktop_config.json
  3. Add an entry under "mcpServers":
{
  "mcpServers": {
    "gitlab-server": {
      "command": "node",
      "args": ["/absolute/path/to/mcp-server-extended-gitlab/dist/mcpServer.js"],
      "env": {
        "TOOLS_INCLUDE": "projects,merge_requests"
      }
    }
  }
}

After publishing the project to npm you can instead use:

{
  "mcpServers": {
    "gitlab-server": {
      "command": "npx",
      "args": ["mcp-server-extended-gitlab", "--includes=projects,merge_requests"]
    }
  }
}

Cursor

  1. Run npm run start:mcp (append -- --includes=projects,merge_requests to limit tools).
  2. Create or edit mcp_servers.json in your Cursor data directory:
    • macOS: ~/Library/Application Support/Cursor/mcp_servers.json
    • Windows: %APPDATA%/Cursor/mcp_servers.json
  3. Add:
{
  "gitlab-server": {
    "type": "sse",
    "url": "http://localhost:3000"
  }
}

Restart Cursor to load the configuration.

Other MCP clients

Most MCP-capable applications follow the same pattern: point them to http://localhost:3000 (or your chosen address) and specify the transport type (SSE or STDIO) according to your client's documentation.


🤝 Contributing

Issues and PRs are welcome! Please follow the existing coding style and include tests for new functionality.


📜 License

Released under the MIT License.