Complete working example using MCP server with GitLab API.
For GitLab API specifically:
- Reduced from 200+ potential tools to 26 aggregated tools
- 85% reduction in MCP tool count
- Tested with real GitLab OpenAPI specification
Visit https://gitlab.com/-/user_settings/personal_access_tokens and create a token with appropriate scopes.
Reuse the README Quick Start instructions to load the GitLab specification and profile. Substitute:
MCP4_PROFILE=gitlabGITLAB_TOKEN=<your GitLab token>GITLAB_API_BASE_URL=https://gitlab.com/api/v4
Follow the standard launch steps (npm start or npx mcp4openapi) after installing dependencies.
CLI profile selector variant (uses the profile registry):
npx mcp4openapi --profile gitlab- loads GitLab profile from
profiles/gitlab/developer-profile-oauth.jsonbecause of"profile_id": "gitlab"definition - loads OpenAPI specification from
profiles/gitlab/openapi.yamlbecause of"openapi_spec_path": "./openapi.yaml"definition - uses profile-specific auth env vars (for example,
GITLAB_TOKENandGITLAB_API_BASE_URL)
The profiles/gitlab/developer-profile-oauth.json profile provides 26 aggregated tools.
Some of them are:
Work with GitLab groups (list, get, list_projects, list_subgroups).
Example - list all groups:
{
"action": "list"
}Example - get group details:
{
"action": "get",
"group_id": "davidruzicka"
}Work with GitLab projects (list, get).
Example - list all projects:
{
"action": "list",
"membership": true
}Example - get project details:
{
"action": "get",
"project_id": "123"
}Work with merge requests (list, get, create, delete).
Example - list merge requests:
{
"project_id": "123",
"action": "list",
"state": "opened"
}Example - create merge request:
{
"project_id": "123",
"action": "create",
"source_branch": "feature/new-feature",
"target_branch": "main",
"title": "Implement new feature"
}Work with issues (list, get, create, delete).
Example - list issues:
{
"project_id": "123",
"action": "list",
"state": "opened"
}Example - create issue:
{
"project_id": "123",
"action": "create",
"title": "Bug: Application crashes on startup"
}Manage badges for a project (list, get, create, update, delete).
Example - list badges:
{
"project_id": "123",
"action": "list"
}Example - create badge:
{
"project_id": "123",
"action": "create",
"link_url": "https://example.com",
"image_url": "https://example.com/badge.svg"
}Manage repository branches (list, get, create, delete, protect, unprotect, exists).
Example - create branch:
{
"project_id": "123",
"action": "create",
"branch": "feature/new-feature",
"ref": "main"
}Example - protect branch:
{
"project_id": "123",
"action": "protect",
"branch": "main"
}List repository commits with optional filters for ref and file path.
Example - list commits for a file:
{
"project_id": "123",
"action": "list",
"path": "src%2Findex.js",
"ref_name": "main"
}Manage access requests for projects or groups (list, approve, deny, request).
Example - list access requests:
{
"resource_type": "project",
"resource_id": "123",
"action": "list"
}Example - approve access request:
{
"resource_type": "group",
"resource_id": "davidruzicka",
"action": "approve",
"user_id": 456,
"access_level": 30
}List CI/CD jobs for a project with optional status filtering.
Example:
{
"project_id": "123",
"scope": ["failed", "canceled"]
}Run and inspect pipelines/jobs (run, inspect, retry/cancel, play manual jobs, download artifacts).
Example - trigger manual job:
{
"project_id": "123",
"action": "play_job",
"job_id": 1234
}The gitlab-developer.json profile includes:
- Auth: Bearer token configurable via
GITLAB_TOKENenvironment variable - Base URL: Configurable via
GITLAB_API_BASE_URL(default:https://gitlab.com/api/v4) - Rate Limit: 600 requests/minute global, with overrides for destructive operations
- Retry: 3 attempts with exponential backoff [1s, 2s, 4s]
- Retry Status Codes: 429, 502, 503, 504
- Array Format: brackets (for query parameters like
scope[])
Each tool groups related operations, e.g.:
manage_groups: 4 operations (list, get, list_projects, list_subgroups)manage_projects: 2 operations (list, get)manage_merge_requests: 4 operations (list, get, create, delete)manage_issues: 4 operations (list, get, create, delete)manage_project_badges: 5 operations (list, get, create, update, delete)manage_branches: 7 operations (list, get, create, delete, protect, unprotect, exists)repository_commits: 1 operation (list)manage_access_requests: 8 operations (list/approve/deny/request for project/group)list_project_jobs: 1 operation with filteringmanage_pipelines_jobs: 7 operations (run, get pipeline, get job, retry, cancel, play job, download artifacts)- ...
Total: 38+ operations aggregated into 26 tools.
The project includes integration tests using a mock GitLab server:
npm testTests cover:
- All 10 tools
- CRUD operations
- Error scenarios (404, 403)
- Query parameter handling
- Resource type discrimination (project vs group)
- Pagination and filtering
Add to your mcp.json:
{
"mcpServers": {
"gitlab": {
"command": "node",
"args": ["/path/to/mcp4openapi/dist/index.js"],
"env": {
"MCP4_PROFILE": "gitlab",
"GITLAB_TOKEN": "glpat-xxxxxxxxxxxxxxxxxxxx",
"GITLAB_API_BASE_URL": "https://gitlab.com/api/v4"
}
}
}
}This Claude Desktop example is stdio + token based. For OAuth browser flow, use HTTP transport and URL-based client configuration from OAUTH.md.
List groups you're member of:
{
"tool": "manage_groups",
"arguments": {
"action": "list",
"owned": true
}
}List your projects:
{
"tool": "manage_projects",
"arguments": {
"action": "list",
"membership": true
}
}Create a merge request:
{
"tool": "manage_merge_requests",
"arguments": {
"project_id": "123",
"action": "create",
"source_branch": "feature/new-feature",
"target_branch": "main",
"title": "Add new feature",
"description": "This PR implements feature X"
}
}List open merge requests:
{
"tool": "manage_merge_requests",
"arguments": {
"project_id": "123",
"action": "list",
"state": "opened"
}
}Create an issue:
{
"tool": "manage_issues",
"arguments": {
"project_id": "123",
"action": "create",
"title": "Bug: Application crashes on startup",
"labels": "bug,critical"
}
}{
"tool": "list_project_jobs",
"arguments": {
"project_id": "123",
"scope": ["failed"]
}
}Create feature branch:
{
"tool": "manage_branches",
"arguments": {
"project_id": "123",
"action": "create",
"branch": "feature/implement-x",
"ref": "main"
}
}Protect main branch:
{
"tool": "manage_branches",
"arguments": {
"project_id": "123",
"action": "protect",
"branch": "main"
}
}{
"tool": "manage_access_requests",
"arguments": {
"resource_type": "group",
"resource_id": "davidruzicka",
"action": "approve",
"user_id": 456,
"access_level": 30
}
}Access levels:
- 10 = Guest
- 20 = Reporter
- 30 = Developer (default)
- 40 = Maintainer
- 50 = Owner
Verify your token (read_user right is required):
curl -H "Authorization: Bearer $GITLAB_TOKEN" https://gitlab.com/api/v4/userIf hitting rate limits, adjust in profile:
{
"interceptors": {
"rate_limit": {
"max_requests_per_minute": 300
}
}
}Ensure API is accessible and use correct base URL:
export MCP4_API_BASE_URL=https://gitlab.yourcompany.com/api/v4You can create additional profiles for different use cases:
profiles/gitlab/admin-profile.json- Include admin operationsprofiles/gitlab/readonly-profile.json- Only GET operationsprofiles/gitlab/ci-profile.json- Focus on CI/CD operations
See profiles/gitlab/developer-profile-oauth.json as a template and profile-schema.json for the JSON schema.
The profiles/gitlab/openapi.yaml file is a partial GitLab API specification used for testing.
For complete GitLab API documentation, see: https://docs.gitlab.com/ee/api/
To update the specification:
- Download from GitLab repository
- Place in
profiles/gitlab/directory asopenapi.yaml - Rebuild profile if adding new operations