Motivation
I've been using Cursor IDE as my primary development environment and absolutely love how it enhances my coding workflow with AI assistance. As someone who works extensively with GitLab for version control and CI/CD, I wanted to bring GitLab's powerful API capabilities directly into my Cursor IDE experience. Building an MCP server seemed like the perfect way to achieve this while also getting hands-on practice with the MCP protocol.
Implementation
Let's walk through building a GitLab MCP server step by step. We'll create a server that can interact with GitLab's API endpoints while following MCP protocol specifications.
Project Structure
First, let's set up our project structure:
mkdir gitlab-mcp-server
cd gitlab-mcp-server
npm init -y
The project structure should look like this:
gitlab-mcp-server/
├── src/
│ ├── server.ts
│ └── main.ts
├── package.json
└── tsconfig.json
Install Dependencies
Add the required dependencies:
npm install @cursor/mcp-server axios dotenv zod
npm install -D typescript @types/node
Update package.json with the build and start scripts:
{
"scripts": {
"build": "tsc",
"start": "node dist/main.js"
}
}
Server Implementation
Let's implement the server in src/server.ts
:
import { McpServer } from '@cursor/mcp-server';
import axios from 'axios';
import { z } from 'zod';
import dotenv from 'dotenv';
// Load environment variables
dotenv.config();
const GITLAB_TOKEN = process.env.GITLAB_TOKEN;
if (!GITLAB_TOKEN) {
throw new Error('GITLAB_TOKEN environment variable is required');
}
// Create GitLab API client
const gitlabClient = axios.create({
baseURL: 'https://gitlab.com/api/v4',
headers: {
'Authorization': `Bearer ${GITLAB_TOKEN}`,
'Content-Type': 'application/json'
}
});
// Create MCP server instance
export const mcpServer = new McpServer();
// Add a tool for creating issues
mcpServer.tool({
name: 'gitlab_create_issue',
description: 'Create a new issue in a GitLab project',
parameters: z.object({
project_id: z.number().describe('The ID of the project'),
title: z.string().describe('The title of the issue'),
description: z.string().describe('The description of the issue')
}),
handler: async ({ project_id, title, description }) => {
try {
const response = await gitlabClient.post(`/projects/${project_id}/issues`, {
title,
description
});
return {
issue_id: response.data.iid,
issue_url: response.data.web_url
};
} catch (error) {
throw new Error(`Failed to create GitLab issue: ${error.message}`);
}
}
});
Main Entry Point
Create src/main.ts
as the entry point:
import { mcpServer } from './server';
const PORT = process.env.PORT || 7860;
mcpServer.listen(PORT, () => {
console.log(`GitLab MCP Server listening on port ${PORT}`);
});
Usage
Installation
Install the package globally:
npm install -g gitlab-mcp-server
Configuration
Add the GitLab MCP server to your Cursor IDE's mcp.json
:
{
"servers": [
{
"name": "gitlab",
"url": "http://localhost:7860"
}
]
}
Create a .env
file with your GitLab access token:
GITLAB_TOKEN=your_gitlab_personal_access_token
Example Prompts
Here are some example prompts you can use in Cursor IDE:
- Creating a new issue:
Create a GitLab issue for project ID 12345 to update dependencies
Response:
I'll help you create a GitLab issue for updating dependencies.
Created issue #42: "Update Project Dependencies"
Issue URL: https://gitlab.com/project/issues/42
- Fetching project details:
Get information about GitLab project myorg/myproject
Response:
Here are the project details:
- Name: myproject
- Description: My awesome project
- Stars: 25
- Forks: 8
- Last activity: 2024-01-08
- Listing merge requests:
Show open merge requests for project myorg/myproject
Response:
Open merge requests:
1. "Add user authentication" by @sarah
2. "Fix pagination bug" by @john
3. "Update API documentation" by @mike
How It Works
Rendering diagram...
The diagram shows how user requests flow through the system:
- User enters a prompt in Cursor IDE
- Cursor calls the appropriate MCP tool
- MCP server makes authenticated API requests to GitLab
- GitLab responds with data
- MCP server processes and returns the result
- Cursor presents the information to the user