
Your agent needs to read and act on GitLab: open issues, raise merge requests, watch pipelines, update records on behalf of your developers. GitLab now ships two paths. The official GitLab MCP server reached Beta in GitLab 18.6, and the REST and GraphQL APIs your code has called for years are still there. They cover overlapping but not identical territory, they put you on different auth paths, and for headless or write-heavy agents one of those differences is a hard blocker. Here is how to pick.
The GitLab MCP server is built into GitLab and maintained by GitLab, not a community fork. It started as an experiment in GitLab 18.3 and moved to Beta in GitLab 18.6, with support for the 2025-03-26 and 2025-06-18 MCP protocol specifications added in 18.7.
It is exposed by your own instance at https://<your-gitlab>/api/v4/mcp, not a central hosted endpoint. It is available on Premium and Ultimate, and requires GitLab Duo and beta features to be turned on. Authentication uses OAuth 2.0 Dynamic Client Registration, so a client registers itself, the user approves a browser consent screen, and the client receives an access token.
Official docs: the GitLab MCP server and the MCP server tools.
The GitLab API is two surfaces: a REST API at /api/v4 organized into resource groups for projects, repositories, issues, merge requests, pipelines, members, webhooks, releases, and more, and a GraphQL API at /api/graphql with queries and mutations.
Auth is token-based. The API accepts personal access tokens, OAuth 2.0 tokens, project access tokens, group access tokens, and CI/CD job tokens, passed in the PRIVATE-TOKEN or Authorization: Bearer header. Each token carries explicit scopes such as api, read_api, read_repository, and write_repository.
Official docs: the REST API, the GraphQL API, and REST API authentication.
The MCP server covers the conversational and read surface well, plus issue and merge request creation and pipeline control. The API owns everything operational and every write the MCP server has not shipped.
The MCP server is built for read and review, with a narrow set of writes. Anything that changes the repository or the project configuration lives in the API. If your agent commits code, cuts a release, manages branches, or merges an approved MR, the MCP server does not expose a tool for it. That is not a temporary limitation; it reflects the tool set GitLab has shipped so far.
The MCP server uses OAuth 2.0 Dynamic Client Registration. Every user who connects completes a browser consent flow, and the resulting token is bound to that user's GitLab permissions. The default scope granted through Dynamic Client Registration is mcp, which is purpose-built for the MCP server's tools.
There is one consequence worth stating plainly: an MCP token and a full API token are not interchangeable. The mcp scope is separate from api and read_api. A credential minted for the MCP path does not grant general REST or GraphQL access, and the reverse is also true.
The API gives you more options. Personal access tokens authenticate as a user. OAuth supports Authorization Code, Authorization Code with PKCE, and the Device Authorization Grant for input-limited devices. Project access tokens and group access tokens are bot-user-backed credentials scoped to a single project or group. CI/CD job tokens authenticate pipeline jobs.
One thing GitLab does not offer is a client-credentials or JWT-bearer service grant. The GitLab pattern for a non-interactive service identity is a project or group access token, not a machine OAuth flow.
For a multi-tenant B2B agent acting across many customer namespaces, MCP gives you one OAuth token per user automatically. The API lets you choose: per-user OAuth, or a project or group access token that acts as a bot identity. Neither path solves storage, refresh, or revocation. That is infrastructure you own regardless of the path.
GitLab manages the server, the tool schemas, and the protocol negotiation. You still own per-user token storage, refresh, revocation on disconnect, and tenant isolation. You also own safety: GitLab states explicitly that you are responsible for guarding against prompt injection, and advises using MCP tools only on GitLab objects you trust.
The MCP server is gated behind Premium or Ultimate, GitLab Duo, and beta feature flags. For some teams that governance is a feature. For an agent that needs to deploy without those prerequisites, it is a dependency to plan around.
You own the full operational surface: endpoint selection, request construction, pagination, error handling, retries, and the token lifecycle. The tradeoff is control. The REST API is versioned and follows a deprecation process, and GraphQL mutations are explicit, so a deterministic pipeline is not exposed to schema changes shipped through an MCP server update.
The API also reaches every tier. Core REST endpoints are available on Free, while the MCP server is not.
The GitLab MCP server tools page lists 16 tools: get_mcp_server_version, create_issue, get_issue, create_merge_request, get_merge_request, get_merge_request_commits, get_merge_request_diffs, get_merge_request_pipelines, get_pipeline_jobs, get_job_log, manage_pipeline, create_workitem_note, get_workitem_notes, search, search_labels, and semantic_code_search.
Read the list and the gaps are concrete. There is no tool to write a file or create a commit, no tool to create or delete a branch or tag, no tool to cut a release, no tool to register a webhook, no tool to add a project or group member, and no tool to set a CI/CD variable. Issue and merge request coverage is create-and-read only; there is no update, close, merge, or approve.
The REST API documents all of these as first-class resources, including the Commits API for file operations, Project webhooks, and the full REST resource index. The Scalekit GitLab connector turns that surface into 110 named tools, which is the practical way to see the difference: it includes gitlab_file_create, gitlab_branch_create, gitlab_tag_create, gitlab_release_create, gitlab_project_webhook_create, gitlab_merge_request_merge, and gitlab_merge_request_approve, none of which exist on the official MCP server.
Whether you choose MCP or the API, every user in a multi-tenant agent has their own GitLab credential. Fifty customers means fifty credential lifecycles. The MCP OAuth flow gives you a token per user. The API's OAuth flow gives you an access token per user, and a project or group access token gives you a bot credential per namespace.
OAuth access tokens expire after two hours and must be refreshed. Personal, project, and group access tokens expire at a set date, default 365 days, and can be revoked by the user at any time. In every case the token has to live somewhere encrypted, isolated per tenant, and revocable, and your agent has to detect a revoked or expired token rather than failing silently.
Scalekit's GitLab connector handles the OAuth flow, per-user token storage in the Token Vault, and automatic refresh for both paths. The same auth infrastructure works whether you chose the MCP path or the direct API path. The path decision does not change what you need at the credential layer.
The Scalekit GitLab connector is built on the REST and GraphQL surface, so it covers the writes the official MCP server does not. With the api scope it exposes all 110 tools; with read_api you get a read-only agent. Scalekit acts as the OAuth client, redirects the user to GitLab, stores the token, and refreshes it before expiry. Your code only ever passes a connection_name and a user identifier.
Credentials never touch your agent runtime. The Token Vault stores them per user and per tool, rotates them, and injects them at call time. For a multi-tenant GitLab agent, that means every tool call runs as the specific user who authorized it, with their exact project and group permissions. What the user cannot do in GitLab, the agent cannot do.
Create the connected account, load the scoped tool surface, then run the Claude tool-use loop. Note that the connection_name must match the connection you created in the dashboard exactly, including case.
The Node SDK follows the same shape. Use connectionName and identifier, list the scoped surface, then execute.
Scalekit has a native LangChain adapter. The agent decides what to call; Scalekit handles auth on every invocation, so there is no token plumbing in your agent logic.
Scalekit is framework-agnostic; the scoped tool schemas plug into any LLM API. A Hermes model served through an OpenAI-compatible endpoint consumes the same Scalekit tools. You point the OpenAI client at the Hermes endpoint, list the scoped tools, and execute the one the model selects.
If you need the connector wired to a runtime Scalekit does not document a native adapter for yet, ask in the Scalekit Slack community or talk to Scalekit's engineers.
If your client expects an MCP server, point it at Scalekit's per-user GitLab endpoint instead of standing up your own. The endpoint is static; the identity behind it is per-user.
Auth logs are where multi-tenant agents become operable. Scalekit records who authorized, which agent acted, which tool ran, what scope applied, and what came back. Logs are queryable and exportable to Datadog, Splunk, or any SIEM, with 90-day retention by default.
That matters downstream. When an agent spans GitLab, Slack, and Jira for one user, every tool call resolves to that user's credential and lands in the audit trail attributed to them, not a shared bot account. When a developer leaves, you revoke at the connected-account level and the agent stops acting as them across every connector at once.
If your agent is developer-facing and interactive, and its job is to read, review, search, and create the occasional issue or merge request, the GitLab MCP server is the faster path, with GitLab's permission model and Duo governance applied by default. Account for the Beta status, the Premium or Ultimate requirement, and the browser-only OAuth flow.
If your agent runs headless, writes to the repository, manages releases or webhooks, or has to merge and approve, build against the API directly. The credential management problem is the same either way, and that is the part that needs production-grade infrastructure.
Browse the Scalekit GitLab connector: scalekit.com/agent-connector/gitlab. Or talk to us about your GitLab agent.