OAuth Authentication
GitLab MCP Server supports OAuth 2.1 authentication for use as a Claude Custom Connector. This enables secure per-user authentication without sharing GitLab tokens.
When to Use OAuth
| Scenario | Recommended Mode |
|---|---|
| Personal/local use | Static Token (GITLAB_TOKEN) |
| Team access via Claude Web/Desktop | OAuth Mode |
| Private LAN GitLab with public MCP server | OAuth Mode |
| CI/CD or automated pipelines | Static Token |
Prerequisites
- GitLab 17.1+ (Device Authorization Grant support)
- HTTPS endpoint for gitlab-mcp (required for OAuth)
- GitLab OAuth Application configured
Setup Guide
Step 1: Create GitLab OAuth Application
- In GitLab, navigate to User Settings > Applications (or Admin > Applications for instance-wide)
- Create a new application:
- Name:
GitLab MCP Server - Redirect URI:
https://your-mcp-server.com/oauth/callback - Confidential:
No(PKCE provides security without client secret) - Scopes: Select
apiandread_user
- Name:
- Save and copy the Application ID
TIP
The redirect URI is used by Claude.ai Custom Connectors (Authorization Code Flow). CLI clients use Device Flow which doesn't require redirect URI.
Step 2: Configure Server
# Required for OAuth mode
OAUTH_ENABLED=true
OAUTH_SESSION_SECRET=your-minimum-32-character-secret-key
GITLAB_OAUTH_CLIENT_ID=your-gitlab-application-id
GITLAB_API_URL=https://your-gitlab-instance.com
# Server configuration
PORT=3000
HOST=0.0.0.0
# Optional OAuth settings
GITLAB_OAUTH_CLIENT_SECRET=your-secret # Required only if GitLab app is confidential
GITLAB_OAUTH_SCOPES=api,read_user # Default scopes
OAUTH_TOKEN_TTL=3600 # Token lifetime (seconds)
OAUTH_REFRESH_TOKEN_TTL=604800 # Refresh token lifetime (seconds)
OAUTH_DEVICE_POLL_INTERVAL=5 # Device flow poll interval (seconds)
OAUTH_DEVICE_TIMEOUT=300 # Auth timeout (seconds)Step 3: Deploy with HTTPS
OAuth requires HTTPS. Example with Docker:
docker run -d \
--name gitlab-mcp \
-e OAUTH_ENABLED=true \
-e OAUTH_SESSION_SECRET="$(openssl rand -base64 32)" \
-e GITLAB_OAUTH_CLIENT_ID=your-app-id \
-e GITLAB_API_URL=https://gitlab.example.com \
-e PORT=3000 \
-p 3000:3000 \
ghcr.io/structured-world/gitlab-mcp:latestUse a reverse proxy (nginx, Caddy, Traefik) to add HTTPS. See TLS/HTTPS Configuration.
Claude Web Setup
- Go to claude.ai and sign in
- Navigate to Settings > Connectors
- Click Add custom connector
- Enter your gitlab-mcp server URL:
https://your-mcp-server.com - Click Add
- When prompted, complete authentication:
- You'll see a device code (e.g.,
ABCD-1234) - Open your GitLab instance and enter the code
- Approve the authorization request
- You'll see a device code (e.g.,
- The connector is now active
Claude Desktop Setup
macOS / Linux
Edit ~/.config/claude/claude_desktop_config.json:
{
"mcpServers": {
"gitlab": {
"type": "streamable-http",
"url": "https://your-mcp-server.com/mcp"
}
}
}Windows
Edit %APPDATA%\Claude\claude_desktop_config.json:
{
"mcpServers": {
"gitlab": {
"type": "streamable-http",
"url": "https://your-mcp-server.com/mcp"
}
}
}After adding the server:
- Restart Claude Desktop
- Claude will prompt you to authenticate
- Complete the device flow authorization in GitLab
- Start using GitLab tools with your personal identity
Private LAN GitLab Architecture
For GitLab instances on private networks (not internet-accessible):
+-------------------+ +-------------------+ +-------------------+
| Claude Cloud | HTTPS | gitlab-mcp | HTTP | GitLab Server |
| or Desktop |-------->| (Public IP) |-------->| (Private LAN) |
+-------------------+ +-------------------+ +-------------------+
|
| Device code displayed
v
+-------------------+
| User (on VPN) |
| visits GitLab |
| enters code |
+-------------------+How it works:
- gitlab-mcp server has network access to GitLab (same network or VPN)
- User connects to gitlab-mcp via Claude (public internet)
- gitlab-mcp initiates device authorization with GitLab
- User receives a code and visits GitLab directly (requires VPN/internal access)
- User authenticates in GitLab and enters the code
- gitlab-mcp receives the token and issues an MCP session token
- All subsequent requests use the user's GitLab identity
Requirements:
- gitlab-mcp must reach GitLab API (deploy on same network or use VPN)
- Users must be able to access GitLab web UI (typically via VPN)
- gitlab-mcp must be accessible from internet (for Claude to connect)
OAuth vs Static Token
| Feature | Static Token | OAuth Mode |
|---|---|---|
| Setup complexity | Simple | Moderate |
| Per-user identity | No (shared token) | Yes |
| Token management | Manual | Automatic |
| Audit trail | Single identity | Per-user actions |
| Security | Token in config | No tokens in config |
| Best for | Personal use, CI/CD | Teams, shared access |
OAuth Flows
The server supports two OAuth flows automatically:
| Flow | Trigger | Used By | How It Works |
|---|---|---|---|
| Authorization Code | redirect_uri present | Claude.ai Custom Connectors | Redirects to GitLab OAuth, then back |
| Device Flow | No redirect_uri | CLI clients, Claude Desktop | Shows device code for manual entry |
The flow is selected automatically based on the presence of redirect_uri in the authorization request.
Endpoints
When OAuth is enabled:
| Endpoint | Method | Description |
|---|---|---|
/.well-known/oauth-authorization-server | GET | OAuth metadata discovery |
/.well-known/oauth-protected-resource | GET | Protected resource metadata (RFC 9470) |
/authorize | GET | Start authorization (auto-selects flow) |
/oauth/callback | GET | GitLab callback (Auth Code Flow only) |
/oauth/poll | GET | Poll for completion (Device Flow only) |
/token | POST | Exchange code for tokens |
/register | POST | Dynamic Client Registration (RFC 7591) |
/health | GET | Health check |
Troubleshooting
"OAuth not configured" error
- Ensure
OAUTH_ENABLED=trueis set - Verify
OAUTH_SESSION_SECRETis at least 32 characters - Check
GITLAB_OAUTH_CLIENT_IDis correct
Device code not accepted
- Verify GitLab version is 17.1 or later
- Check OAuth application scopes include
api - Ensure the application is not set as "Confidential"
"Failed to refresh token" error
- GitLab refresh token may have expired
- Re-authenticate through Claude connector settings
Cannot reach GitLab for authentication
- For private LAN GitLab, connect to VPN first
- Verify you can access GitLab web UI in your browser
