Skip to main content
Glama

mcp-gitlab

by atla-digital
CLAUDE.md17 kB
# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Development Commands ### Build and Development - `npm run build` - Compile TypeScript and make executable - `npm run prepare` - Runs build (used by npm lifecycle) - `npm run watch` - Watch TypeScript files for changes and recompile - `npm run inspector` - Start MCP inspector for debugging server ### Code Quality & Linting ```bash # Lint and format code npm run lint # Check linting issues npm run lint:fix # Auto-fix linting issues npm run format # Format code with Prettier npm run format:check # Check code formatting ``` ### CI/CD & Documentation ```bash # Install git hooks for automatic documentation generation npm run install-hooks # Generate tool documentation manually npm run generate-docs ``` ## Architecture Overview This is a Model Context Protocol (MCP) server for GitLab integration built in TypeScript with **Streamable HTTP** as the primary transport. The server enables AI assistants to interact with GitLab repositories through a comprehensive set of tools. ### Streamable HTTP Transport The server implements the Streamable HTTP MCP transport protocol, running as an HTTP service on port 3001. This allows for: - Direct HTTP-based MCP communication - Better performance and reliability than stdio/process-based transports - Support for multiple concurrent clients - Easy deployment in containerized environments ### Core Architecture **Main Entry Point**: `src/server/streamable-http-server.ts` - Implements GitLabStreamableHttpServer class with HTTP transport - Creates axios instances with GitLab API authentication per session - Sets up request handlers for tools, resources, and capabilities **Tool Organization**: The codebase is organized into four main functional domains: 1. **Repository Operations** (`src/handlers/repository-handlers.ts`) - Projects, branches, merge requests, issues - File operations and branch comparisons 2. **Integration Management** (`src/handlers/integration-handlers.ts`) - Slack integration, webhooks - Managed by `IntegrationsManager` class 3. **CI/CD Operations** (`src/handlers/cicd-handlers.ts`) - Pipeline triggers, CI/CD variables - Managed by `CiCdManager` class 4. **User/Group Management** (`src/handlers/users-groups-handlers.ts`) - User and group operations, project memberships - Managed by `UsersGroupsManager` class ### Key Design Patterns **Tool Registry Pattern**: `src/utils/tool-registry.ts` maps tool names to handler functions, enabling clean separation of tool definitions from implementations. **Manager Classes**: Domain-specific manager classes (`IntegrationsManager`, `CiCdManager`, `UsersGroupsManager`) encapsulate related API operations and are injected into handlers via `HandlerContext`. **Centralized Tool Definitions**: `src/utils/tools-data.ts` contains all tool schemas exported as `toolDefinitions` array. This file is monitored by git hooks for automatic TOOLS.md generation. ### Resource System The server exposes GitLab projects as MCP resources via `gitlab://projects` URI, handled by `src/utils/resource-handlers.ts`. ### Configuration Management The server uses **Zod-validated configuration** from environment variables with sensible defaults: #### Configuration Schema (`src/utils/config.ts`) - **Server**: `PORT`, `NODE_ENV` - **Logging**: `LOG_LEVEL` (error|warn|info|http|debug) - **Sessions**: `SESSION_MAX_AGE`, `SESSION_CLEANUP_INTERVAL` - **HTTP**: `AXIOS_TIMEOUT` (request timeout in ms) - **Development**: `ENABLE_REQUEST_LOGGING`, `ENABLE_DETAILED_ERRORS` #### Environment Setup ```bash # Copy example configuration cp .env.example .env # Edit with your values nano .env ``` **Example `.env.example`**: ```env PORT=3000 NODE_ENV=development LOG_LEVEL=info SESSION_MAX_AGE=604800000 # 7 days SESSION_CLEANUP_INTERVAL=300000 # 5 minutes AXIOS_TIMEOUT=30000 # 30 seconds ENABLE_REQUEST_LOGGING=true ENABLE_DETAILED_ERRORS=false ``` ### Structured Logging The server implements **Winston-based structured logging** with component-specific loggers: #### Log Components - **API Logger**: GitLab API requests/responses (`GitLab-API`) - **Session Logger**: Session lifecycle events (`Session`) - **Server Logger**: HTTP server events (`HTTP-Server`) - **Auth Logger**: Authentication events (`Auth`) #### Log Levels & Output - **Console**: Colorized, human-readable format - **File** (production): JSON format in `logs/` directory - **Configurable**: Set `LOG_LEVEL` environment variable #### Example Log Entry ```json { "timestamp": "2025-08-12 22:54:15:5415", "level": "info", "message": "Created new session", "component": "Session", "tokenPreview": "glpat-xx...", "gitlabUrl": "https://gitlab.com/api/v4" } ``` ### MCP Prompts for Workflow Guidance This GitLab MCP server supports **MCP Prompts** - reusable workflow templates that provide step-by-step guidance for complex GitLab operations. #### Available Prompts **`quick-mr-review`** - A simple merge request review workflow - **Arguments**: `project_id` (required), `merge_request_iid` (required) - **Purpose**: Demonstrates multi-step GitLab operations for code review - **Steps**: Get MR details → Get changes → Review → Add comments #### Using Prompts 1. **List available prompts:** ```json {"jsonrpc": "2.0", "id": 1, "method": "prompts/list", "params": {}} ``` 2. **Get prompt with parameters:** ```json { "jsonrpc": "2.0", "id": 1, "method": "prompts/get", "params": { "name": "quick-mr-review", "arguments": { "project_id": "web/runner", "merge_request_iid": "5" } } } ``` #### Workflow Integration Prompts provide templates that guide you through multi-step operations: - **Structured guidance** for complex workflows - **Parameter substitution** for specific projects/MRs - **Tool chaining** examples showing how to combine multiple GitLab tools - **Best practices** for common development tasks This standardizes how AI agents can access workflow knowledge and ensures consistent, reliable execution of complex GitLab operations. ### Client Configuration #### For Streamable HTTP Compatible Clients Direct connection to the Streamable HTTP server: ``` http://localhost:3001/mcp ``` #### For Claude Code (via mcp-remote proxy) Since Claude Code doesn't support Streamable HTTP natively, use `mcp-remote` as a proxy: ```json { "mcpServers": { "sm-gitlab": { "command": "npx", "args": [ "mcp-remote@latest", "http://host.docker.internal:3001/mcp", "--allow-http", "--header", "X-GitLab-Token: ${GITLAB_TOKEN}", "--header", "X-GitLab-URL: ${GITLAB_URL}" ], "env": { "GITLAB_TOKEN": "your_gitlab_token", "GITLAB_URL": "https://your-gitlab-instance.com/api/v4" } } } } ``` ### Authentication GitLab credentials are passed as HTTP headers: - `X-GitLab-Token` - Required GitLab API token - `X-GitLab-URL` - GitLab API base URL (defaults to https://gitlab.com/api/v4) ## Adding New Tools When adding a new GitLab API tool to the MCP server, follow these steps: ### 1. Research GitLab API - Check GitLab API documentation for endpoint, parameters, and authentication requirements - Identify required vs optional parameters - Note any special considerations (authentication, permissions, etc.) ### 2. Add Tool Definition **File**: `src/utils/tools-data.ts` - Add new tool object to `toolDefinitions` array - Follow existing naming convention: `gitlab_[action]_[resource]` - Include complete JSON Schema for `inputSchema` - Mark required parameters in `required` array Example: ```typescript { name: 'gitlab_create_issue', description: 'Create a new issue in a GitLab project', inputSchema: { type: 'object', properties: { project_id: { type: 'string', description: 'The ID or URL-encoded path of the project' }, title: { type: 'string', description: 'The title of the issue' } // ... other properties }, required: ['project_id', 'title'] } } ``` ### 3. Implement Handler Function **File**: `src/handlers/[domain]-handlers.ts` (choose appropriate domain) - Create handler function following `ToolHandler` type - Validate required parameters using `McpError` with `ErrorCode.InvalidParams` - Use `context.axiosInstance` for GitLab API calls - Return formatted response using `formatResponse(response.data)` Example: ```typescript export const createIssue: ToolHandler = async (params, context) => { const { project_id, title, description } = params.arguments || {}; if (!project_id || !title) { throw new McpError(ErrorCode.InvalidParams, 'project_id and title are required'); } const response = await context.axiosInstance.post( `/projects/${encodeURIComponent(String(project_id))}/issues`, { title, description } ); return formatResponse(response.data); }; ``` ### 4. Register Tool in Registry **File**: `src/utils/tool-registry.ts` - Import handler function - Add mapping entry: `tool_name: handlerFunction` - Place in appropriate section (Repository, Integration, CI/CD, Users/Groups) Example: ```typescript gitlab_create_issue: repoHandlers.createIssue, ``` ### 5. Build and Test ```bash npm run build ``` - Verify TypeScript compilation succeeds - Check that new tool compiles without errors ### 6. Deploy New Version For Docker deployment: ```bash docker compose down docker compose up --build -d ``` For direct deployment: ```bash npm run build # Restart your MCP server process ``` ### 7. Verify Deployment Test the new tool is available: ```bash curl -X POST http://localhost:3001/mcp \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -H "X-GitLab-Token: your_token" \ -d '{"jsonrpc": "2.0", "id": 1, "method": "tools/list", "params": {}}' ``` ## API Testing and Verification The MCP server runs an HTTP endpoint on port 3001 that can be tested directly. Here's how to properly test the API: ### Required Headers All API requests must include these headers: ```bash -H "Content-Type: application/json" -H "Accept: application/json, text/event-stream" -H "X-GitLab-Token: your_gitlab_token" -H "X-GitLab-URL: your_gitlab_api_url" # Optional, defaults to https://gitlab.com/api/v4 ``` ### GitLab Configuration The gitlab token and address can be obtained from `.mcp.json` ### Response Format The API returns responses in Server-Sent Events (SSE) format: ``` event: message data: {"result": {"tools": [...]},"jsonrpc":"2.0","id":1} ``` ### Extracting JSON from SSE To get valid JSON from the SSE response, use: ```bash curl -X POST http://localhost:3001/mcp \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -H "X-GitLab-Token: YOUR_TOKEN" \ -H "X-GitLab-URL: YOUR_GITLAB_URL" \ -d '{"jsonrpc": "2.0", "id": 1, "method": "tools/list", "params": {}}' \ | grep '^data:' | sed 's/^data: //' | jq '.' ``` ### Common API Verification Commands **Count total tools:** ```bash curl -X POST http://localhost:3001/mcp \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -H "X-GitLab-Token: YOUR_TOKEN" \ -H "X-GitLab-URL: YOUR_GITLAB_URL" \ -d '{"jsonrpc": "2.0", "id": 1, "method": "tools/list", "params": {}}' \ | grep '^data:' | sed 's/^data: //' | jq '.result.tools | length' ``` **List all tool names:** ```bash curl -X POST http://localhost:3001/mcp \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -H "X-GitLab-Token: YOUR_TOKEN" \ -H "X-GitLab-URL: YOUR_GITLAB_URL" \ -d '{"jsonrpc": "2.0", "id": 1, "method": "tools/list", "params": {}}' \ | grep '^data:' | sed 's/^data: //' | jq -r '.result.tools[] | .name' | sort ``` **Test specific tool execution:** ```bash curl -X POST http://localhost:3001/mcp \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -H "X-GitLab-Token: YOUR_TOKEN" \ -H "X-GitLab-URL: YOUR_GITLAB_URL" \ -d '{"jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": {"name": "gitlab_get_project_id", "arguments": {"remote_url": "git@gitlab.com:group/project.git"}}}' \ | grep '^data:' | sed 's/^data: //' | jq '.result' ``` **Verify specific tools exist:** ```bash curl -X POST http://localhost:3001/mcp \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -H "X-GitLab-Token: YOUR_TOKEN" \ -H "X-GitLab-URL: YOUR_GITLAB_URL" \ -d '{"jsonrpc": "2.0", "id": 1, "method": "tools/list", "params": {}}' \ | grep '^data:' | sed 's/^data: //' | jq -r '.result.tools[] | .name' \ | grep -E 'gitlab_(get_issue|update_issue|create_branch|list_pipelines)' ``` ### Health Check Test server health without GitLab authentication: ```bash curl http://localhost:3001/health ``` ### Troubleshooting **Common Issues:** - Missing `text/event-stream` in Accept header → "Not Acceptable" error - Missing GitLab token → "GitLab API token required" error - Invalid GitLab token → Authentication fails during session creation - Wrong GitLab URL → Connection timeouts or 404 errors **Debug Steps:** 1. Check container status: `docker compose ps` 2. View server logs: `docker compose logs -f` 3. Test health endpoint first: `curl http://localhost:3001/health` 4. Verify GitLab credentials work: Test with simple GitLab API call ## CI/CD Pipeline ### GitHub Actions Workflows The project includes automated CI/CD pipelines using GitHub Actions: #### Docker Build & Publish (`.github/workflows/docker-publish.yml`) - **Triggers**: Push to `main` branch, release publication - **Features**: - Multi-platform builds (linux/amd64, linux/arm64) - Publishes to GitHub Container Registry (ghcr.io) - Build caching for performance - Artifact attestations for security - Automatic tagging (branch, PR, semver, latest) #### CI Pipeline (`.github/workflows/ci.yml`) - **Triggers**: Push to `main`/`develop`, pull requests - **Features**: - Multi-version Node.js testing (20, 22) - TypeScript compilation and type checking - Build validation - HTTP server startup testing - Docker container testing with distroless-compatible health checks - TOOLS.md documentation validation ### Git Hooks & Documentation #### Pre-commit Hook (`git-hooks/pre-commit`) - Automatically regenerates `TOOLS.md` when tool definitions change - Monitors changes to `src/tools/definitions/` and `src/utils/tools-data.ts` - Runs build process to ensure latest compiled definitions - Adds updated documentation to the commit #### Documentation Generation (`scripts/generate-tools-md.js`) - Generates comprehensive tool documentation from TypeScript definitions - Categorizes tools by function (Repository, Integrations, CI/CD, User Management) - Creates formatted markdown with parameter tables and default values - Maintains table of contents with GitHub-compatible anchors ### Setup Commands ```bash # Install git hooks for automatic documentation npm run install-hooks # Generate documentation manually npm run generate-docs # Complete build and documentation workflow npm run build && npm run generate-docs ``` ## Code Quality & Best Practices ### ESLint & Prettier Integration - **ESLint 9** with TypeScript support and strict rules - **Prettier** integration for consistent code formatting - **Pre-configured rules** for Node.js and TypeScript best practices - **Auto-fix capabilities** via npm scripts #### Code Quality Commands ```bash npm run lint # Check for linting issues npm run lint:fix # Auto-fix linting and formatting issues npm run format # Format code with Prettier npm run format:check # Check if code is formatted correctly ``` #### Configuration Files - `eslint.config.js` - ESLint configuration with TypeScript support - `.prettierrc` - Prettier formatting rules - `.prettierignore` - Files to exclude from formatting ### Development Workflow 1. **Write code** following TypeScript best practices 2. **Run linting** with `npm run lint:fix` to auto-format 3. **Build and test** with `npm run build` 4. **Commit changes** (pre-commit hooks auto-generate docs) ## Important Development Notes - Tool definitions in `tools-data.ts` automatically generate TOOLS.md via pre-commit hook - All handlers receive `HandlerContext` containing axios instance and manager classes - Error handling is centralized in `response-formatter.ts` - The server binary is built to `build/index.js` and made executable during build - Always use `docker compose up --build` when deploying to ensure latest code is included - Tool registry maps tool names to handler functions for clean separation of concerns - Use GitHub Actions for CI/CD automation with comprehensive testing and validation

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/atla-digital/mcp-gitlab'

If you have feedback or need assistance with the MCP directory API, please join our Discord server