Skip to main content

cursor ide workflows

Cursor IDE + GitLab Integration

Last Updated: January 7, 2026 Cursor Version: Latest Website: https://cursor.com

Overview

Cursor is an AI-first code editor built on VSCode, offering deep integration with AI agents. This guide covers:

  1. Cursor Features - Cloud agents, MCP support, team collaboration
  2. GitLab Integration - Direct GitLab connectivity
  3. Agent Workflows - Custom agents in Cursor
  4. Team Patterns - Multi-developer collaboration
  5. Best Practices - Optimal Cursor + GitLab workflows

Cursor Features

Cloud Agents

Cursor provides cloud-hosted AI agents that can:

  • Understand entire codebases (unlimited context)
  • Execute commands in your development environment
  • Make multi-file edits
  • Run tests and fix errors
  • Create PRs/MRs with full context

Key Capabilities:

  • Infinite Context: Entire codebase indexed
  • Multi-File Edits: Change multiple files simultaneously
  • Terminal Access: Execute commands
  • Git Integration: Commit, push, create MRs
  • MCP Protocol: Use external tools

MCP Integration

Cursor supports the Model Context Protocol (MCP) for tool integration.

Built-in MCP Servers:

  • File system operations
  • Git operations
  • Terminal execution
  • Browser automation
  • Database queries

Custom MCP Servers:

  • GitLab API integration
  • Jira/Linear integration
  • Slack notifications
  • Custom tools

Cursor Agent System

Agent Modes:

  1. Chat Mode: Ask questions, get explanations
  2. Composer Mode: Multi-file code generation
  3. Inline Edit: Quick fixes and refactoring
  4. Terminal Agent: Command execution and debugging

GitLab Integration

Setup

1. Install Cursor:

# Download from cursor.com # Or via package manager brew install --cask cursor

2. Configure GitLab:

// .cursor/config.json { "gitlab": { "url": "https://gitlab.com", "token": "${GITLAB_TOKEN}", "defaultProject": "blueflyio/my-project" }, "git": { "provider": "gitlab", "autoFetch": true, "autoSync": true }, "mcp": { "servers": { "gitlab": { "command": "node", "args": ["~/.cursor/mcp-servers/gitlab/index.js"], "env": { "GITLAB_TOKEN": "${GITLAB_TOKEN}", "GITLAB_URL": "https://gitlab.com" } } } } }

3. Install GitLab MCP Server:

# Install MCP server for GitLab npx @modelcontextprotocol/create-server gitlab # Configure in Cursor settings cursor --install-mcp gitlab

GitLab MCP Server

Custom GitLab MCP Server (~/.cursor/mcp-servers/gitlab/index.js):

import { MCPServer } from '@modelcontextprotocol/sdk'; import { Gitlab } from '@gitbeaker/node'; const server = new MCPServer({ name: 'gitlab-mcp', version: '1.0.0' }); const gitlab = new Gitlab({ token: process.env.GITLAB_TOKEN, host: process.env.GITLAB_URL }); // Tool: Get issue details server.addTool({ name: 'gitlab_get_issue', description: 'Get issue details from GitLab', inputSchema: { type: 'object', properties: { project_id: { type: 'number' }, issue_iid: { type: 'number' } }, required: ['project_id', 'issue_iid'] }, async execute({ project_id, issue_iid }) { const issue = await gitlab.Issues.show(project_id, issue_iid); return { title: issue.title, description: issue.description, labels: issue.labels, assignees: issue.assignees.map(a => a.username), state: issue.state }; } }); // Tool: Create merge request server.addTool({ name: 'gitlab_create_mr', description: 'Create a merge request', inputSchema: { type: 'object', properties: { project_id: { type: 'number' }, source_branch: { type: 'string' }, target_branch: { type: 'string' }, title: { type: 'string' }, description: { type: 'string' } }, required: ['project_id', 'source_branch', 'target_branch', 'title'] }, async execute(params) { const mr = await gitlab.MergeRequests.create( params.project_id, params.source_branch, params.target_branch, params.title, { description: params.description } ); return { iid: mr.iid, web_url: mr.web_url }; } }); // Tool: Run GitLab CI/CD pipeline server.addTool({ name: 'gitlab_trigger_pipeline', description: 'Trigger a CI/CD pipeline', inputSchema: { type: 'object', properties: { project_id: { type: 'number' }, ref: { type: 'string' }, variables: { type: 'object' } }, required: ['project_id', 'ref'] }, async execute({ project_id, ref, variables }) { const pipeline = await gitlab.Pipelines.create(project_id, ref, { variables: Object.entries(variables || {}).map(([key, value]) => ({ key, variable_type: 'env_var', value: String(value) })) }); return { id: pipeline.id, web_url: pipeline.web_url, status: pipeline.status }; } }); // Tool: Get MR diff server.addTool({ name: 'gitlab_get_mr_diff', description: 'Get merge request diff', inputSchema: { type: 'object', properties: { project_id: { type: 'number' }, mr_iid: { type: 'number' } }, required: ['project_id', 'mr_iid'] }, async execute({ project_id, mr_iid }) { const changes = await gitlab.MergeRequests.changes(project_id, mr_iid); return { changes: changes.changes.map(change => ({ old_path: change.old_path, new_path: change.new_path, diff: change.diff })) }; } }); // Start server server.listen(3000); console.log('GitLab MCP Server running on port 3000');

Agent Workflows

Workflow 1: Issue to Implementation

Natural Language Workflow:

User in Cursor:
"Implement issue #456 from GitLab project 789"

Cursor Agent (using MCP):
1. Calls gitlab_get_issue(789, 456)
2. Reads issue description and requirements
3. Creates implementation plan
4. Generates code across multiple files
5. Runs tests
6. Creates commit
7. Pushes branch
8. Calls gitlab_create_mr(...)
9. Returns MR URL

Example in Cursor:

Cursor Chat:
> Implement GitLab issue blueflyio/my-project#123

Agent Response:
I'll help implement issue #123. Let me fetch the details...

[Fetching issue via MCP...]

Issue: "Add OAuth2 authentication"
Labels: enhancement, security
Priority: high

I'll implement this with the following plan:
1. Add OAuth2 dependencies
2. Create authentication middleware
3. Add login/logout endpoints
4. Update user model
5. Add tests

[Generating code...]

Created files:
- src/auth/oauth2.ts
- src/middleware/auth.ts
- src/routes/auth.ts
- tests/auth.test.ts

[Running tests...]
 All tests passing

[Creating commit...]
Committed: "feat: implement OAuth2 authentication"

[Creating merge request...]
MR created: https://gitlab.com/blueflyio/my-project/-/merge_requests/789

Ready for review! 

Workflow 2: MR Review

Review MR in Cursor:

Cursor Chat:
> Review GitLab MR !789 in project blueflyio/my-project

Agent:
Fetching MR details and diff...

## MR Review: Add OAuth2 authentication

### Security Analysis
 **MEDIUM**: Missing rate limiting on /auth/login endpoint
  File: src/routes/auth.ts:45
  Recommendation: Add express-rate-limit middleware

### Code Quality
 Good separation of concerns
 Comprehensive test coverage (92%)
 **LOW**: Consider extracting token validation to separate function

### Performance
 Efficient database queries
 Proper use of async/await

### Recommendations
1. Add rate limiting (critical for auth endpoints)
2. Consider adding OAuth2 provider configuration in env vars
3. Add JSDoc comments for public API

Overall Assessment: **APPROVE** with minor suggestions

Workflow 3: Automated Testing

Generate and run tests:

Cursor Chat:
> Generate tests for src/auth/oauth2.ts and run them

Agent:
Analyzing src/auth/oauth2.ts...

Generating test cases for:
- OAuth2 token generation
- Token validation
- Token refresh
- Error handling

[Creating tests/auth/oauth2.test.ts...]

import { OAuth2Provider } from '../../src/auth/oauth2';

describe('OAuth2Provider', () => {
  describe('generateToken', () => {
    it('should generate valid JWT token', async () => {
      const provider = new OAuth2Provider();
      const token = await provider.generateToken({ userId: 123 });

      expect(token).toBeDefined();
      expect(token).toMatch(/^eyJ/);
    });
  });

  describe('validateToken', () => {
    it('should validate correct token', async () => {
      const provider = new OAuth2Provider();
      const token = await provider.generateToken({ userId: 123 });
      const payload = await provider.validateToken(token);

      expect(payload.userId).toBe(123);
    });

    it('should reject expired token', async () => {
      const provider = new OAuth2Provider({ expiresIn: -1 });
      const token = await provider.generateToken({ userId: 123 });

      await expect(
        provider.validateToken(token)
      ).rejects.toThrow('Token expired');
    });
  });
});

[Running tests...]

 OAuth2Provider  generateToken  should generate valid JWT token (23ms)
 OAuth2Provider  validateToken  should validate correct token (18ms)
 OAuth2Provider  validateToken  should reject expired token (12ms)

Test Suites: 1 passed, 1 total
Tests: 3 passed, 3 total

All tests passing! 

Workflow 4: CI/CD Integration

Trigger pipeline from Cursor:

Cursor Chat:
> Run GitLab pipeline for current branch

Agent:
Current branch: feat/oauth2-auth
Project: blueflyio/my-project (789)

Triggering pipeline...

Pipeline #12345 started
Status: running
URL: https://gitlab.com/blueflyio/my-project/-/pipelines/12345

Jobs:
- test (running)
- build (pending)
- deploy (pending)

[Watching pipeline...]

 test completed (2m 34s)
 build completed (1m 12s)
  deploy waiting for manual trigger

Pipeline succeeded! 

Would you like me to trigger the deploy job?

Workflow 5: Documentation Generation

Generate docs from code:

Cursor Chat:
> Generate API documentation for src/api/ and save to docs/api.md

Agent:
Analyzing API endpoints in src/api/...

Found endpoints:
- POST /auth/login
- POST /auth/logout
- POST /auth/refresh
- GET /users
- POST /users
- GET /users/:id

[Generating documentation...]

Created docs/api.md with:
- Endpoint descriptions
- Request/response schemas
- Authentication requirements
- Example requests
- Error codes

[Committing changes...]
Committed: "docs: generate API documentation"

Documentation ready! 

Team Collaboration

Cursor Rules for Teams

Shared Rules (.cursor/rules.json):

{ "project": "blueflyio/my-project", "codeStyle": { "language": "typescript", "style": "airbnb", "maxLineLength": 100, "indent": 2 }, "conventions": { "commitMessage": "conventional-commits", "branchNaming": "issue-number-description", "fileNaming": "kebab-case" }, "automation": { "autoTest": true, "autoLint": true, "autoFormat": true, "autoCommit": false }, "gitlab": { "autoCreateMR": true, "mrTemplate": ".gitlab/merge_request_templates/default.md", "assignReviewers": ["@tech-lead", "@security-team"], "requireApproval": true }, "prompts": { "codeReview": "Review for security, performance, and best practices", "testGeneration": "Generate comprehensive tests with 80%+ coverage", "documentation": "Generate clear documentation with examples" } }

Team Workflows

1. Issue Assignment Workflow:

// .cursor/workflows/issue-assignment.ts export const issueAssignmentWorkflow = { trigger: 'issue.assigned', async execute(issue: GitLabIssue) { // Fetch issue details const issueData = await gitlab.getIssue(issue.projectId, issue.iid); // Analyze complexity const analysis = await cursorAgent.analyze({ prompt: `Analyze complexity of: ${issueData.description}`, context: { codebase: 'full', relatedFiles: true } }); // Create implementation plan const plan = await cursorAgent.createPlan({ issue: issueData, complexity: analysis.complexity, estimatedHours: analysis.estimatedHours }); // Comment on issue await gitlab.Issues.createNote(issue.projectId, issue.iid, { body: `## Implementation Plan ${plan.summary} ### Estimated Effort ${analysis.estimatedHours} hours ### Files to Modify ${plan.files.map(f => `- ${f}`).join('\n')} ### Tasks ${plan.tasks.map((t, i) => `${i + 1}. ${t}`).join('\n')} ` }); } };

2. Code Review Workflow:

// .cursor/workflows/code-review.ts export const codeReviewWorkflow = { trigger: 'merge_request.opened', async execute(mr: GitLabMergeRequest) { // Get MR diff const diff = await gitlab.getMRDiff(mr.projectId, mr.iid); // Run Cursor agent review const review = await cursorAgent.review({ diff: diff, focusAreas: ['security', 'performance', 'testing'], strictMode: true }); // Post review comments for (const issue of review.issues) { await gitlab.MergeRequests.createNote(mr.projectId, mr.iid, { body: `**${issue.severity.toUpperCase()}**: ${issue.description} File: \`${issue.file}:${issue.line}\` **Recommendation**: ${issue.recommendation} \`\`\`suggestion ${issue.suggestedCode} \`\`\` `, position: { base_sha: mr.diff_refs.base_sha, start_sha: mr.diff_refs.start_sha, head_sha: mr.diff_refs.head_sha, position_type: 'text', new_path: issue.file, new_line: issue.line } }); } // Overall assessment await gitlab.MergeRequests.createNote(mr.projectId, mr.iid, { body: review.summary }); } };

3. Continuous Documentation:

// .cursor/workflows/documentation.ts export const documentationWorkflow = { trigger: 'push', async execute(push: GitLabPush) { // Find changed files const changedFiles = push.commits.flatMap(c => c.modified); // Filter for code files const codeFiles = changedFiles.filter(f => f.endsWith('.ts') || f.endsWith('.tsx') || f.endsWith('.py') ); if (codeFiles.length === 0) return; // Generate/update documentation for (const file of codeFiles) { const code = await fs.readFile(file, 'utf-8'); const docs = await cursorAgent.generateDocs({ code, format: 'markdown', includeExamples: true }); // Save to docs directory const docsPath = file.replace('src/', 'docs/').replace(/\.(ts|py)$/, '.md'); await fs.writeFile(docsPath, docs); } // Commit documentation await git.add('docs/'); await git.commit('docs: update documentation'); await git.push(); } };

Best Practices

1. Context Management

Optimize Context Window:

// .cursor/context.json { "include": [ "src/**/*.{ts,tsx,js,jsx}", "tests/**/*.{ts,tsx}", "docs/**/*.md", "package.json", "tsconfig.json" ], "exclude": [ "node_modules/**", "dist/**", "build/**", ".git/**", "*.log" ], "prioritize": [ "currently_open_files", "recently_modified", "imported_by_open_files" ], "maxContextSize": "200k" // tokens }

2. Prompt Engineering

Effective Prompts:

// Good prompts "Implement OAuth2 authentication following OWASP guidelines with comprehensive tests" "Review this MR for security vulnerabilities, focusing on authentication and authorization" "Refactor src/auth/ to follow SOLID principles, maintaining all existing tests" // Ineffective prompts "Make it better" "Fix the code" "Add tests"

3. Security

Secure Configuration:

// .cursor/security.json { "secrets": { "scan": true, "preventCommit": true, "patterns": [ "api[_-]?key", "password", "secret", "token", "private[_-]?key" ] }, "codeReview": { "checkSQLInjection": true, "checkXSS": true, "checkCSRF": true, "checkAuthBypass": true }, "dependencies": { "checkVulnerabilities": true, "autoUpdate": "patch", // auto-update patch versions "block": ["critical", "high"] // block these severities } }

4. Performance

Optimize Agent Execution:

// .cursor/performance.json { "caching": { "enabled": true, "ttl": 3600, // seconds "strategies": [ "file_analysis", "test_results", "lint_results" ] }, "parallelization": { "maxConcurrentAgents": 3, "tasks": [ "test_generation", "documentation", "code_review" ] }, "resourceLimits": { "maxTokensPerRequest": 100000, "maxExecutionTime": 300, // seconds "maxMemory": "2Gi" } }

5. Cost Management

Monitor Usage:

// .cursor/usage-tracker.ts import { CursorUsage } from '@cursor/sdk'; const tracker = new CursorUsage({ logFile: '.cursor/usage.log', alertThreshold: { daily: 1000000, // tokens monthly: 25000000 } }); // Track usage tracker.on('threshold_exceeded', (usage) => { console.warn(`Usage exceeded: ${usage.tokens} tokens`); // Notify team gitlab.Issues.create(projectId, { title: 'Cursor Usage Alert', description: `Daily usage exceeded: ${usage.tokens} tokens`, labels: ['cost-management', 'cursor'] }); });

Advanced Patterns

Multi-Agent Orchestration

// .cursor/orchestration/feature-development.ts export class FeatureDevelopmentOrchestrator { async execute(issueIid: number) { // Stage 1: Analysis const analysis = await this.plannerAgent.analyze(issueIid); // Stage 2: Implementation const code = await this.implementerAgent.generate(analysis.plan); // Stage 3: Testing const tests = await this.testAgent.generate(code); const testResults = await this.testAgent.run(); // Stage 4: Review const review = await this.reviewAgent.review({ code, tests, testResults }); // Stage 5: Documentation const docs = await this.docsAgent.generate(code); // Stage 6: MR Creation if (review.approved && testResults.passed) { const mr = await this.createMR({ code, tests, docs, review }); return { success: true, mrUrl: mr.web_url }; } else { return { success: false, issues: review.issues }; } } }

GitLab CI/CD from Cursor

// .cursor/ci-integration.ts import { Gitlab } from '@gitbeaker/node'; import { CursorAgent } from '@cursor/sdk'; export async function optimizePipeline() { const gitlab = new Gitlab({ token: process.env.GITLAB_TOKEN }); const agent = new CursorAgent(); // Get recent pipelines const pipelines = await gitlab.Pipelines.all(projectId, { per_page: 10 }); // Analyze performance const analysis = await agent.analyze({ prompt: `Analyze these pipeline runs and suggest optimizations: ${JSON.stringify(pipelines, null, 2)}`, context: { file: '.gitlab-ci.yml' } }); // Apply optimizations if (analysis.suggestions.length > 0) { await agent.applyChanges({ file: '.gitlab-ci.yml', changes: analysis.suggestions }); // Create MR with changes await gitlab.MergeRequests.create(projectId, sourceBranch, targetBranch, { title: 'chore: optimize CI/CD pipeline', description: analysis.summary }); } }

Resources

Documentation

Community

Extensions & Tools

Next Steps

  1. Install Cursor: Download from cursor.com
  2. Configure GitLab: Add token and project
  3. Setup MCP Server: Install GitLab MCP server
  4. Try Workflows: Test issue-to-implementation workflow
  5. Customize: Create team-specific rules and workflows

Related Documentation: