This guide explains how to set up OAuth2 authentication for the GitLab MCP server.
OAuth2 provides several advantages over personal access tokens:
- Better Security: Tokens are obtained through a secure browser-based flow
- Automatic Token Refresh: Tokens are automatically refreshed when they expire
- Scoped Access: You can limit what the application can access
- Easy Revocation: You can revoke access from your GitLab settings at any time
- A GitLab account (GitLab.com or self-hosted GitLab instance)
- Node.js installed on your machine
- The GitLab MCP server installed
⚠️ Important: OAuth is designed for local/desktop environments (e.g., Claude Desktop, VS Code). For Docker deployments, use Personal Access Token instead, as OAuth requires browser-based authentication and a local callback server which does not work properly in containerized environments.
-
Log in to your GitLab instance (e.g., https://gitlab.com)
-
Navigate to Applications:
- Click on your profile picture in the top right
- Select Settings (or Preferences)
- In the left sidebar, click Applications
-
Create a new application:
- Click Add new application (or New application)
- Fill in the details:
- Name:
GitLab MCP Server(or any name you prefer) - Redirect URI:
http://127.0.0.1:8888/callback- Note: If you want to use a different port, update this URI accordingly
- Confidential:
- Unchecked (recommended for desktop/CLI apps): Uses PKCE for security, no client secret needed
- Checked (for server environments): Requires client secret, provides additional security for server-side apps
- Scopes: Select the following scope:
api- Grants complete read/write access to the API (includes all necessary permissions)
- Name:
-
Save the application:
- Click Save application
- Important: Copy the Application ID - you'll need this as your
GITLAB_OAUTH_CLIENT_ID - For Confidential apps: Also copy the Secret - you'll need this as
GITLAB_OAUTH_CLIENT_SECRET
Edit your Claude configuration file:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
Linux: ~/.config/Claude/claude_desktop_config.json
Add or update the GitLab MCP server configuration:
{
"mcpServers": {
"gitlab": {
"command": "npx",
"args": ["-y", "@zereight/mcp-gitlab"],
"env": {
"GITLAB_USE_OAUTH": "true",
"GITLAB_OAUTH_CLIENT_ID": "your_application_id_here",
"GITLAB_OAUTH_CLIENT_SECRET": "your_client_secret_here",
"GITLAB_OAUTH_REDIRECT_URI": "http://127.0.0.1:8888/callback",
"GITLAB_API_URL": "https://gitlab.com/api/v4"
}
}
}
}Note:
GITLAB_OAUTH_CLIENT_SECRETis only required if you checked "Confidential" when creating your GitLab OAuth application. For non-confidential (public) apps, you can omit this variable.
If you're using a self-hosted GitLab instance, update the GITLAB_API_URL:
{
"mcpServers": {
"gitlab": {
"command": "npx",
"args": ["-y", "@zereight/mcp-gitlab"],
"env": {
"GITLAB_USE_OAUTH": "true",
"GITLAB_OAUTH_CLIENT_ID": "your_application_id_here",
"GITLAB_OAUTH_CLIENT_SECRET": "your_client_secret_here",
"GITLAB_OAUTH_REDIRECT_URI": "http://127.0.0.1:8888/callback",
"GITLAB_API_URL": "https://your-gitlab-instance.com/api/v4"
}
}
}
}-
Start the MCP server (or restart Claude if using Claude Desktop)
-
When the server starts, it will:
- Detect that no OAuth token exists
- Start a local HTTP server on port 8888
- Automatically open your default browser to the GitLab authorization page
-
In your browser:
- You'll see the GitLab authorization page
- Review the requested permissions
- Click Authorize to grant access
-
After authorization:
- You'll be redirected to a success page
- You can close the browser window
- The token is securely saved to
~/.gitlab-mcp-token.json
-
The MCP server is now authenticated and ready to use!
The OAuth token is stored in a JSON file with restricted permissions (readable only by you):
- Default location:
~/.gitlab-mcp-token.json - Custom location: Set
GITLAB_OAUTH_TOKEN_PATHenvironment variable
The token file contains:
- Access token
- Refresh token (if provided)
- Expiry time
- Token type
The MCP server automatically handles token refresh:
- Checks token expiry before each API request
- Automatically refreshes the token if it's expired (or will expire within 5 minutes)
- If refresh fails, it will restart the OAuth flow
If port 8888 is already in use, you can use a different port:
-
Update the Redirect URI in your GitLab OAuth application:
http://127.0.0.1:9999/callback -
Update the
GITLAB_OAUTH_REDIRECT_URIenvironment variable:{ "env": { "GITLAB_OAUTH_REDIRECT_URI": "http://127.0.0.1:9999/callback" } }
If the browser doesn't open automatically:
- Look for the authorization URL in the server logs
- Manually copy and paste the URL into your browser
New in v2.0.8+: The MCP server now supports multiple Claude sessions running simultaneously!
When you start a new Claude session while an OAuth server is already running:
- The new instance automatically detects that the port is in use
- It connects to the existing OAuth server as a client
- The existing server opens a new browser window for authentication
- Each session gets its own token independently
What this means for you:
- You can run multiple Claude sessions without port conflicts
- Each session will trigger its own OAuth flow
- The first session that starts becomes the OAuth server
- Subsequent sessions connect to it as clients
- All sessions can authenticate independently
If you still want to use a different port:
- Change the port as described in "Using a Different Port" above
- Or stop the process using port 8888
If you see a "redirect URI mismatch" error:
- Verify that the redirect URI in your GitLab OAuth application exactly matches the one in your configuration
- Make sure to include the
/callbackpath
If you see permissions errors:
- The token file is automatically created with restricted permissions (0600)
- Make sure your user has write access to the directory where the token file is stored
To force re-authentication, delete the token file:
rm ~/.gitlab-mcp-token.jsonThen restart the MCP server to go through the OAuth flow again.
To revoke the MCP server's access to your GitLab account:
- Go to your GitLab Settings → Applications
- Find the Authorized applications section
- Find "GitLab MCP Server" (or whatever name you used)
- Click Revoke
- Delete the local token file:
rm ~/.gitlab-mcp-token.json
- Keep your Client ID confidential: While it's not a secret, don't share it unnecessarily
- Don't share your token file: The
~/.gitlab-mcp-token.jsonfile contains your access token - Use scoped access: Only grant the scopes your application needs
- Regularly review authorized applications: Periodically check your authorized applications in GitLab
- Revoke access when done: If you stop using the MCP server, revoke its access
When creating your GitLab OAuth application, you can choose between two types:
| Feature | Confidential | Non-Confidential (Public) |
|---|---|---|
| Client Secret | Required (GITLAB_OAUTH_CLIENT_SECRET) |
Not needed |
| Security Method | Client secret + PKCE | PKCE only |
| Use Case | Server-side applications | Desktop/CLI applications |
| Secret Storage | Must store secret securely | No secret to protect |
| Recommendation | When you control the server | Recommended for MCP |
Non-Confidential (Recommended for MCP):
- Desktop applications like Claude Desktop
- CLI tools and local development
- Any environment where you cannot securely store a client secret
- Uses PKCE (Proof Key for Code Exchange) for security
Why Recommended? Per RFC 8252 (OAuth 2.0 for Native Apps), native applications (desktop/CLI apps) cannot securely store client secrets, so public clients with PKCE are recommended.
Confidential:
- Server-side applications where you can securely store secrets
- Enterprise deployments with strict security requirements
- When your organization requires client secret authentication
| Feature | OAuth2 | Personal Access Token |
|---|---|---|
| Setup complexity | Medium (requires OAuth app) | Low (just create token) |
| Security | Better (browser-based flow) | Good (manual token) |
| Token rotation | Automatic | Manual |
| Revocation | Easy (from GitLab UI) | Manual (delete token) |
| Expiration | Configurable | Configurable |
| Scoping | Application-level | User-level |
{
"env": {
"GITLAB_OAUTH_TOKEN_PATH": "/path/to/custom/token.json"
}
}You can combine OAuth with read-only mode:
{
"env": {
"GITLAB_USE_OAUTH": "true",
"GITLAB_OAUTH_CLIENT_ID": "your_client_id",
"GITLAB_READ_ONLY_MODE": "true"
}
}You can restrict access to specific projects:
{
"env": {
"GITLAB_USE_OAUTH": "true",
"GITLAB_OAUTH_CLIENT_ID": "your_client_id",
"GITLAB_ALLOWED_PROJECT_IDS": "123,456,789"
}
}


