Skip to main content
Glama

GitLab MCP Server

GitHub stars npm downloads npm GitHub License Ask DeepWiki MCP Toplist mcpindex

English | 한국어 | 简体中文 | Português (Brasil)

📖 Documentation → · llms.txt · llms-full.txt

Default: 40 tools (38 core + discover_tools + help). 288 tools exist in total (285 in toolsets + execute_graphql + discover_tools + help). Start lean; call discover_tools to activate more for this session.

Token budget: MCP clients send the whole tools/list to the model at session start. Keep the default (~40 tools, ~12k schema tokens). Call discover_tools to activate a category for this session (session-only; with OAUTH_STATELESS_MODE=true persist a named GITLAB_TOOLSETS list), or use Skill + CLI and skip MCP schemas. Do not set GITLAB_TOOLSETS=all — it loads ~all tools and costs ~73k schema tokens. See tools/list size and comparison.

Install the zereight-mcp-gitlab binary first with npm install -g @zereight/mcp-gitlab, or Homebrew brew tap zereight/gitlab-mcp https://github.com/zereight/gitlab-mcp and brew install zereight/gitlab-mcp/zereight-mcp-gitlab. Official MCP Registry listing: io.github.zereight/gitlab-mcp. One-liner: npx -y @zereight/mcp-gitlab@latest.

Without → With

Without this MCP

With this MCP

Paste MR URLs and diffs into chat

list_merge_request_changed_files → batched get_merge_request_file_diff

Hunt job logs in the GitLab UI

get_pipeline_job_output with pagination

Re-explain the project path every turn

project_id=group%2Fproject and merge_request_iid=123

Three install paths

Path

When

How

Local IDE

Cursor, Claude Code, Codex on your machine

stdio + PAT or local OAuth

Shared HTTP

Team or hosted MCP

Streamable HTTP URL + remote auth or MCP OAuth

Claude.ai

Claude web connectors

Public HTTPS + GITLAB_MCP_OAUTH

Install

Install in Cursor

Install the binary first (npm install -g @zereight/mcp-gitlab, or Homebrew brew tap zereight/gitlab-mcp https://github.com/zereight/gitlab-mcp then brew install zereight/gitlab-mcp/zereight-mcp-gitlab). Read the token without echo:

read -rs GITLAB_PERSONAL_ACCESS_TOKEN && export GITLAB_PERSONAL_ACCESS_TOKEN
# Claude Code
claude mcp add gitlab --transport stdio --scope local --env GITLAB_PERSONAL_ACCESS_TOKEN="$GITLAB_PERSONAL_ACCESS_TOKEN" --env GITLAB_API_URL=https://gitlab.com/api/v4 -- zereight-mcp-gitlab

# Codex
codex mcp add gitlab --env GITLAB_PERSONAL_ACCESS_TOKEN="$GITLAB_PERSONAL_ACCESS_TOKEN" --env GITLAB_API_URL=https://gitlab.com/api/v4 -- zereight-mcp-gitlab

Other clients: VS Code · GitHub Copilot · JSON clients · Cursor details

Agent paste-prompt

Copy this into an agent that can edit MCP config:

Install the GitLab MCP server (@zereight/mcp-gitlab) for this workspace.
Binary: zereight-mcp-gitlab (npm i -g @zereight/mcp-gitlab, or npx -y @zereight/mcp-gitlab@latest).
Auth: GITLAB_PERSONAL_ACCESS_TOKEN plus GITLAB_API_URL=https://gitlab.com/api/v4 (or GITLAB_USE_OAUTH=true).
Local: claude mcp add gitlab --transport stdio --scope local --env GITLAB_PERSONAL_ACCESS_TOKEN="$GITLAB_PERSONAL_ACCESS_TOKEN" --env GITLAB_API_URL=https://gitlab.com/api/v4 -- zereight-mcp-gitlab
Or: codex mcp add gitlab --env GITLAB_PERSONAL_ACCESS_TOKEN="$GITLAB_PERSONAL_ACCESS_TOKEN" --env GITLAB_API_URL=https://gitlab.com/api/v4 -- zereight-mcp-gitlab
Cursor: use the README deeplink or docs/clients/cursor.md.
Remote HTTP: point the client at https://mcp.example.com/mcp (Streamable HTTP). Claude.ai needs GITLAB_MCP_OAUTH on that host.
Default list: 40 tools (38 core + discover_tools + help). Call discover_tools to expand. Do not set GITLAB_TOOLSETS=all (loads ~all schemas, ~73k tokens). Do not enable the api toolset unless you accept its bypass risk.
Equal non-MCP path: npx skills add zereight/gitlab-mcp --skill gitlab-mcp-skill plus the zereight-mcp-gitlab CLI.

Remote HTTP

First-class option for a hosted or self-hosted server. Point the client at a Streamable HTTP URL:

{
  "mcpServers": {
    "gitlab": {
      "type": "http",
      "url": "https://mcp.example.com/mcp"
    }
  }
}
  • Hosted / Claude.ai: GITLAB_MCP_OAUTH=true on the server (see MCP OAuth)

  • Per-user PAT headers: REMOTE_AUTHORIZATION=true (see Remote Authorization)

  • Local Docker examples are in Usage

Skill + CLI (no MCP required)

Skill + CLI is an equal path, not a fallback. Same workflows, full payloads in a terminal, no MCP registration.

npx skills add zereight/gitlab-mcp --skill gitlab-mcp-skill
zereight-mcp-gitlab user whoami
zereight-mcp-gitlab mr list

See CLI without MCP and skills/gitlab-mcp/.

MCP vs Human CLI

Use MCP when

Use the CLI when

The agent needs structured tools in chat

You need the full payload (diffs, logs, artifacts)

jmespath or compact results are enough

GITLAB_MCP_COMPACT_RESULTS is on and you want the rest in a terminal

You already registered the server

You have a PAT or ran auth and do not want MCP

Human CLI is never compacted. Destructive tools and GITLAB_TOOL_POLICY_APPROVE tools need --yes.

Tips

project_id is a numeric ID or a URL-encoded path. Example: group group, project project, merge request !123 → project_id=group%2Fproject, merge_request_iid=123. Nested groups use %2F between every segment (group%2Fsubgroup%2Fproject).

FAQ

How do I authenticate? Local desktop: GITLAB_PERSONAL_ACCESS_TOKEN (or GITLAB_PERSONAL_ACCESS_TOKEN_FILE) is the simplest. Local OAuth is GITLAB_USE_OAUTH=true. Remote Claude.ai uses GITLAB_MCP_OAUTH. Multi-user HTTP uses REMOTE_AUTHORIZATION and a per-request token header.

Why do I only see ~40 tools? The default core toolset is 38 tools plus always-on discover_tools and help. That is intentional: a client sends every listed schema to the model up front. Call discover_tools with no args to list categories, then pass a category (pipelines, wiki, …) to activate it for this session. Session-only; with OAUTH_STATELESS_MODE=true persist a named GITLAB_TOOLSETS list. Do not set GITLAB_TOOLSETS=all — it loads ~all schemas (~73k tokens) and still does not enable api.

Local OAuth vs MCP OAuth vs remote auth? Local OAuth opens a browser on the same machine as the server. MCP OAuth is for a public HTTPS server and clients such as Claude.ai. Remote authorization forwards the caller's PAT or job token; there is no OAuth dance.

How do I shrink huge replies? Pass jmespath on any tool call. Or set GITLAB_MCP_COMPACT_RESULTS=true so oversized MCP replies become a preview plus a CLI command. Use the CLI when you need the full payload.

Why is the api toolset dangerous? gitlab_api_request bypasses group/project allowlists, other tool filters, and per-tool safety checks. Prompt injection can drive it. Enable it only by listing api in GITLAB_TOOLSETS. all, discover_tools, and GITLAB_TOOLS do not.

Cursor rule / CLAUDE.md snippet

GitLab merge requests, issues, and pipelines go through this MCP (@zereight/mcp-gitlab).
Start with the default core tools. Call discover_tools to expand. Do not set GITLAB_TOOLSETS=all.
Prefer list_merge_request_changed_files, then batched get_merge_request_file_diff.
Use jmespath or compact results; use the CLI for full diffs and job logs.

Star History Chart

@zereight/mcp-gitlab

Agent-workflow-optimized GitLab MCP — manage projects, merge requests, issues, pipelines, wiki, releases, tags, milestones, and more through stdio, SSE, and Streamable HTTP.

Supports PAT, OAuth, read-only mode, dynamic API URLs, and remote authorization for VS Code, Claude, Cursor, Copilot, and other MCP clients.

Why use this GitLab MCP?

  • Default 40 tools (38 core + discover_tools + help); 288 total — start lean; call discover_tools to activate more without CQRS-style grouping. GITLAB_TOOLSETS=all loads ~all schemas (~73k tokens); prefer discover-on-demand or Skill + CLI

  • MR 2-step review — list_merge_request_changed_files → batched get_merge_request_file_diff

  • Agent Skill built in — workflow guidance in skills/gitlab-mcp/

  • Flexible auth — Personal Access Token, local OAuth2 browser flow, MCP OAuth proxy, and per-request remote authorization

  • Multiple transports — stdio for local clients, SSE for legacy clients, and Streamable HTTP for modern remote deployments

  • Client-friendly setup — examples for Claude Code, Codex, Antigravity, OpenCode, Copilot, Cline, Roo Code, Cursor, Kilo Code, and Amp Code

  • Self-hosted ready — works with custom GitLab instances, proxy settings, and dynamic API URL routing

  • JMESPath result filtering — optional jmespath on tool calls (see tools/list) shrinks JSON results without changing GitLab API requests; when response masking is enabled, JMESPath runs on masked data.

How we compare

@zereight/mcp-gitlab

GitLab MCP A (community CQRS-style)

GitLab official MCP server

Best for

AI agent workflows

Enterprise multi-instance / grouped tools

Built into GitLab, no separate install

Tool model

288 tools: 285 in toolsets + execute_graphql + discover_tools + help

~50–60 grouped browse_* / manage_* tools

Toolsets chosen with an HTTP header

MR review

2-step batched diff

Varies

get_merge_request with diffs

Node.js

>=20.0.0

Often >=24

Node.js 20+ for stdio via mcp-remote

License

MIT

Varies

Part of GitLab

tools/list size (measured 2026-11-05)

A client sends the whole tools/list result to the model at session start. Token estimate is UTF-8 bytes / 4.

Profile

Tools

JSON bytes

Est. tokens

Default (core + discover_tools + help)

40

46,943

11,736

GITLAB_TOOL_PROFILE=slim

39

45,935

11,484

GITLAB_TOOLSETS=all

286

293,906

73,477

Re-measure with npm run build && npm run test:mock (test/tools-list-budget.test.ts) after description or schema changes.

GitLab also ships an official MCP server.

  • Free, Premium, and Ultimate. Moved from Premium to Free in GitLab 19.2. Generally available in GitLab 19.5.

  • On GitLab.com, a top-level group Owner allows access to the MCP server. On GitLab Self-Managed and GitLab Dedicated, an administrator controls the instance setting. Default rules are on the official page.

  • Remote clients use HTTP https://<gitlab.example.com>/api/v4/mcp with OAuth 2.0 dynamic client registration.

  • stdio goes through mcp-remote and needs Node.js 20 or later.

  • Toolsets use the X-Gitlab-Enabled-Mcp-Server-Toolsets header. An optional X-Gitlab-Mcp-Server-Tool-Name-Prefix header keeps the first 32 characters of a tool-name prefix.

Full comparison with the official GitLab MCP server →

Quick start: choose either Personal Access Token or OAuth2 setup below, install @zereight/mcp-gitlab, and use zereight-mcp-gitlab in your MCP client configuration.

Client Setup Guides

Related MCP server: gitlab-mcp

Usage

Setup Overview

Authentication Methods

The server supports four authentication methods:

For local/desktop use (most common):

  1. Personal Access Token (GITLAB_PERSONAL_ACCESS_TOKEN or GITLAB_PERSONAL_ACCESS_TOKEN_FILE) — simplest setup

  2. OAuth2 — Local Browser (GITLAB_USE_OAUTH) — recommended for better security

For server/remote deployments:

  1. OAuth2 — MCP Proxy (GITLAB_MCP_OAUTH) — for remote MCP clients such as Claude.ai

  2. Remote Authorization (REMOTE_AUTHORIZATION) — multi-user deployments where each caller provides their own token

Quick setup paths

For the simplest local setup, start with a Personal Access Token. For browser-based local auth, use OAuth2. For remote or multi-user deployments, continue to the MCP OAuth and Remote Authorization sections later in this README.

Install the server once:

brew tap zereight/gitlab-mcp https://github.com/zereight/gitlab-mcp
brew install zereight/gitlab-mcp/zereight-mcp-gitlab

Or with npm:

npm install -g @zereight/mcp-gitlab

Or with Nix, by adding this flake to your own:

# flake.nix
inputs.gitlab-mcp.url = "github:zereight/gitlab-mcp";

# wherever you configure your MCP client:
command = lib.getExe inputs.gitlab-mcp.packages.${system}.default;

The store path is pinned by your lock file; update it with nix flake update gitlab-mcp.

The examples use zereight-mcp-gitlab, a less collision-prone alias for the legacy mcp-gitlab binary. If your MCP client cannot find it, use the absolute path from which zereight-mcp-gitlab.

No global install? Pin npx to the previous stable release (the version these docs recommend), for example npx -y @zereight/mcp-gitlab@2.3.21. If you always want the newest release, use npx -y @zereight/mcp-gitlab@latest instead. To try a fix merged to main before the next stable release, use npx -y @zereight/mcp-gitlab@next, a pre-release build that is not meant for production. The server prints a notice to stderr on startup when a newer version is available (disable with GITLAB_DISABLE_VERSION_CHECK=true).

Claude Desktop one-click install (MCP Bundle)

Every GitHub release after v2.3.1 ships a gitlab-mcp.mcpb MCP Bundle. Download the latest bundle and open it with Claude Desktop (or drag it into Settings → Extensions). Claude Desktop asks for your Personal Access Token (stored as a sensitive value) and lets you set GITLAB_API_URL, GITLAB_PERMISSION_MODE, GITLAB_TOOLSETS, and GITLAB_MASKING_ENABLED. No separate Node.js or npm install is needed.

To build the bundle from source, run npm run pack:mcpb (writes gitlab-mcp.mcpb).

Using CLI Arguments (for clients with env var issues)

Some MCP clients (like GitHub Copilot CLI) have issues with environment variables. Use CLI arguments instead:

{
  "mcpServers": {
    "gitlab": {
      "command": "zereight-mcp-gitlab",
      "args": ["--token=YOUR_GITLAB_TOKEN", "--api-url=https://gitlab.com/api/v4"],
      "tools": ["*"]
    }
  }
}

Available CLI arguments:

  • --token - GitLab Personal Access Token (replaces GITLAB_PERSONAL_ACCESS_TOKEN)

  • --api-url - GitLab API URL (replaces GITLAB_API_URL)

  • --read-only=true - Deprecated (removed in next major (v3.0.0)); use --permission-mode=readonly instead (replaces GITLAB_READ_ONLY_MODE)

  • --permission-mode - Permission level: readonly, modify (no delete or teardown tools), or full (replaces GITLAB_PERMISSION_MODE, default full)

  • --toolsets - Named toolsets (replaces GITLAB_TOOLSETS; unset uses the lean core default). Do not pass all unless you accept ~73k schema tokens. gitlab_api_request needs --toolsets=api

  • --tools=list_issues - Add individual tools (replaces GITLAB_TOOLS)

  • --use-wiki=true - Deprecated (removed in next major (v3.0.0)); use --toolsets=core,wiki instead (replaces USE_GITLAB_WIKI)

  • --use-milestone=true - Deprecated (removed in next major (v3.0.0)); use --toolsets=core,milestones instead (replaces USE_MILESTONE)

  • --use-pipeline=true - Deprecated (removed in next major (v3.0.0)); use --toolsets=core,pipelines and append validate_ci_lint,validate_project_ci_lint to the existing --tools list (or set --tools=validate_ci_lint,validate_project_ci_lint when that list is unset) (replaces USE_PIPELINE)

  • --disable-version-check=true - Disable the startup new-version notice (replaces GITLAB_DISABLE_VERSION_CHECK)

  • --masking-enabled=true - Enable text-response masking (replaces GITLAB_MASKING_ENABLED)

  • --masking-config - Path to a masking configuration file (replaces GITLAB_MASKING_CONFIG)

  • --masking-policy-file - Path to a protected managed-policy file (replaces GITLAB_MASKING_POLICY_FILE)

  • --masking-workspace-dir - Directory used to resolve masking files (replaces GITLAB_MASKING_WORKSPACE_DIR)

  • --download-dir - Directory download_attachment and download_job_artifacts save files under (replaces GITLAB_DOWNLOAD_DIR; default .gitlab-mcp-downloads)

  • --compact-results=true - Truncate oversized MCP tool replies and attach a CLI command for the full payload (replaces GITLAB_MCP_COMPACT_RESULTS; default off)

  • --compact-result-chars - Character threshold for compacting (replaces GITLAB_MCP_COMPACT_RESULT_CHARS; default 4000)

  • --compact-tools - Comma-separated tool names to compact when oversized, without turning global compact on (replaces GITLAB_MCP_COMPACT_TOOLS)

  • --list-summary-default=true - list_* tools and mr_discussions treat an omitted summary argument as true; summary: false still returns the full JSON (replaces GITLAB_MCP_LIST_SUMMARY_DEFAULT; default off)

  • --tool-profile - full (default) or slim. slim drops draft notes, emoji reactions, labels, CI catalog tools, and create_group from the initial list. Ignored when GITLAB_TOOLSETS is set (replaces GITLAB_TOOL_PROFILE)

If you already set GITLAB_TOOLSETS or --toolsets, append wiki, milestones, or pipelines to that list instead of replacing it. If you already set GITLAB_TOOLS or --tools, append validate_ci_lint and validate_project_ci_lint to that list instead of replacing it. An explicit list replaces the default core toolset; it does not merge.

CLI arguments take precedence over environment variables.

zereight-mcp-gitlab auth is a subcommand (not an MCP server flag). It runs GitLab device flow and exits. See CLI Arguments.

The same binary is also a gh-style GitLab CLI (tool <name> or curated forms such as mr list). No MCP registration is needed — set a PAT, or run auth and set GITLAB_USE_OAUTH=true: see CLI without MCP. setup --cursor / setup --claude prints client config; doctor checks token, API URL, toolsets, and version. Use it for the full payload in a terminal. MCP replies stay in the chat unless you set GITLAB_MCP_COMPACT_RESULTS=true (or --compact-results), which replaces oversized tool replies with a preview and a CLI command. Human CLI is never compacted. Same permission mode, toolsets, denied-tools regex, and tool-policy filters. Destructive tools and GITLAB_TOOL_POLICY_APPROVE tools need --yes. See Human CLI.

Fine-grained tool filtering: use GITLAB_PERMISSION_MODE=modify to allow create/update while blocking every delete tool and the destructive teardown tools (cancel_pipeline, cancel_pipeline_job, stop_environment, stop_stale_environments, unprotect_branch, unprotect_tag) — including destructive mutations (deletion and teardown verbs) through execute_graphql and push_files delete/move actions — or GITLAB_PERMISSION_MODE=readonly for read-only access. You can also enable toolset groups with GITLAB_TOOLSETS=<group,…>, allow-list individual tools with GITLAB_TOOLS=<tool,…> (e.g. read-only groups plus a few specific write tools), and deny-list by pattern with GITLAB_DENIED_TOOLS_REGEX. The legacy USE_GITLAB_WIKI / USE_MILESTONE / USE_PIPELINE flags are deprecated (removed in next major (v3.0.0)). Use GITLAB_TOOLSETS=core,wiki, core,milestones, or core,pipelines (USE_PIPELINE also needs validate_ci_lint,validate_project_ci_lint appended to an existing GITLAB_TOOLS list instead of replacing it). If you already set GITLAB_TOOLSETS, append the toolset to your existing list instead of replacing it. If GITLAB_TOOLS is unset, set GITLAB_TOOLS=validate_ci_lint,validate_project_ci_lint. If it is already set, append validate_ci_lint,validate_project_ci_lint instead of replacing that list. See Tools Reference and Environment Variables.

CAUTION

gitlab_api_request (toolset api) bypasses GITLAB_ALLOWED_GROUPS and other group restrictions, project allowlists, tool-level restrictions (GITLAB_TOOLS, GITLAB_DENIED_TOOLS_REGEX on other tools), and individual tool safety checks. The full token permission scope is exposed. Prompt injection can drive this tool. Operators who rely on these restrictions must NOT enable it. Enable it only by listing api in GITLAB_TOOLSETS (GITLAB_TOOLSETS=all, discover_tools, GITLAB_TOOLS, legacy USE_* flags, and GITLAB_TOOL_PROFILE do not). With GITLAB_ALLOWED_PROJECT_IDS or a session project scope, only /projects/:id paths for an allowed project are accepted. Endpoints such as /search, /users, /groups/:id, and /runners are rejected. Body and query parameters that name another project are not checked. GITLAB_PROJECT_ID and OAuth group allowlists are not enforced.

  • sse

Pass the variable name only. The Docker client copies the exported GITLAB_PERSONAL_ACCESS_TOKEN into the container.

docker run -i --rm \
  -e HOST=0.0.0.0 \
  -e GITLAB_PERSONAL_ACCESS_TOKEN \
  -e GITLAB_API_URL="https://gitlab.com/api/v4" \
  -e GITLAB_PERMISSION_MODE=readonly \
  -e GITLAB_TOOLSETS=core,wiki,milestones,pipelines \
  -e SSE=true \
  -e SSE_AUTH_TOKEN=your_mcp_sse_token \
  -p 3333:3002 \
  zereight050/gitlab-mcp
{
  "mcpServers": {
    "gitlab": {
      "type": "sse",
      "url": "http://localhost:3333/sse",
      "headers": {
        "Authorization": "Bearer your_mcp_sse_token"
      }
    }
  }
}
  • streamable-http

docker run -i --rm \
  -e HOST=0.0.0.0 \
  -e REMOTE_AUTHORIZATION=true \
  -e GITLAB_API_URL="https://gitlab.com/api/v4" \
  -e GITLAB_PERMISSION_MODE=readonly \
  -e GITLAB_TOOLSETS=core,wiki,milestones,pipelines \
  -e STREAMABLE_HTTP=true \
  -p 3333:3002 \
  zereight050/gitlab-mcp
{
  "mcpServers": {
    "gitlab": {
      "type": "streamable-http",
      "url": "http://localhost:3333/mcp",
      "headers": {
        "Authorization": "Bearer glpat-..."
      }
    }
  }
}

Using MCP OAuth Proxy (GITLAB_MCP_OAUTH)

For server/remote deployments only. This mode requires the MCP server to be deployed with a publicly accessible HTTPS URL. For local/desktop use, see GITLAB_USE_OAUTH above.

For remote MCP clients that support the MCP OAuth specification (e.g. Claude.ai). The server acts as a full OAuth 2.0 authorization server — unauthenticated requests receive a 401 + WWW-Authenticate response, which triggers the OAuth browser flow automatically on the client side.

Remote MCP clients such as OpenCode, MCPJam, and Claude.ai can send their own callback URL during authorization. If you cannot register every client callback URL in GitLab, enable GITLAB_OAUTH_CALLBACK_PROXY=true. With callback proxy mode, GitLab only needs one registered redirect URI: {MCP_SERVER_URL}/callback.

GITLAB_OAUTH_REDIRECT_URI is for local OAuth (GITLAB_USE_OAUTH) only. It does not override remote MCP OAuth client callback URLs and should not be used to fix remote Unregistered redirect_uri errors.

This variable exists because the local OAuth flow starts a browser on the same machine as the MCP server and listens for the callback on a local HTTP server, for example http://127.0.0.1:8888/callback.

Remote MCP OAuth is different. In GITLAB_MCP_OAUTH=true mode, the MCP client provides its own callback URL during /authorize. GITLAB_OAUTH_REDIRECT_URI does not replace that client-provided URL.

Mode

Enable with

Callback variable

GitLab redirect URI

Local OAuth

GITLAB_USE_OAUTH=true

GITLAB_OAUTH_REDIRECT_URI

http://127.0.0.1:8888/callback or your local callback

Remote MCP OAuth

GITLAB_MCP_OAUTH=true

GITLAB_OAUTH_CALLBACK_PROXY=true

{MCP_SERVER_URL}/callback

Use GITLAB_OAUTH_REDIRECT_URI only when the MCP server itself owns the local browser callback. Use GITLAB_OAUTH_CALLBACK_PROXY=true when a remote MCP client owns the callback URL.

How it works: You deploy this MCP server somewhere with a public HTTPS URL. MCP clients connect to {MCP_SERVER_URL}/mcp. The server handles the OAuth 2.0 flow, exchanging credentials with GitLab on behalf of the client.

Prerequisites:

  1. A publicly accessible HTTPS server URL (MCP_SERVER_URL) — use ngrok for local testing

  2. A pre-registered GitLab OAuth application with api (or read_api) scopes — Go to Admin area → Applications, set Redirect URI to {MCP_SERVER_URL}/callback

Environment Variable

Required

Description

GITLAB_MCP_OAUTH

✅

Set to true to enable

GITLAB_API_URL

✅

GitLab API base URL. Do not embed credentials (user:pass@) in the URL; they are ignored. A comma in a password must be written as %2C.

GITLAB_OAUTH_APP_ID

✅

GitLab OAuth Application ID

MCP_SERVER_URL

✅

Public HTTPS URL of this MCP server

STREAMABLE_HTTP

✅

Must be true

GITLAB_OAUTH_CALLBACK_PROXY

optional

Set to true to use the MCP server's fixed /callback URL

GITLAB_OAUTH_ALLOWED_REDIRECT_URIS

optional

Client callback URLs that callback proxy mode will redirect to (default: Claude, ChatGPT, Cursor and loopback callbacks; defaults,<url> to add one)

GITLAB_OAUTH_SCOPES

optional

Comma-separated scopes (default: api,read_api,read_user)

GITLAB_OAUTH_ALLOWED_GROUPS

optional

Comma-separated group full paths — only members (and subgroup members) may use the server (replaces deprecated GITLAB_ALLOWED_GROUPS)

OAUTH_DISABLE_REFRESH_TOKEN

optional

Set to true to issue no refresh tokens: users re-authorize in the browser each time the GitLab access token expires (2 h), regardless of the session TTL

When STREAMABLE_HTTP=true, server-side GitLab credentials (GITLAB_PERSONAL_ACCESS_TOKEN, GITLAB_JOB_TOKEN, GITLAB_AUTH_COOKIE_PATH, or GITLAB_USE_OAUTH) require REMOTE_AUTHORIZATION=true, GITLAB_MCP_OAUTH=true, or STREAMABLE_HTTP_AUTH_TOKEN.

Troubleshooting Unregistered redirect_uri

Check the redirect_uri in the browser URL. If it points to a client callback such as http://127.0.0.1:xxxxx/.../callback, enable:

GITLAB_OAUTH_CALLBACK_PROXY=true

Do not fix remote MCP OAuth by changing GITLAB_OAUTH_REDIRECT_URI. That variable is for local OAuth (GITLAB_USE_OAUTH) only.

docker run -i --rm \
  -e HOST=0.0.0.0 \
  -e GITLAB_MCP_OAUTH=true \
  -e GITLAB_OAUTH_CALLBACK_PROXY=true \
  -e STREAMABLE_HTTP=true \
  -e MCP_SERVER_URL=https://your-server.example.com \
  -e GITLAB_API_URL="https://gitlab.com/api/v4" \
  -e GITLAB_OAUTH_APP_ID=your_app_id \
  -p 3000:3002 \
  zereight050/gitlab-mcp

MCP client configuration:

{
  "mcpServers": {
    "gitlab": {
      "type": "http",
      "url": "https://your-server.example.com/mcp"
    }
  }
}

Using Remote Authorization (REMOTE_AUTHORIZATION)

For server/remote deployments only. Each HTTP caller provides their own GitLab token directly in request headers — no OAuth flow involved.

For multi-user or multi-tenant deployments where each caller provides their own GitLab token in the HTTP request header. No OAuth flow — the MCP server forwards the token to GitLab on behalf of the caller.

Header priority: Private-Token > JOB-TOKEN > Authorization: Bearer

Environment Variable

Required

Description

REMOTE_AUTHORIZATION

✅

Set to true to enable

STREAMABLE_HTTP

✅

Must be true

ENABLE_DYNAMIC_API_URL

optional

Allow per-request GitLab URL via X-GitLab-API-URL header

GITLAB_ALLOWED_HOSTS

optional

Comma-separated allowed X-GitLab-API-URL hosts; GITLAB_API_URL hosts are always allowed. Also trusted as download redirect targets (release assets, job artifacts, uploaded attachments); list private-network hosts here

GITLAB_ALLOW_UNAUTHENTICATED_TOOL_DISCOVERY

optional

Allow unauthenticated initialize, notifications/initialized, tools/list, and server/discover only (tool calls still require auth)

MCP_SERVER_URL / MCP_ALLOWED_HOSTS / MCP_ALLOWED_ORIGINS

optional

Allowed public /mcp host/origin values for DNS rebinding protection

MCP_TRUST_PROXY

optional

Trust Forwarded / X-Forwarded-* headers behind a reverse proxy (download URLs, Express req.ip, /mcp IP rate limits, OAuth rate limits)

GITLAB_ALLOW_UNAUTHENTICATED_TOOL_DISCOVERY=true is intended for MCP gateways or admin UIs that need to inspect tool metadata before a user provides a GitLab token. Leave it disabled unless the tool list is safe to expose in your deployment.

When MCP_SERVER_URL is not set, remote download URLs fall back to the local server address. Set MCP_TRUST_PROXY=true only if the server is reachable through a trusted reverse proxy and direct client access to the MCP server is blocked. This enables Express trust proxy for Streamable HTTP and SSE, derives public download URLs from Forwarded / X-Forwarded-Proto / X-Forwarded-Host / X-Forwarded-Prefix, and keeps OAuth endpoint rate limiting working when proxies send X-Forwarded-For with a client port (for example 1.2.3.4:5678). Existing OAuth+proxy deployments must set this explicitly after the flag was introduced.

Example request headers:

Private-Token: glpat-xxxxxxxxxxxxxxxxxxxx

or using a Bearer token:

Authorization: Bearer glpat-xxxxxxxxxxxxxxxxxxxx

⚠️ REMOTE_AUTHORIZATION is not compatible with SSE transport. STREAMABLE_HTTP=true is required.

Environment Variables

Use the dedicated reference for the full environment variable list:

Most users only need one of these starting sets:

  • Local PAT: GITLAB_PERSONAL_ACCESS_TOKEN, GITLAB_API_URL

  • Local OAuth: GITLAB_USE_OAUTH=true, GITLAB_OAUTH_CLIENT_ID, GITLAB_OAUTH_REDIRECT_URI, GITLAB_API_URL

  • Remote multi-user HTTP: STREAMABLE_HTTP=true, REMOTE_AUTHORIZATION=true (or GITLAB_MCP_OAUTH=true), MCP_TRUST_PROXY=true (behind a reverse proxy), MAX_REQUESTS_PER_MINUTE=300, MCP_SERVER_URL or MCP_ALLOWED_HOSTS, HOST, PORT

  • Multiple side-by-side deployments: set a distinct MCP_SERVER_NAME per instance (e.g. gitlab-selfhosted-readonly) so clients, logs, and telemetry can tell them apart

  • Multi-pod HPA (stateless): above + OAUTH_STATELESS_MODE=true, OAUTH_STATELESS_SECRET (same across all pods). See Stateless Mode.

Commonly referenced variables:

  • GITLAB_API_URL

  • GITLAB_PERSONAL_ACCESS_TOKEN

  • GITLAB_USE_OAUTH

  • REMOTE_AUTHORIZATION

  • MCP_TRUST_PROXY

  • MAX_REQUESTS_PER_MINUTE

  • MAX_SESSIONS

  • MCP_ALLOWED_HOSTS

  • MCP_ALLOWED_ORIGINS

  • GITLAB_MCP_OAUTH

  • GITLAB_OAUTH_CALLBACK_PROXY

  • GITLAB_OAUTH_ALLOWED_REDIRECT_URIS

  • OAUTH_REGISTER_RATE_LIMIT_PER_HOUR

  • OAUTH_DISABLE_REFRESH_TOKEN

  • OAUTH_STATELESS_MODE

  • OAUTH_STATELESS_SECRET

The reference document also covers:

  • auth and OAuth variables

  • MCP OAuth proxy variables

  • project and tool filtering variables

  • dynamic tool discovery via discover_tools (on-demand toolset activation)

  • transport and session variables

  • proxy and TLS variables

For callback proxy mode details, see GitLab MCP OAuth Callback Proxy.

SSE session limits

GET /sse is subject to the same remote-transport controls as Streamable HTTP:

  • Capacity: at most MAX_SESSIONS concurrent SSE sessions (default 1000); further connections get 503.

  • Creation rate limit: new connections are limited to MAX_REQUESTS_PER_MINUTE per client IP (default 60); excess connections get 429.

  • Idle timeout: a session that receives no POST /messages request for SESSION_TIMEOUT_SECONDS (default 1 hour) is closed, so an idle client must reconnect instead of holding a capacity slot. Unlike Streamable HTTP, holding the SSE stream open does not count as activity.

  • /health returns 503 with status: "degraded" while the instance is at capacity.

Tune these with MAX_SESSIONS, MAX_REQUESTS_PER_MINUTE, and SESSION_TIMEOUT_SECONDS.

Streamable HTTP session timeout

Streamable HTTP sessions use the same SESSION_TIMEOUT_SECONDS idle timeout in every mode, including a server-side token without REMOTE_AUTHORIZATION or GITLAB_MCP_OAUTH: a session with no POST /mcp request for that long is closed, and its next request gets 404 so the client re-initializes. An open GET /mcp stream pauses the timer until the stream closes or the next POST /mcp arrives, so a client with a stream open still expires SESSION_TIMEOUT_SECONDS after its last POST.

Remote Authorization Setup (Multi-User Support)

When using REMOTE_AUTHORIZATION=true, the MCP server can support multiple users, each with their own GitLab token passed via HTTP headers. This is useful for:

  • Shared MCP server instances where each user needs their own GitLab access

  • IDE integrations that can inject user-specific tokens into MCP requests

Setup Example:

# Start server with remote authorization
docker run -d \
  -e HOST=0.0.0.0 \
  -e STREAMABLE_HTTP=true \
  -e REMOTE_AUTHORIZATION=true \
  -e GITLAB_API_URL="https://gitlab.com/api/v4" \
  -e GITLAB_PERMISSION_MODE=readonly \
  -e SESSION_TIMEOUT_SECONDS=3600 \
  -p 3333:3002 \
  zereight050/gitlab-mcp

Client Configuration:

Your IDE or MCP client must send one of these headers with each request:

Authorization: Bearer glpat-xxxxxxxxxxxxxxxxxxxx

or

Private-Token: glpat-xxxxxxxxxxxxxxxxxxxx

The token is stored per session (identified by mcp-session-id header) and reused for subsequent requests in the same session. The session belongs to the GitLab user of that token: a request with another user's token gets 404 Session not found, and GET / DELETE /mcp without a token get 401.

Remote Authorization Client Configuration Example with Cursor

{
  "mcpServers": {
    "GitLab": {
      "url": "http(s)://<your_mcp_gitlab_server>/mcp",
      "headers": {
        "Authorization": "Bearer glpat-..."
      }
    }
  }
}

Important Notes:

  • Remote authorization only works with Streamable HTTP transport

  • Each session is isolated - tokens from one session cannot access another session's data Tokens are automatically cleaned up when sessions close

  • Session timeout: Auth tokens expire after SESSION_TIMEOUT_SECONDS (default 1 hour) of inactivity. After timeout the session is closed and its next request gets 404, so the client re-initializes with its auth headers.

  • Each request resets the timeout timer for that session

  • Rate limiting: /mcp requests are limited to MAX_REQUESTS_PER_MINUTE per client IP, and per MCP session when using OAuth or remote authorization (default 60). The per-IP limit uses a fixed 60-second window, counts per server process, and also covers GET /mcp; stateless mode skips the per-session limit. See environment-variables.md.

  • Capacity limit: Server accepts up to MAX_SESSIONS concurrent sessions (default 1000)

MCP OAuth Setup (Claude.ai Native OAuth)

When using GITLAB_MCP_OAUTH=true, the server acts as an OAuth proxy to your GitLab instance. Claude.ai (and any MCP-spec-compliant client) handles the entire browser authentication flow automatically — no manual Personal Access Token management needed.

Prerequisites:

A pre-registered GitLab OAuth application is required. GitLab restricts dynamically registered (unverified) applications to the mcp scope, which is insufficient for API calls (need api or read_api).

  1. Go to your GitLab instance → Admin Area > Applications (instance-wide) or User Settings > Applications (personal)

  2. Create a new application with:

    • Confidential: unchecked

    • Scopes: api, read_api, read_user (or whichever scopes you intend to request via GITLAB_OAUTH_SCOPES)

  3. Save and copy the Application ID — this is your GITLAB_OAUTH_APP_ID

How it works:

  1. User adds your MCP server URL in Claude.ai

  2. Claude.ai discovers OAuth endpoints via /.well-known/oauth-authorization-server

  3. Claude.ai registers itself via Dynamic Client Registration (POST /register) — handled locally by the MCP server (each client gets a virtual client ID)

  4. Claude.ai redirects the user's browser to GitLab's login page using the pre-registered OAuth application

  5. User authenticates; GitLab redirects back to https://claude.ai/api/mcp/auth_callback

  6. Claude.ai sends Authorization: Bearer <token> on every MCP request

  7. Server validates the token with GitLab and stores it per session

Server setup:

docker run -d \
  -e STREAMABLE_HTTP=true \
  -e GITLAB_MCP_OAUTH=true \
  -e GITLAB_OAUTH_APP_ID="your-gitlab-oauth-app-client-id" \
  -e GITLAB_API_URL="https://gitlab.example.com/api/v4" \
  -e MCP_SERVER_URL="https://your-mcp-server.example.com" \
  -p 3002:3002 \
  zereight050/gitlab-mcp

For local development (HTTP allowed):

MCP_DANGEROUSLY_ALLOW_INSECURE_ISSUER_URL=true \
STREAMABLE_HTTP=true \
GITLAB_MCP_OAUTH=true \
GITLAB_OAUTH_APP_ID=your-gitlab-oauth-app-client-id \
MCP_SERVER_URL=http://localhost:3002 \
GITLAB_API_URL=https://gitlab.com/api/v4 \
node build/index.js

Claude.ai configuration:

{
  "mcpServers": {
    "GitLab": {
      "url": "https://your-mcp-server.example.com/mcp"
    }
  }
}

No headers field is needed — Claude.ai obtains the token via OAuth automatically.

Environment variables:

Variable

Required

Description

GITLAB_MCP_OAUTH

Yes

Set to true to enable

GITLAB_OAUTH_APP_ID

Yes

Client ID of the pre-registered GitLab OAuth application

MCP_SERVER_URL

Yes

Public HTTPS URL of your MCP server; also allowed for /mcp Host/Origin checks

GITLAB_API_URL

Yes

Your GitLab instance API URL (e.g. https://gitlab.com/api/v4). Do not embed credentials (user:pass@) in the URL; they are ignored. A comma in a password must be written as %2C.

STREAMABLE_HTTP

Yes

Must be true (SSE is not supported)

GITLAB_OAUTH_SCOPES

No

Comma-separated GitLab scopes to request (e.g. api,read_user). Defaults to api (or read_api when the effective permission mode is readonly). The pre-registered application must be configured with at least these scopes.

OAUTH_REGISTER_RATE_LIMIT_PER_HOUR

No

Per-IP limit (fixed 1-hour window) for Dynamic Client Registration (POST /register). Default 20/hour; range 1–1000. Raise when clients (e.g. multiple IDE windows) hit registration throttling. Not a GitLab API limit.

OAUTH_DISABLE_REFRESH_TOKEN

No

Set true to drop refresh_token from /token responses and reject the refresh grant with invalid_grant, so users re-authorize in the browser when the GitLab access token expires. Default false. In callback proxy mode, MCP clients that follow this server's flow never receive a GitLab refresh token (in passthrough the client can get one from GitLab directly). This is a re-authorization policy for standard MCP clients, not a security boundary. Refresh tokens issued before enabling stay valid until revoked in GitLab under User Settings → Applications → Authorized applications → Revoke.

MCP_DANGEROUSLY_ALLOW_INSECURE_ISSUER_URL

No

Set true for local HTTP dev only

Important Notes:

  • MCP OAuth only works with Streamable HTTP transport (SSE=true is incompatible)

  • Each user session stores its own OAuth token — sessions are fully isolated

  • Session timeout, rate limiting, and capacity limits apply identically to the REMOTE_AUTHORIZATION mode (SESSION_TIMEOUT_SECONDS, MAX_REQUESTS_PER_MINUTE, MAX_SESSIONS)

  • DCR rate limiting: POST /register is limited to OAUTH_REGISTER_RATE_LIMIT_PER_HOUR per client IP (default 20/hour). Separate from /mcp limits and GitLab API quotas. See environment-variables.md.

  • Header auth fallback: when Private-Token or JOB-TOKEN request headers are present, OAuth validation is skipped and the raw token is used directly for that session. This allows PATs and CI job tokens to be used alongside the OAuth flow on the same server instance. Authorization: Bearer is always treated as an OAuth token — use Private-Token for PAT-based header auth.

Agent Skill Files

Skill + CLI is an equal path to MCP (see Skill + CLI). Pre-built skill files are available in skills/gitlab-mcp/ for AI agents that support skill/instruction loading (Claude Code, GitHub Copilot, Cursor, etc.).

  • SKILL.md — Core guide (~800 tokens) with toolset overview, key workflows, and parameter hints

  • reference/ — Detailed workflow docs for code review, merge requests, issues, pipelines, and vulnerability triage

Install with the skills CLI:

npx skills add zereight/gitlab-mcp --skill gitlab-mcp-skill

Register the skill directory in your AI client to get optimal tool usage guidance without relying solely on the full ListTools response.

Tools 🛠️

  1. merge_merge_request - Merge a merge request

  2. approve_merge_request - Approve a merge request

  3. unapprove_merge_request - Unapprove a merge request

  4. get_merge_request_approval_state - Get merge request approval details including approvers

  5. get_merge_request_conflicts - Get the conflicts of a merge request

  6. list_merge_request_pipelines - List pipelines for a merge request with pagination

  7. execute_graphql - Execute a GitLab GraphQL query

  8. create_or_update_file - Create or update a file in a GitLab project

  9. search_repositories - Search for GitLab projects

  10. create_repository - Create a new GitLab project

  11. create_group - Create new group or subgroup

  12. get_file_contents - Get contents of a file or directory from a GitLab project

  13. push_files - Push multiple files in a single commit

  14. create_issue - Create a new issue

  15. create_merge_request - Create a new merge request

  16. fork_repository - Fork a project to your account or specified namespace

  17. create_branch - Create a new branch

  18. get_branch - Get branch details (commit, protection status)

  19. list_branches - List branches in project with search filter

  20. delete_branch - Delete branch from project

  21. list_protected_branches - List protected branches in a project, supports search filter

  22. get_protected_branch - Get details of a single protected branch (access levels, force push settings)

  23. protect_branch - Protect a repository branch (set push/merge/unprotect access levels)

  24. update_protected_branch - Update an existing protected branch rule in place (access levels, force push, code owner approval)

  25. unprotect_branch - Remove protection from a previously protected branch

  26. update_default_branch - Change the default branch of a project

  27. get_merge_request - Get details of a merge request (merge_request_iid or source_branch required). Set include_summaries=true for deployment/commit/approval summaries

  28. get_merge_request_diffs - Get the changes/diffs of a merge request (merge_request_iid or source_branch required)

  29. list_merge_request_changed_files - List changed file paths in a merge request without diff content (merge_request_iid or source_branch required)

  30. list_merge_request_diffs - List merge request diffs with pagination (merge_request_iid or source_branch required)

  31. get_merge_request_file_diff - Get diffs for specific files from a merge request (merge_request_iid or source_branch required)

  32. list_merge_request_versions - List all versions of a merge request

  33. get_merge_request_version - Get a specific version of a merge request

  34. get_branch_diffs - Get diffs between two branches or commits

  35. update_merge_request - Update a merge request (merge_request_iid or source_branch required)

  36. create_note - Create a new note (comment) to an issue or merge request

  37. create_merge_request_thread - Create a new thread on a merge request

  38. resolve_merge_request_thread - Resolve a thread on a merge request

  39. mr_discussions - List discussion items for a merge request

  40. get_merge_request_discussion - Get a single discussion item for a merge request

  41. delete_merge_request_discussion_note - Delete a discussion note on a merge request

  42. update_merge_request_discussion_note - Update a discussion note on a merge request

  43. create_merge_request_discussion_note - Add a new discussion note to an existing merge request thread

  44. create_merge_request_note - Add a new note to a merge request

  45. delete_merge_request_note - Delete an existing merge request note

  46. get_merge_request_note - Get a specific note for a merge request

  47. get_merge_request_notes - List notes for a merge request

  48. update_merge_request_note - Modify an existing merge request note

  49. get_draft_note - Get a single draft note from a merge request

  50. list_draft_notes - List draft notes for a merge request

  51. create_draft_note - Create a draft note for a merge request

  52. update_draft_note - Update an existing draft note

  53. delete_draft_note - Delete a draft note

  54. publish_draft_note - Publish a single draft note

  55. bulk_publish_draft_notes - Publish all draft notes for a merge request. Optionally sets reviewer_state and posts a summary note (GitLab 19.2+). Can set reviewer_state even with no drafts.

  56. list_merge_request_emoji_reactions - List all emoji reactions on a merge request

  57. list_merge_request_note_emoji_reactions - List all emoji reactions on a merge request note. Pass discussion_id for discussion thread replies.

  58. create_merge_request_emoji_reaction - Add an emoji reaction to a merge request (e.g. thumbsup, rocket, eyes)

  59. delete_merge_request_emoji_reaction - Remove an emoji reaction from a merge request

  60. create_merge_request_note_emoji_reaction - Add an emoji reaction to a merge request note. Pass discussion_id for discussion thread replies.

  61. delete_merge_request_note_emoji_reaction - Remove an emoji reaction from a merge request note. Pass discussion_id for discussion thread replies.

  62. update_issue_note - Modify an existing issue thread note

  63. create_issue_note - Add a note to an issue, optionally replying to a discussion thread

  64. list_issue_emoji_reactions - List all emoji reactions on an issue

  65. list_issue_note_emoji_reactions - List all emoji reactions on an issue note. Pass discussion_id for discussion thread replies.

  66. create_issue_emoji_reaction - Add an emoji reaction to an issue (e.g. thumbsup, rocket, eyes)

  67. delete_issue_emoji_reaction - Remove an emoji reaction from an issue

  68. create_issue_note_emoji_reaction - Add an emoji reaction to an issue note. Pass discussion_id for discussion thread replies.

  69. delete_issue_note_emoji_reaction - Remove an emoji reaction from an issue note. Pass discussion_id for discussion thread replies.

  70. list_issues - List issues (default: created by current user; use scope='all' for all)

  71. my_issues - List issues assigned to the authenticated user

  72. get_issue - Get one issue. Slim nested milestone by default; full_response=true for the complete milestone

  73. update_issue - Update an issue. Slim confirmation by default; full_response=true for the complete object

  74. update_issue_description_patch - Patch an issue description (search/replace or unified diff) without resending the full body. dry_run previews; create_note summarizes

  75. reorder_issue - Move an issue within the manual sort order shown on issue boards. move_after_id and move_before_id take the neighbor issue's global id (the id field), not its iid; pass at least one. Returns the reordered issue.

  76. delete_issue - Delete an issue

  77. list_todos - List GitLab to-do items for the current user

  78. mark_todo_done - Mark a GitLab to-do item as done

  79. mark_all_todos_done - Mark all pending GitLab to-do items as done for the current user

  80. list_issue_links - List all issue links for a specific issue

  81. list_issue_discussions - List discussions for an issue

  82. get_issue_link - Get a specific issue link

  83. create_issue_link - Create an issue link between two issues

  84. delete_issue_link - Delete an issue link

  85. list_namespaces - List all namespaces (users and groups) available to the current user. Filter by kind='group' for groups only.

  86. get_namespace - Get details of a namespace (user or group) by ID or path. Groups are namespaces with kind='group'.

  87. verify_namespace - Verify if a namespace path exists. Use parent_id to scope the check to a specific parent namespace — required for nested namespaces where the same path may exist under different parents.

  88. get_project - Get details of a specific project

  89. list_projects - List projects accessible by the current user

  90. update_project - Update project settings such as description, visibility, default branch, and feature access levels

  91. list_project_members - List members of a GitLab project

  92. list_group_members - List members of a GitLab group with optional name or username search

  93. list_labels - List labels for a project

  94. get_label - Get a single label from a project

  95. create_label - Create a new label in a project

  96. update_label - Update an existing label in a project

  97. delete_label - Delete a label from a project

  98. list_group_projects - List projects in a group

  99. list_wiki_pages - List wiki pages in a project

  100. get_wiki_page - Get details of a specific wiki page

  101. create_wiki_page - Create a wiki page in a project

  102. update_wiki_page - Update a wiki page in a project

  103. delete_wiki_page - Delete a wiki page from a project

  104. list_group_wiki_pages - List wiki pages in a group

  105. get_group_wiki_page - Get details of a specific group wiki page

  106. create_group_wiki_page - Create a wiki page in a group

  107. update_group_wiki_page - Update a wiki page in a group

  108. delete_group_wiki_page - Delete a wiki page from a group

  109. get_repository_tree - List files and directories in a repository

  110. list_pipelines - List pipelines with filtering options

  111. get_pipeline - Get details of a specific pipeline

  112. get_pipeline_variables - Get variables configured for a pipeline

  113. get_pipeline_test_report - Get pipeline test report

  114. get_pipeline_test_report_summary - Get pipeline test report summary

  115. delete_pipeline - Delete a pipeline. Requires the project Owner role, cannot be undone, and does not automatically delete child pipelines.

  116. update_pipeline_metadata - Update pipeline metadata

  117. list_deployments - List deployments with filtering options

  118. get_deployment - Get deployment details, including approval_summary, approvals, and pending_approval_count when GitLab provides them

  119. create_deployment - Create a deployment

  120. update_deployment - Update a deployment status

  121. delete_deployment - Delete a deployment

  122. list_deployment_merge_requests - List merge requests shipped with a deployment

  123. approve_deployment - Approve or reject a protected-environment deployment

  124. list_environments - List environments in a project

  125. get_environment - Get details of a specific environment

  126. update_environment - Update an environment

  127. delete_environment - Delete a stopped environment

  128. stop_environment - Stop an environment

  129. stop_stale_environments - Stop eligible stale environments; protected environments are excluded and environments are stopped, not deleted

  130. delete_review_app_environments - Schedule deletion of stopped review-app environments one week later; dry_run defaults to true and actual scheduling requires dry_run=false

  131. list_pipeline_triggers - List project pipeline trigger tokens

  132. get_pipeline_trigger - Get a project pipeline trigger

  133. create_pipeline_trigger - Create a project pipeline trigger

  134. update_pipeline_trigger - Update a project pipeline trigger

  135. delete_pipeline_trigger - Delete a project pipeline trigger

  136. trigger_pipeline - Trigger a pipeline with a pipeline trigger token

  137. list_pipeline_jobs - List all jobs in a specific pipeline

  138. list_pipeline_trigger_jobs - List trigger jobs (bridges) in a pipeline

  139. get_pipeline_job - Get details of a GitLab pipeline job number

  140. get_pipeline_job_output - Get a pipeline job trace, with end-based pagination or full-log substring/regex search

  141. validate_ci_lint - Validate provided GitLab CI/CD YAML content for a project

  142. validate_project_ci_lint - Validate an existing .gitlab-ci.yml configuration for a project

  143. list_ci_catalog_resources - List GitLab CI/CD Catalog resources/components visible to the user

  144. get_ci_catalog_resource - Get details for a GitLab CI/CD Catalog resource, including versions and components

  145. create_pipeline - Create a new pipeline for a branch or tag

  146. retry_pipeline - Retry a failed or canceled pipeline

  147. cancel_pipeline - Cancel a running pipeline

  148. list_pipeline_schedules - List pipeline schedules in a project, optionally filtered to active or inactive

  149. get_pipeline_schedule - Get details of a specific pipeline schedule, including its variables and last pipeline

  150. list_pipeline_schedule_pipelines - List the pipelines that a pipeline schedule has triggered

  151. create_pipeline_schedule - Create a new pipeline schedule for a branch or tag

  152. update_pipeline_schedule - Update an existing pipeline schedule

  153. delete_pipeline_schedule - Delete a pipeline schedule

  154. play_pipeline_schedule - Run a pipeline schedule immediately

  155. take_ownership_pipeline_schedule - Take ownership of a pipeline schedule

  156. get_pipeline_schedule_variable - Get a single variable of a pipeline schedule

  157. create_pipeline_schedule_variable - Create a variable for a pipeline schedule

  158. update_pipeline_schedule_variable - Update a variable of a pipeline schedule

  159. delete_pipeline_schedule_variable - Delete a variable from a pipeline schedule

  160. play_pipeline_job - Run a manual pipeline job

  161. play_pipeline_jobs - Play multiple manual pipeline jobs sequentially

  162. retry_pipeline_job - Retry a failed or canceled pipeline job

  163. cancel_pipeline_job - Cancel a running pipeline job

  164. erase_pipeline_job - Erase a pipeline job log and artifacts

  165. wait_for_pipeline - Wait for a pipeline to reach a terminal status

  166. wait_for_job - Wait for a job to reach a terminal status

  167. list_job_artifacts - List artifact files in a job's archive

  168. download_job_artifacts - Download job artifact archive (zip) and save it under the download directory

  169. get_job_artifact_file - Get content of a single file from a job's artifacts

  170. list_merge_requests - List merge requests (without project_id: user's MRs; with project_id: project MRs)

  171. list_group_merge_requests - List merge requests across all projects of a group and its subgroups

  172. list_milestones - List milestones with filtering options

  173. get_milestone - Get details of a specific milestone

  174. create_milestone - Create a new milestone

  175. edit_milestone - Edit an existing milestone

  176. delete_milestone - Delete a milestone

  177. get_milestone_issue - Get issues associated with a specific milestone

  178. get_milestone_merge_requests - Get merge requests associated with a specific milestone

  179. promote_milestone - Promote a milestone to the next stage

  180. get_milestone_burndown_events - Get burndown events for a specific milestone

  181. list_group_milestones - List group milestones with filtering options

  182. get_group_milestone - Get details of a specific group milestone

  183. create_group_milestone - Create a new group milestone

  184. edit_group_milestone - Edit an existing group milestone

  185. delete_group_milestone - Delete a group milestone

  186. get_group_milestone_issue - Get issues associated with a specific group milestone

  187. get_group_milestone_merge_requests - Get merge requests associated with a specific group milestone

  188. get_group_milestone_burndown_events - Get burndown events for a specific group milestone

  189. get_users - Get GitLab user details by usernames

  190. get_user - Get user details by ID

  191. whoami - Get current authenticated user details

  192. list_commits - List repository commits with filtering options

  193. get_commit - Get details of a specific commit

  194. get_commit_diff - Get changes/diffs of a specific commit

  195. get_file_blame - Get git blame for a file at a given ref. Each entry maps a contiguous range of source lines to the commit that last changed them (id, author, authored_date, message). Use range_start/range_end to limit blame to specific lines.

  196. list_commit_statuses - List statuses for a commit

  197. create_commit_status - Create or update the status of a commit

  198. list_group_iterations - List group iterations with filtering options

  199. get_group_iteration - Get a group iteration by ID, IID, or GraphQL GID

  200. update_group_iteration - Update a manual group iteration's title, description, or dates

  201. create_group_iteration - Create a group iteration, optionally in a given iteration cadence

  202. delete_group_iteration - Delete a group iteration by ID, IID, or GraphQL GID

  203. list_project_iterations - List the iterations available to a project with filtering options

  204. list_group_iteration_cadences - List a group's iteration cadences with filtering options

  205. create_group_iteration_cadence - Create an iteration cadence in a group

  206. update_group_iteration_cadence - Update an iteration cadence's title, description, schedule, or automation

  207. delete_group_iteration_cadence - Delete an iteration cadence

  208. upload_markdown - Upload a file for use in markdown content

  209. download_attachment - Download an uploaded file from a project (images returned as base64; other files, or images with local_path, are saved as new files under the download directory)

  210. health_check - Check auth and versions. Always includes mcp_server_version. When authenticated, also GitLab version, revision, and enterprise from GET /api/v4/version. Version lookup failures omit those fields instead of failing

  211. list_events - List events for the authenticated user (before/after: YYYY-MM-DD)

  212. get_project_events - List events for a project (before/after: YYYY-MM-DD)

  213. list_releases - List all releases for a project

  214. get_release - Get a release by tag name

  215. create_release - Create a new release

  216. update_release - Update an existing release

  217. delete_release - Delete a release (does not delete the tag)

  218. create_release_evidence - Create release evidence (Premium/Ultimate)

  219. download_release_asset - Download a release asset file by direct asset path

  220. list_tags - List repository tags for a project

  221. get_tag - Get a repository tag by name

  222. create_tag - Create a new repository tag

  223. delete_tag - Delete a repository tag

  224. get_tag_signature - Get the X.509 signature of a signed tag (404 if unsigned)

  225. list_protected_tags - List protected tags in a project

  226. get_protected_tag - Get details of a single protected tag or wildcard (create access levels)

  227. protect_tag - Protect a repository tag or wildcard (set who can create it)

  228. unprotect_tag - Remove protection from a previously protected tag or wildcard

  229. get_work_item - Get a work item with full details including status, hierarchy, type, and widgets

  230. list_work_items - List work items with filters (type, state, search, assignees, labels)

  231. create_work_item - Create a work item (issue, task, incident, epic, etc.) with full field support

  232. update_work_item - Update a work item (title, description, labels, assignees, state, parent, custom fields, etc.)

  233. convert_work_item_type - Convert a work item to a different type

  234. list_work_item_statuses - List available statuses for a work item type (Premium/Ultimate)

  235. list_custom_field_definitions - List custom field definitions for a work item type

  236. move_work_item - Move a work item to a different project

  237. list_work_item_notes - List notes and discussions on a work item

  238. create_work_item_note - Add a note to a work item (supports Markdown, internal notes, threads)

  239. list_work_item_emoji_reactions - List all emoji reactions on a work item

  240. list_work_item_note_emoji_reactions - List all emoji reactions on a work item note (comment, thread, or thread reply)

  241. create_work_item_emoji_reaction - Add an emoji reaction to a work item (e.g. thumbsup, rocket, eyes)

  242. delete_work_item_emoji_reaction - Remove an emoji reaction from a work item

  243. create_work_item_note_emoji_reaction - Add an emoji reaction to a work item note (comment, thread, or thread reply)

  244. delete_work_item_note_emoji_reaction - Remove an emoji reaction from a work item note (comment, thread, or thread reply)

  245. get_timeline_events - List timeline events for an incident

  246. create_timeline_event - Create a timeline event on an incident

  247. list_webhooks - List webhooks for a project or group

  248. create_webhook - Create a webhook on a project or group

  249. update_webhook - Update an existing project or group webhook

  250. delete_webhook - Delete a project or group webhook

  251. list_webhook_events - List recent webhook events (past 7 days)

  252. get_webhook_event - Get full details of a specific webhook event

  253. search_code - Search for code across all projects (requires advanced search or Zoekt)

  254. search_project_code - Search for code within a specific project (requires advanced search or Zoekt)

  255. search_group_code - Search for code within a specific group (requires advanced search or Zoekt)

  256. list_project_variables - List CI/CD variables for a project

  257. get_project_variable - Get a single CI/CD variable from a project

  258. create_project_variable - Create a CI/CD variable for a project

  259. update_project_variable - Update an existing CI/CD variable in a project

  260. delete_project_variable - Delete a CI/CD variable from a project

  261. list_group_variables - List CI/CD variables for a group

  262. get_group_variable - Get a single CI/CD variable from a group

  263. create_group_variable - Create a CI/CD variable for a group

  264. update_group_variable - Update an existing CI/CD variable in a group

  265. delete_group_variable - Delete a CI/CD variable from a group

  266. get_dependency_proxy_settings - Get dependency proxy settings for a group

  267. update_dependency_proxy_settings - Update dependency proxy settings for a group (enable/disable, credentials for authenticated Docker Hub pulls)

  268. list_dependency_proxy_blobs - List cached dependency proxy blobs for a group

  269. purge_dependency_proxy_cache - Schedule purge of all cached dependency proxy blobs for a group

  270. list_project_vulnerabilities - List vulnerabilities for a project with optional state, severity, and report type filters (GraphQL-backed, cursor pagination)

  271. get_vulnerability - Get full details of a specific vulnerability

  272. dismiss_vulnerability - Dismiss a vulnerability with a reason (acceptable_risk, false_positive, used_in_tests, mitigating_control, not_applicable) and optional comment

  273. confirm_vulnerability - Confirm a vulnerability as a real finding requiring remediation

  274. orbit_query - Execute a GitLab Orbit graph query over the indexed SDLC knowledge graph

  275. orbit_get_schema - Fetch the current GitLab Orbit graph schema (node and edge types)

  276. orbit_get_status - Check GitLab Orbit indexing status for the enabled scope

  277. orbit_list_tools - List the MCP tool definitions exposed by GitLab Orbit

  278. list_snippets - List snippets — project snippets when project_id is given, otherwise personal snippets

  279. get_snippet - Get a snippet's metadata. Set include_content=true to also fetch the raw file content.

  280. create_snippet - Create a snippet — project-scoped when project_id is given, otherwise a personal snippet. Requires title plus either file_name + content (single file) or files[] (multi-file); the two shapes cannot be mixed.

  281. update_snippet - Update an existing snippet (provide at least one field to change). For multi-file edits — renames, deletions, additions — pass files[] with action (create/update/delete/move) and previous_path. The file_name + content shortcut still works for single-file content replacement.

  282. delete_snippet - Delete a snippet

  283. list_project_runners - List runners available to a project (type, status, paused, tag_list). Omits registration and authentication tokens.

  284. get_runner - Get a runner's tag_list, run_untagged, locked, and access_level. When a project allowlist is active, the runner must be available to an allowed project. Omits registration and authentication tokens.

  285. rebase_merge_request - Rebase the source branch of a merge request onto its target branch

  286. gitlab_api_request - Send one GitLab REST call under /api/v4. Enabled only when GITLAB_TOOLSETS lists api. Readonly allows GET; modify rejects DELETE.

  287. discover_tools - List or activate a toolset for this session. Omit category to list; pass one to enable. Prefer this over GITLAB_TOOLSETS=all (loads ~all schemas). Session-only; with OAUTH_STATELESS_MODE=true persist GITLAB_TOOLSETS.

  288. help - Return a short GitLab workflow guide. Omit topic for the overview and topic list.

Wiki page titles vs. slugs

GitLab derives a wiki page's slug (its URL, /-/wikis/<slug>) from the page title. Passing title to update_wiki_page / update_group_wiki_page therefore renames the page and changes its URL — for nested pages it can also move the page to a different path — which breaks existing links.

To change only the displayed title while keeping the URL stable, do not pass title. Instead, store the display title in the page content's YAML front matter and update the content:

---
title: My Custom Display Title
---

Page body…

GitLab keeps the slug/URL untouched and shows the front-matter title in the UI. Read it back with get_wiki_page using render_html: true, which populates the front_matter field — the plain title field always reflects the slug-derived value.

Testing 🧪

The project includes comprehensive test coverage including remote authorization:

# Run all tests (API validation + remote auth)
npm test

# Run only remote authorization tests
npm run test:remote-auth

# Run all tests including readonly MCP tests
npm run test:all

# Run only API validation
npm run test:integration

All remote authorization tests use a mock GitLab server and do not require actual GitLab credentials.

Available Tools

40 tools
create_issueB

Create a new issue. Open a new issue. Use update_issue for an existing issue and create_issue_note for discussion.

NameRequiredDescriptionDefault
titleYesIssue title
labelsNoLabel names
weightNoIssue weight
jmespathNoOptional JMESPath expression filtering the JSON result before return.
issue_typeNoissue, incident, test_case, or taskissue
project_idYesProject ID or complete URL-encoded path to project
descriptionNoIssue description
assignee_idsNoAssignee user IDs
milestone_idNoMilestone ID

TDQS

B3.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The only annotation is openWorldHint=true, so the description carries the burden for a mutation tool. It says nothing about required permissions, whether creation triggers notifications or side effects, what happens on duplicate titles, or what the call returns. Beyond the word 'Create,' no behavior is disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences are useful and one is pure redundancy ('Open a new issue'). The tool-routing sentence is valuable but should lead or merge with the purpose statement to be properly front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Nine parameters, no output schema, and a write operation in an open world – the description gives no information about permission requirements, return payload, or side effects. An agent can call this but cannot predict the consequences or interpret the response from the definition alone.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, including enum values for issue_type and guidance on project_id, so the schema does the heavy lifting. The description adds no meaning about parameters, not even the two required ones or the optional result-filtering jmespath. Baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence states a specific verb+resource ('Create a new issue'). The second sentence, 'Open a new issue,' is a near-verbatim restatement and adds nothing. Sibling differentiation is handled in the third sentence rather than the purpose line itself, so the intent is clear but not tightly front-loaded.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes the agent: use `update_issue` for existing issues and `create_issue_note` for discussion. That covers the most likely mis-selection among siblings. It stops short of stating preconditions (e.g. project must exist, membership required) or when not to create at all.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_issue_noteA

Add a note to an issue, optionally replying to a discussion thread. Add a note to an existing issue, optionally as a reply. Use update_issue for issue fields.

NameRequiredDescriptionDefault
bodyYesThe content of the note or reply
jmespathNoOptional JMESPath expression filtering the JSON result before return.
issue_iidYesThe IID of an issue
created_atNoDate the note was created at (ISO 8601 format)
project_idYesProject ID or complete URL-encoded path to project
discussion_idNoThe ID of a thread. If provided, replies to that thread; otherwise creates a top-level note

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare openWorldHint, so the description carries most of the behavioral burden. It implies a write/append and clarifies the top-level vs threaded-reply outcome, but says nothing about required permissions, whether the note is editable/deletable, rate limits, or idempotency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The first two sentences are near-duplicates ('optionally replying to a discussion thread' vs 'optionally as a reply'), so a third of the text is wasted. The routing sentence is well-placed at the end but the definition could be half its length.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and six parameters, the description leaves return shape, the purpose of created_at and jmespath, and mutation side effects unaddressed. It is adequate for the core invocation but not complete for a create operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents every parameter including discussion_id and jmespath. The description adds only the reply-vs-top-level distinction, which the schema already states, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Add a note to an issue') plus the optional reply mode, and explicitly distinguishes itself from update_issue. It does not, however, differentiate itself from other issue-adjacent siblings like list_issue_discussions or get_issue.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Names the alternative tool (update_issue) and the condition that selects it ('for issue fields'), which is genuine routing guidance. It lacks any statement of prerequisites or when not to add a note, so it falls short of full when/when-not coverage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_merge_requestA

Create a new merge request. Open a merge request from an existing source branch to a target. Use update_merge_request after it exists.

NameRequiredDescriptionDefault
draftNoCreate as draft
titleYesMerge request title
labelsNoMR labels
squashNoSquash commits on merge
jmespathNoOptional JMESPath expression filtering the JSON result before return.
project_idYesProject ID or complete URL-encoded path to project
descriptionNoMerge request description
assignee_idsNoAssignee user IDs
reviewer_idsNoReviewer user IDs
source_branchYesSource branch
target_branchYesTarget branch
target_project_idNoTarget project numeric ID
allow_collaborationNoAllow eligible upstream members to push to the fork source branch
remove_source_branchNoRemove source branch on merge

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The only annotation is openWorldHint=true, so the description carries most of the behavioral burden. It usefully discloses the prerequisite that the source branch must already exist, but says nothing about write-access requirements, draft/squash side effects, cross-project forking, or error behavior when branches are identical or missing.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the action and followed by scope and the lifecycle handoff. No filler and nothing redundant with the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 14-parameter write tool with no output schema, the description covers purpose and lifecycle routing but leaves the agent without any statement about return content, permissions, or the meaning of the riskier options (draft, squash, cross-project). Adequate but thin relative to the tool's complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all 14 parameters including target_project_id, jmespath, and allow_collaboration are already self-documented. The description adds only the source-to-target branch relationship, which the schema fields already convey, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("Create a new merge request") and adds the key topology detail that it runs from an existing source branch to a target. This distinguishes it from read siblings like get_merge_request and list_merge_requests, though it never names which sibling creates the source branch it depends on.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes the agent to `update_merge_request` for post-creation changes, which is a clear when-to-use-which rule. It does not state any when-not conditions, such as preferring an existing MR path or what to do if an MR already exists for the branch pair.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_merge_request_threadA

Create a new thread on a merge request. Start a review thread. Use create_merge_request_note for an unthreaded note and create_merge_request_discussion_note to reply.

NameRequiredDescriptionDefault
bodyYesThe content of the thread
jmespathNoOptional JMESPath expression filtering the JSON result before return.
positionNoPosition when creating a diff note
created_atNoDate the thread was created at (ISO 8601 format)
project_idYesProject ID or complete URL-encoded path to project
merge_request_iidYesThe IID of a merge request

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations only expose `openWorldHint`, so the description carries most of the behavioral burden. It clearly signals a write operation by saying 'Create' and 'Start a review thread', but it does not disclose permission needs, rate limits, reversibility, or how diff-note positioning affects behavior. It is adequate but has clear gaps.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three short sentences, front-loads the primary action, and immediately routes to alternatives. Every sentence contributes to selecting or using the tool, with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The input schema is unusually rich, including detailed guidance for diff positions and multiline comments, so the description does not need to repeat those semantics. It is complete enough for tool selection and routing, though it could mention that supplying `position` creates a diff note rather than a general MR thread.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all six parameters, including the complex nested `position` object. The description adds no parameter-level meaning beyond the high-level distinction between thread, note, and reply, so baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: creating a new thread on a merge request, and explicitly frames it as starting a review thread. It also distinguishes this tool from note-creation and reply alternatives, so an agent can identify its role without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit routing guidance: use this tool for a new thread, `create_merge_request_note` for an unthreaded note, and `create_merge_request_discussion_note` to reply. The alternatives and their conditions are named directly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

discover_toolsA
Read-only

List or activate a toolset for this session. Omit category to list; pass one to enable. Prefer this over GITLAB_TOOLSETS=all (loads ~all schemas). Session-only; with OAUTH_STATELESS_MODE=true persist GITLAB_TOOLSETS=core,<category> instead. Categories: core, merge_requests, issues, repositories, branches, projects, labels, ci, groups, pipelines, milestones, wiki, releases, tags, snippets, users, workitems, webhooks, search, variables, dependency_proxy, vulnerabilities, orbit. Response lists already-active ones. api is explicit-only.

NameRequiredDescriptionDefault
categoryNoToolset to activate (e.g. pipelines, wiki). Omit to list. Prefer a category over GITLAB_TOOLSETS=all. Session-only; persist `GITLAB_TOOLSETS=core,<category>` when OAUTH_STATELESS_MODE=true.
jmespathNoOptional JMESPath expression filtering the JSON result before return.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the bar is lower, yet the description adds real context beyond them: activation is session-scoped and non-persistent, the stateless-mode workaround, and that the response lists already-active toolsets. The one gap is that 'activate a toolset' is a session-state change that sits in mild tension with readOnlyHint=true, and the description never reconciles that — no note that no remote data is modified.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action and the list/enable switch before any caveats, and no sentence is filler — even the long category enumeration is load-bearing since the schema has no enum. It is dense at roughly one paragraph plus a 24-item list, which is near the upper bound of comfortable scanning but justified by the missing enum.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description compensates by describing the return ('Response lists already-active ones'), and it covers the persistence model, the stateless-mode alternative, the preferred alternative to all-schemas loading, and the full valid value set. For a two-parameter session tool, nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so baseline is 3. The description does add genuine value the schema lacks, enumerating all 24 valid category values where the schema only offers two examples ('e.g. pipelines, wiki'), but it adds nothing about the jmespath parameter beyond what the schema already states.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a precise dual-purpose statement: 'List or activate a toolset for this session,' then immediately disambiguates the two modes ('Omit category to list; pass one to enable'). This is clearly distinct from every sibling tool, which performs GitLab domain operations, so an agent can identify this as a tool-discovery/toolset-management utility without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit conditional guidance for both arguments (omit vs pass a category) and names the alternative it should replace: 'Prefer this over GITLAB_TOOLSETS=all (loads ~all schemas).' It also supplies the correct substitute path for stateless deployments ('with OAUTH_STATELESS_MODE=true persist `GITLAB_TOOLSETS=core,<category>` instead') and flags 'api is explicit-only,' leaving little to infer.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_branchA
Read-only

Get branch details (commit, protection status). To find resources, use the matching list or search tool.

NameRequiredDescriptionDefault
jmespathNoOptional JMESPath expression filtering the JSON result before return.
project_idYesProject ID or complete URL-encoded path to project
branch_nameYesName of the branch

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so safety profile is covered by structured data. The description adds that the result contains commit and protection status, which is useful context, but says nothing about permissions, error behavior, or response shape beyond those two fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, no filler, with the core purpose front-loaded before the disambiguation hint. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only single-resource fetch with fully documented parameters and readOnlyHint annotations, the description covers purpose plus partial return content. No output schema exists, so a slightly fuller account of the returned object would help, but it is close to complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so project_id, branch_name, and the jmespath filter are all documented in the schema itself. The description adds no additional parameter meaning, which is the expected baseline when the schema does the work.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ("Get branch details") and enumerates the returned fields (commit, protection status), which distinguishes it from mutation tools like update_merge_request. It does not explicitly name the sibling list_branches, so differentiation is only implied.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The second sentence routes the agent to "the matching list or search tool" when it needs to find resources, which sets a usage boundary. However, it never names list_branches or any concrete alternative, so the routing guidance is generic and requires the agent to infer the sibling.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_commitB
Read-only

Get details of a specific commit. To find resources, use the matching list or search tool.

NameRequiredDescriptionDefault
shaYesThe commit hash or name of a repository branch or tag
statsNoInclude commit stats
jmespathNoOptional JMESPath expression filtering the JSON result before return.
project_idYesProject ID or complete URL-encoded path to project

TDQS

B3.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and openWorldHint, so the safety profile is covered. The description adds nothing beyond that: no mention of what 'details' includes, that stats are optional, that jmespath filters the payload, or any auth/rate-limit context. For a read tool this is thin but not contradictory.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with the core purpose front-loaded and no filler. The second sentence carries mild value as a discovery hint, though it is near-boilerplate.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

A simple read-only tool with no output schema, so the description needn't explain return values. Still, 'details' is underspecified — the agent gets no sense of what fields come back or how stats/jmespath change the result, which would matter for constructing follow-up calls.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the parameters are fully documented in the schema itself (sha as hash/branch/tag, stats toggle, jmespath filter). The description contributes no additional parameter meaning. Baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Get details of a specific commit.' An agent can tell it retrieves a single commit. However, it does not distinguish itself from siblings like get_commit_diff or list_commits, so the agent must infer that this returns commit metadata rather than a diff.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The line 'To find resources, use the matching list or search tool' implies the SHA must be discovered via list_commits first, which is useful. But it is generic boilerplate, gives no explicit when-not-to-use guidance, and never mentions get_commit_diff as the alternative for diff content.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_commit_diffA
Read-only

Get changes/diffs of a specific commit. Return the file diffs for one commit. Use get_commit for metadata without the patch.

NameRequiredDescriptionDefault
shaYesThe commit hash or name of a repository branch or tag
jmespathNoOptional JMESPath expression filtering the JSON result before return.
full_diffNoWhether to return the full diff or only first page (default: false)
project_idYesProject ID or complete URL-encoded path to project

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds that the payload is a patch rather than metadata, but says nothing about diff size, truncation, or that paging is controlled by full_diff — behavior an agent would want to know before fetching a large commit.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences with the core purpose front-loaded and the routing hint last. Slight redundancy between 'Get changes/diffs' and 'Return the file diffs' keeps it from being maximally tight.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only retrieval tool with a fully documented schema and no output schema, this covers purpose, scope, and sibling disambiguation. The only real gap is what a returned diff looks like and whether large diffs are truncated, which is left implicit.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with all four parameters documented including the full_diff paging flag and jmespath. The description adds no parameter-level meaning beyond the schema, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Get changes/diffs of a specific commit') and reinforces it with 'Return the file diffs for one commit.' It explicitly separates itself from the sibling get_commit, so an agent can choose between them without reading schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Names the alternative (get_commit) and the condition that selects it ('metadata without the patch'), which is the exact routing decision an agent faces. It stops short of covering other near-neighbors like get_merge_request_diffs or list_commit_changed_files, so it is clear but not exhaustive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_file_blameA
Read-only

Get git blame for a file at a given ref. Each entry maps a contiguous range of source lines to the commit that last changed them (id, author, authored_date, message). Use range_start/range_end to limit blame to specific lines.

NameRequiredDescriptionDefault
refYesThe name of branch, tag or commit (required by GitLab blame API)
jmespathNoOptional JMESPath expression filtering the JSON result before return.
file_pathYesThe full path of the file to blame, relative to repo root
range_endNoLast line of the blame range (inclusive, 1-based). Both range[start] and range[end] must be set together.
project_idYesProject ID or complete URL-encoded path to project
range_startNoFirst line of the blame range (inclusive, 1-based). Both range[start] and range[end] must be set together.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, so the description does not need to repeat safety semantics. It adds behavior beyond the annotations by explaining the entry structure: contiguous source-line ranges map to the commit with id, author, authored_date, and message. It does not cover pagination or edge cases, but the read-only hint plus output-shape context is meaningful.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two well-structured sentences. The first front-loads the action and resource; the second communicates the return shape and the optional range limitation. Every phrase contributes information, and there is no filler or duplication of schema text.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given there is no output schema, the description supplies the essential return semantics by naming the fields a caller can expect in each entry. The schema covers all parameters, and the read-only annotation covers the safety profile. Missing details such as pagination or behavior on nonexistent refs are minor for a straightforward blame call.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema itself documents all six parameters including range_start, range_end, ref, and file_path. The description adds only a light hint that range_start/range_end limit the blame to specific lines, which is useful but does not materially go beyond the schema. Baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Get git blame for a file at a given ref.' This clearly separates it from read-content tools like get_file_contents and commit-history tools like get_commit-repository. It also states the central output concept (line ranges mapped to commits), removing ambiguity about what GitLab blame returns.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives a clear operational context: run blame at a specific ref dat and optionally constrain the result to a range of lines with range_start/range_end. It does not explicitly name sibling alternatives or say when not to use this tool, but 'git blame' is a distinct enough operation that the usage context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_file_contentsC
Read-only

Get contents of a file or directory from a GitLab project.

NameRequiredDescriptionDefault
refNoBranch/tag/commit to get contents from
pathNoAlias of file_path
jmespathNoOptional JMESPath expression filtering the JSON result before return.
file_pathNoPath to the file or directory. Takes precedence over 'path' when both are provided
project_idNoProject ID or URL-encoded path (optional; falls back to env)

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so safety is covered. The description adds no behavioral context at all: it doesn't say what happens when path points at a directory (listing vs error), what happens if ref is omitted, or whether large files are truncated.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single well-formed sentence with zero filler and the resource front-loaded. It is efficient, though its brevity comes at the cost of the missing usage and behavioral detail noted elsewhere.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The rich schema covers parameters and the annotations cover safety, but with five parameters, no required fields, and no output schema, the description should clarify the file-vs-directory return shape and default ref behavior. As written it is minimally adequate rather than complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all five parameters (including the path/file_path precedence rule and the project_id env fallback) are already documented in the schema. The description contributes nothing parameter-specific, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Get contents of a file or directory') scoped to a GitLab project, which is enough to distinguish it from most siblings like get_file_blame or get_repository_tree. It stops short of explicitly naming how it differs from those adjacent tools, so a 4 rather than a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use or when-not-to-use guidance, and no alternatives are named even though get_file_blame, get_repository_tree, and get_commit_diff all overlap in scope. The agent must infer selection purely from the tool name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_issueA
Read-only

Get one issue. Slim nested milestone by default; full_response=true for the complete milestone. Use this for issue management. Use list_issues or my_issues to discover issues first.

NameRequiredDescriptionDefault
jmespathNoOptional JMESPath expression filtering the JSON result before return.
issue_iidYesIssue IID
project_idYesProject ID or URL-encoded path
full_responseNoIf true, include the complete milestone (including description). Default is slim (id, iid, title, state, web_url).

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and openWorldHint, so safety is covered; the description adds useful behavioral context by disclosing that the milestone is slimmed by default and that full_response=true is needed for the complete object. It does not describe error behavior for a missing issue or permission failures, but the added default-response detail is meaningful beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the core action and the default return shape. The middle sentence ("Use this for issue management") is filler that does not earn its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only single-resource fetch with no output schema, the description covers the action, the default return shape, how to get the full version, and how to find issues first. Nothing critical for calling it correctly is missing, though error/not-found behavior is unstated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and each parameter (including full_response and jmespath) is documented in the schema itself. The description mentions full_response but repeats the schema's own wording rather than adding new semantics, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb+resource ("Get one issue") and immediately states the returned shape (slim nested milestone by default), which separates it from list-oriented siblings. The only weak line is "Use this for issue management," which restates the obvious rather than narrowing scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly routes discovery to `list_issues` or `my_issues` "first," giving the agent a clear alternative and the condition that selects it. It stops short of stating when-not to use this tool (e.g., bulk retrieval) or any prerequisites such as project membership.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_merge_requestA
Read-only

Get details of a merge request (merge_request_iid or source_branch required). Set include_summaries=true for deployment/commit/approval summaries. To find resources, use the matching list or search tool.

NameRequiredDescriptionDefault
jmespathNoOptional JMESPath expression filtering the JSON result before return.
project_idYesProject ID or URL-encoded path
source_branchNoSource branch name
include_summariesNoIf true, include deployment, commit, and approval summaries (extra API calls). Default false.
merge_request_iidNoMerge request IID

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and openWorldHint, so the safety profile is covered. The description adds genuinely new behavioral context: the identifier requirement that the schema does not enforce (only project_id is required) and the fact that include_summaries triggers extra API calls, which signals added latency/cost. It does not cover failure behavior when neither identifier is supplied, but the value added beyond annotations is real.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with purpose, then the identifier constraint, then the optional flag and the discovery alternative. Every sentence carries distinct information with no repetition of the schema or annotations.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only fetch tool with a fully documented 5-parameter schema and no output schema, the description covers purpose, required identifiers, and the cost of summaries. The main remaining gap is that it never sketches what 'details' includes (fields, size of payload) or how the jmespath filter interacts with the result, which matters somewhat given no output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description goes further by stating the cross-parameter constraint (one of merge_request_iid or source_branch must be provided) that the schema's required list does not capture. It also clarifies the practical effect of include_summaries as extra API calls, beyond the schema's 'extra API calls' phrasing. This is meaningful semantics beyond the structured fields.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource ('Get details of a merge request'), which clearly separates it from list_merge_requests and the diff/note/discussion siblings. It does not name a specific sibling it competes with, instead referring generically to 'the matching list or search tool', so it falls short of full sibling differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear usage conditions: an identifier (merge_request_iid or source_branch) is required, and include_summaries=true should be set when deployment/commit/approval summaries are wanted. It also routes agents to the list/search tools for discovery. There is no explicit when-not guidance, but the context is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_merge_request_approval_stateA
Read-only

Get merge request approval details including approvers. Inspect approval rules and approvers before merging. Use approve_merge_request to change approval state.

NameRequiredDescriptionDefault
jmespathNoOptional JMESPath expression filtering the JSON result before return.
project_idYesProject ID or complete URL-encoded path to project
merge_request_iidYesThe IID of the merge request

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds no further behavioral context — no permission requirements, no note on what happens when no approval rules exist, and no indication of the response shape beyond "details including approvers".

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the core verb and result, followed by usage context and the alternative. No filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

A simple three-parameter read tool with full schema coverage and no output schema; the description conveys what comes back (approval rules and approvers) and when to call it. Minor gap: it does not clarify behavior when approvals are disabled or the MR is not in an approvable state.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so project_id, merge_request_iid, and jmespath are all documented in the schema itself. The description adds no parameter-level meaning, which is acceptable at this coverage level but not above baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: retrieves merge request approval details including approvers. It also separates itself from the mutating sibling by naming `approve_merge_request`, so an agent can distinguish read vs write without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"Inspect approval rules and approvers before merging" gives a concrete usage moment, and the final sentence routes state changes to `approve_merge_request`. It stops short of saying when to prefer it over `get_merge_request`, which may also surface related MR data.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_merge_request_diffsB
Read-only

Get the changes/diffs of a merge request (merge_request_iid or source_branch required). To find resources, use the matching list or search tool.

NameRequiredDescriptionDefault
viewNoDiff view type
jmespathNoOptional JMESPath expression filtering the JSON result before return.
project_idYesProject ID or URL-encoded path
source_branchNoSource branch name
merge_request_iidNoMerge request IID
excluded_file_patternsNoArray of regex patterns to exclude files from the diff results. Each pattern is a JavaScript-compatible regular expression that matches file paths to ignore. Examples: ["^vendor/", "^test/mocks/", "\.spec\.ts$", "package-lock\.json"]

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is known. The description adds the useful constraint that one of merge_request_iid or source_branch must be supplied, but says nothing about pagination, diff size limits, or behavior of the excluded_file_patterns filtering.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with the core action and the key required-input condition front-loaded. There is no padding, though the sibling-routing sentence is vague rather than pointed.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and six parameters, the description covers the essential invocation contract but omits the filtering and view options and does not clarify result shape or size. It is adequate but leaves gaps relative to the tool's surface area.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so every parameter including view, jmespath, and excluded_file_patterns is already documented. The description only re-emphasizes the merge_request_iid/source_branch choice, adding marginal meaning beyond the schema, which fits the baseline 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('Get the changes/diffs of a merge request') and clarifies the conditional requirement for merge_request_iid or source_branch. It does not, however, differentiate this tool from close siblings such as list_merge_request_diffs, get_merge_request_changed_files, or get_merge_request_file_diff, so an agent cannot distinguish them from the text alone.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'To find resources, use the matching list or search tool' provides only generic routing advice and implies discovery workflow, but it never names the specific alternative (e.g., list_merge_request_diffs) or says when this tool should be preferred for a single merge request.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_merge_request_discussionA
Read-only

Get a single discussion item for a merge request. Fetch one discussion by id. Use mr_discussions for a collection and get_merge_request_note for a flat note.

NameRequiredDescriptionDefault
jmespathNoOptional JMESPath expression filtering the JSON result before return.
project_idYesProject ID or complete URL-encoded path to project
discussion_idYesThe ID of a thread
merge_request_iidYesThe IID of a merge request

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the read-only, external-facing profile is covered. The description adds nothing about return shape (e.g., whether the thread's notes are included) or how jmespath affects output, so it is only marginally additive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, zero filler, with the core purpose front-loaded before the disambiguation clause. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a fetch-by-id tool with full schema coverage and annotations covering safety, this is nearly complete. The one minor gap is not stating what the returned discussion contains (notes? resolved state?), which the absence of an output schema leaves implicit.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so project_id, merge_request_iid, discussion_id, and jmespath are all documented in the schema. The description mentions 'by id' but adds no syntax or semantic detail beyond the schema, making the baseline 3 appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Get a single discussion item for a merge request') and reinforces the singular scope with 'Fetch one discussion by id.' This clearly distinguishes it from the collection sibling mr_discussions and the flat-note sibling get_merge_request_note.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly names both alternatives and the condition selecting each: 'Use `mr_discussions` for a collection and `get_merge_request_note` for a flat note.' The agent knows exactly when this tool is and is not the right choice.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_merge_request_file_diffA
Read-only

Get diffs for specific files from a merge request (merge_request_iid or source_branch required).

NameRequiredDescriptionDefault
unidiffNoPresent diff in the unified diff format. Default is false.
jmespathNoOptional JMESPath expression filtering the JSON result before return.
file_pathsYesList of file paths to retrieve diffs for (e.g. ['src/api/users.ts', 'src/repo/user.go']). Call list_merge_request_changed_files first to get the full list of changed paths.
project_idYesProject ID or URL-encoded path
source_branchNoSource branch name
merge_request_iidNoMerge request IID

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered and the description need not repeat it. The description adds the either/or MR identifier constraint, but says nothing about diff size limits, truncation, or response shape — relevant gaps for a diff-returning tool with no output schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence that front-loads the action and resource and ends with the key constraint. Nothing is redundant and nothing needs reordering.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a six-parameter, read-only retrieval tool with no output schema, the description covers what it returns at a high level and the identifier constraint. It leaves out practical behavior an agent would want — whether all requested paths are returned in one call, how large diffs are handled, and how this differs from the sibling diff tools.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline would be 3, but the description contributes a genuine cross-parameter constraint: merge_request_iid OR source_branch, neither of which appears in the schema's required list. That is meaning the schema does not enforce on its own.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('Get diffs') plus a narrowing scope ('for specific files from a merge request'), which separates it from the broader list_merge_request_diffs and get_merge_request_diffs siblings. It stops short of naming those alternatives, so the differentiation is inferable rather than explicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The parenthetical '(merge_request_iid or source_branch required)' gives a precondition for calling, which is useful. However, it never says when to prefer this over get_merge_request_diffs or list_merge_request_diffs, nor that the file_paths prerequisite (list_merge_request_changed_files) lives only in the schema, so routing guidance is implied rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_merge_request_noteA
Read-only

Get a specific note for a merge request. Fetch one note by id. Use get_merge_request_notes for a collection and mr_discussions for threads.

NameRequiredDescriptionDefault
note_idYesThe ID of a thread note
jmespathNoOptional JMESPath expression filtering the JSON result before return.
project_idYesProject ID or complete URL-encoded path to project
merge_request_iidYesThe IID of a merge request

TDQS

A4.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds useful clarity that this fetches exactly one note by id, but it does not add behavioral detail such as response shape, permissions, or rate limits beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the core purpose, followed by the specific action and alternatives. There is no redundant or low-value text.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

This is a simple read-only retrieval tool with complete schema documentation and annotations covering safety. The description supplies enough context to invoke it correctly and route between the relevant sibling tools, with no output schema required for a basic get-by-id operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all four parameters are already documented in the schema. The description only reinforces that lookup is by id and does not add syntax, format, or constraint details beyond what the schema provides; baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: get a specific note for a merge request, fetching one note by id. It also distinguishes the tool from collection and thread-oriented siblings, so an agent can identify its singular-note role without inspecting the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly names alternatives: get_merge_request_notes for a collection and mr_discussions for threads. These conditions directly tell the agent when to choose this tool versus its closest siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_merge_request_notesA
Read-only

List notes for a merge request. List flat notes. Use mr_discussions when thread structure and resolution state are required.

NameRequiredDescriptionDefault
pageNoPage number for pagination
sortNoThe sort order of the notes
jmespathNoOptional JMESPath expression filtering the JSON result before return.
order_byNoThe field to sort the notes by
per_pageNoNumber of items per page
project_idYesProject ID or complete URL-encoded path to project
merge_request_iidYesThe IID of a merge request

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish that this is a read-only, open-world operation. The description adds relevant behavioral context by clarifying that returned notes are flat rather than threaded, but it does not mention pagination behavior or any practical limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, with the core purpose and the key exclusion front-loaded. There is no redundant or wasted language.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only list tool with a fully documented schema and annotations, the description is nearly complete. The only minor gap is that it does not describe the return shape or pagination expectations, though the flat-note distinction gives useful context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the input schema already explains all seven parameters. The description adds no parameter-level details beyond the operation itself, which is appropriate baseline behavior when the schema carries the burden.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific operation and resource: listing notes for a merge request. It further distinguishes the result as flat notes and explicitly names the sibling tool to use when thread structure is needed.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives an explicit alternative: use `mr_discussions` when thread structure and resolution state are required. This directly tells the agent when to choose this tool versus a closely related sibling.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_projectB
Read-only

Get details of a specific project. To find resources, use the matching list or search tool.

NameRequiredDescriptionDefault
jmespathNoOptional JMESPath expression filtering the JSON result before return.
project_idYesProject ID or URL-encoded path

TDQS

B3.4/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds no behavioral context beyond that—it does not describe what 'details' includes, permission requirements, or any special handling like URL-encoded paths.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two concise sentences with the core purpose front-loaded. The second sentence adds useful routing context without unnecessary verbosity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter retrieval tool with annotations covering safety, the description is minimally adequate. However, it does not explain what project details are returned or how JMESPath filtering affects the response, leaving some contextual gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so both parameters (project_id and jmespath) are fully documented in the input schema. The description adds no additional meaning beyond what the schema provides, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('Get details of a specific project'), making the tool's purpose clear. It does not fully distinguish itself from sibling retrieval tools like list_projects, but the routing sentence helps clarify its role.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly directs the agent to use a matching list or search tool when trying to find resources, implying this tool is for retrieving a known project. This gives clear usage context, though it does not name a specific sibling or state when not to use this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_repository_treeC
Read-only

List files and directories in a repository.

NameRequiredDescriptionDefault
refNoBranch or tag. Defaults to the default branch.
pageNoOffset page number from 1 (items + next_page)
pathNoPath inside the repository
jmespathNoOptional JMESPath expression filtering the JSON result before return.
per_pageNoItems per page
recursiveNoRecursive tree
page_tokenNoKeyset token from the previous next_page_token
paginationNoUse keyset for large trees (items + next_page_token). Omit both page and pagination for the legacy array (deprecated).
project_idYesProject ID or URL-encoded path

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. Beyond that the description discloses nothing about the behavior that actually matters here: three mutually exclusive pagination modes including a deprecated legacy array, item + next_page_token response shapes, and how recursive affects result size. For a nine-parameter listing tool this is a substantial behavioral gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with zero filler, and the core purpose lands immediately. It is clean, though its brevity is achieved by omission rather than by tight editing of richer content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With nine parameters, no output schema, and a pagination design that includes a deprecated default mode, one sentence is not enough for an agent to call this correctly on large trees. The description should at minimum point at recursive/path scoping and warn against omitting both page and pagination.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so every one of the nine parameters is already documented, which sets the baseline at 3. The description adds no meaning on top — it says nothing about what recursive returns, what path scoping does, or the three-way pagination choice (keyset, page, deprecated legacy array).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

"List files and directories in a repository" gives a specific verb and resource, and it implicitly reads as a tree/listing operation distinct from get_file_contents. However, it never names get_file_contents or get_repository_tree's own scope boundary (e.g. single-file retrieval vs. directory traversal), so sibling differentiation is left to inference.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to prefer this over get_file_contents, get_branch, or search_repositories. Nothing tells the agent to set recursive for deep traversal, to use path to scope a subtree, or which pagination mode to pick — all decisions the caller must guess at.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

health_checkA
Read-only

Check auth and versions. Always includes mcp_server_version. When authenticated, also GitLab version, revision, and enterprise from GET /api/v4/version. Version lookup failures omit those fields instead of failing.

NameRequiredDescriptionDefault
jmespathNoOptional JMESPath expression filtering the JSON result before return.

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and openWorldHint, so the safety profile is covered; the description earns credit for adding behavior annotations cannot express: the upstream endpoint (GET /api/v4/version) and, notably, that version lookup failures omit those fields rather than failing the call. That partial-degradation contract is exactly the kind of context an agent needs and cannot get from structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, zero filler, and the always-present field is front-loaded before the conditional fields. Every clause carries distinct information: what is checked, what is always returned, what is conditionally returned, and what happens on failure.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, and the description compensates by enumerating the returned fields (mcp_server_version always; version, revision, enterprise when authenticated) and the failure mode. It stops short of explaining what the response looks like when unauthenticated beyond 'always includes mcp_server_version', which leaves a small gap for a diagnostic tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with a single optional jmespath parameter that the schema documents fully with its own description. The tool description adds nothing about the parameter, so the baseline 3 applies — the schema does all the work.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb-plus-resource statement ('Check auth and versions') and immediately clarifies what is always returned versus conditionally returned. It is clearly not a data-fetching sibling, though it never distinguishes itself from whoami, the other auth/identity-adjacent tool in the sibling list.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: an agent can infer this is the tool to call to verify credentials or server version, and the phrase 'When authenticated' hints at a pre-flight role. There is no explicit when-to-use, when-not-to-use, or named alternative (e.g. whoami) that would raise this above implied guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

helpA
Read-only

Return a short GitLab workflow guide. Omit topic for the overview and topic list. Topics: code-review, merge-requests, issues, pipelines, search, token-saving. Prefer discover_tools over GITLAB_TOOLSETS=all. With OAUTH_STATELESS_MODE=true persist GITLAB_TOOLSETS instead.

NameRequiredDescriptionDefault
topicNoGuide to return. Omit for the overview and the list of topics.
jmespathNoOptional JMESPath expression filtering the JSON result before return.

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and openWorldHint, so the safety profile is covered. The description adds that output is a 'short' guide and that behavior shifts under OAUTH_STATELESS_MODE, which is genuinely non-obvious, but the environment-variable sentences are terse and read more like toolset configuration advice than disclosure about this tool's operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four short sentences, front-loaded with the core purpose and topic list before the routing advice. The trailing environment-variable sentences are the weakest part and could be trimmed or clarified without loss.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With only two optional parameters and no output schema, the definition covers enough: what it returns, how to select a topic, and how it relates to discover_tools. The absence of any hint about the shape of the returned guide is a minor gap given there is no output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the topic enum already lists every value with its own description, so the description's topic list and 'omit for the overview' note largely restate structured data. The jmespath parameter, the one piece an agent might want explained, gets no mention here at all.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource ('Return a short GitLab workflow guide') and enumerates the exact topics available, which lets an agent distinguish this documentation tool from the operational siblings (get_project, create_merge_request, etc.). It also names discover_tools as the related-but-different tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit call guidance ('Omit topic for the overview and topic list') and names an alternative tool with a preference rule ('Prefer discover_tools over GITLAB_TOOLSETS=all'). What it lacks is when-not-to-use guidance for the GitLab workflow topics themselves — e.g., when to read a guide versus just calling get_merge_request.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_branchesB
Read-only

List branches in project with search filter. For one known resource, use the matching get tool.

NameRequiredDescriptionDefault
pageNoPage number (default 1)
searchNoSearch term to filter branches by name
summaryNoIf true, return only high-signal fields (id, iid, title, state, web_url, …). Default false keeps the full GitLab JSON.
jmespathNoOptional JMESPath expression filtering the JSON result before return.
per_pageNoItems per page (max 100, default 20)
project_idYesProject ID or complete URL-encoded path to project

TDQS

B3.4/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds only the existence of a search filter, which the schema already documents, and says nothing about pagination behavior, default result size, ordering, or how much data a full listing can return — the practical concerns for a list endpoint.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, front-loaded with the primary action and followed by the alternative-route hint. Nothing is padded, though the second sentence is slightly awkwardly worded ('the matching get tool') rather than crisp.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

This is a simple read-only list tool with a fully documented schema and annotations covering safety, so not much is required. Still, for a paginated endpoint with a default of 20 and a max of 100, a brief note on pagination or result-size expectations would close the remaining gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so page, per_page, search, summary, jmespath and project_id are all documented in the schema itself. The description merely echoes the search filter, adding no format, syntax, or interaction detail beyond what the structured fields provide. Baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb and resource ('List branches in project') plus the scoping modifier ('with search filter'), so an agent immediately knows what the tool returns. It stops short of naming the sibling 'get_branch' explicitly, referring only to 'the matching get tool', which keeps it from a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'For one known resource, use the matching get tool' establishes the list-vs-get split, which is exactly the decision an agent faces here. The guidance is directional but generic — it does not name get_branch or state what counts as a 'known resource' — so it is clear context rather than explicit routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_commitsB
Read-only

List repository commits with filtering options. For one known resource, use the matching get tool.

NameRequiredDescriptionDefault
allNoEvery commit in the repository
pageNoPage number (default 1)
pathNoFile path
orderNodefault or topo
sinceNoCommits on or after this ISO 8601 datetime
untilNoCommits on or before this ISO 8601 datetime
authorNoCommit author
summaryNoIf true, return only high-signal fields (id, iid, title, state, web_url, …). Default false keeps the full GitLab JSON.
jmespathNoOptional JMESPath expression filtering the JSON result before return.
per_pageNoItems per page (max 100, default 20)
ref_nameNoBranch, tag, or revision range. Default: default branch.
trailersNoInclude Git trailers
project_idYesProject ID or URL-encoded path
with_statsNoInclude per-commit stats
first_parentNoFollow only the first parent of merges

TDQS

B3.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already supply readOnlyHint and openWorldHint, so the description's main job is to add the operational detail they don't cover. It says nothing about pagination defaults, full-vs-summary payload behavior, ordering semantics, or result size limits, so an agent learns nothing about runtime behavior it could not already infer from the structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, front-loaded with the verb and resource, no filler adjectives or restated titles. The second sentence is slightly boilerplate and vague, which keeps it out of the top band.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 15 parameters and no output schema, the description is thin, but the schema is fully described and the annotations cover the safety profile, so the essential calling information is present. What is missing is guidance on the interaction of paging, summary/jmespath shaping, and traversal flags (all, first_parent) that matter for a commit listing tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so every one of the 15 parameters is already documented in the schema, including the nuanced summary, jmespath, and ref_name entries. The description's "filtering options" adds no meaning beyond that, making the baseline 3 correct.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

"List repository commits with filtering options" states a specific verb plus resource and implies the filterable axes. It also gestures at separation from the single-resource getter, though it never names get_commit, so the sibling differentiation is suggestive rather than explicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"For one known resource, use the matching get tool" gives a real when-not-to-use condition (single commit already identified), which is more than nothing. But "matching get tool" is unresolved phrasing among 37 siblings, and nothing says when to prefer filters like path/ref_name/since versus list_branches or search_repositories.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_issue_discussionsB
Read-only

List discussions for an issue. List threaded discussions for an issue. Use list_issues or get_issue for issue records.

NameRequiredDescriptionDefault
pageNoPage number (default 1)
summaryNoIf true, return only high-signal fields (id, iid, title, state, web_url, …). Default false keeps the full GitLab JSON.
jmespathNoOptional JMESPath expression filtering the JSON result before return.
per_pageNoItems per page (max 100, default 20)
issue_iidYesThe internal ID of the project issue
project_idYesProject ID or URL-encoded path

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so safety and reach are covered structurally. Beyond that the description adds almost nothing behavioral: it does not say the result is threaded notes, whether pagination is required to collect all discussions, or that empty results mean no discussion thread exists. The word "threaded" is the only behavioral signal, and it merely restates the resource name.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The first two sentences are near-duplicates — "List discussions for an issue" and "List threaded discussions for an issue" — so one is pure waste in a three-sentence description. The routing sentence is well placed at the end, but the tapering redundancy drags down an otherwise short text.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

This is a simple read-only list tool with fully documented parameters and no output schema, so much of the burden is off the description. Still, an agent gets no sense of what a discussion object contains (threaded notes) or how paging interacts with the result set, which are the two things that would round out a listing tool like this.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and all six parameters (including `page`, `per_page`, `summary`, and `jmespath`) are documented in the schema itself. The description adds no meaning beyond that, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb and resource ("List threaded discussions for an issue") and explicitly routes issue-record needs to `list_issues`/`get_issue`, so it is distinguishable from the closest siblings. It does not distinguish itself from discussion-oriented siblings such as `mr_discussions` or `get_merge_request_discussion`, but resource scope (issue vs. merge request) is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It provides one explicit exclusion — use `list_issues` or `get_issue` for issue records rather than this tool — which is useful negative guidance. It never states the positive trigger case (e.g., reading comment threads on an issue to review feedback) or mentions pagination-driven iteration, so the guidance is partial rather than complete.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_issuesA
Read-only

List issues (default: created by current user; use scope='all' for all). Use this for issue management. Optional project_id. Use get_issue when the iid is known and my_issues for assignments.

NameRequiredDescriptionDefault
pageNoPage number (default 1)
scopeNoIssue scope
stateNoIssue state
labelsNoLabel names
searchNoSearch terms
summaryNoIf true, return only high-signal fields (id, iid, title, state, web_url, …). Default false keeps the full GitLab JSON.
due_dateNoDue date
jmespathNoOptional JMESPath expression filtering the JSON result before return.
per_pageNoItems per page (max 100, default 20)
author_idNoAuthor user ID. Mutually exclusive with author_username.
milestoneNoMilestone title
issue_typeNoissue, incident, test_case, or task
project_idNoProject ID or URL-encoded path. Omit to list issues across accessible projects.
assignee_idNoUser ID, none, or any. Mutually exclusive with assignee_username.
confidentialNoConfidential or public
iteration_idNoIteration ID, none (no iteration), or any (has an iteration).
created_afterNoCreated after
updated_afterNoUpdated after
created_beforeNoCreated before
updated_beforeNoUpdated before
author_usernameNoAuthor username. Mutually exclusive with author_id.
assignee_usernameNoUsername. Mutually exclusive with assignee_id.
with_labels_detailsNoInclude label details

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds a genuinely non-obvious behavioral fact — that results are silently filtered to issues created by the current user unless scope='all' — which is not stated in the schema. It does not mention pagination limits or the summary/jmespath output-shaping behavior, but those are documented in the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the scope default that most affects results, followed by alternatives. The middle sentence 'Use this for issue management' is generic filler that could be dropped without loss.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 23-parameter, no-required-param list tool with full schema descriptions and read-only annotations, the description supplies what the schema cannot: the implicit scope default and sibling routing. Missing only output-shape/pagination expectations, which the schema's page, per_page, and summary fields largely cover.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline would be 3. The description adds the missing default value for the scope parameter (created_by_me), which the schema only labels 'Issue scope'. The note that project_id is optional and omitting it spans all accessible projects restates the schema rather than extending it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource ('List issues') and immediately qualifies the scope with the default behavior (created by current user). It also names the sibling tools get_issue and my_issues so the agent can distinguish the listing role, though the filler sentence 'Use this for issue management' adds nothing.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives concrete routing: use scope='all' to broaden beyond the default, use get_issue when the iid is known, and use my_issues for assignments. That covers the main decision points, but there is no guidance on when to use this versus other listing tools like list_projects or list_merge_requests, nor when to omit project_id.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_labelsB
Read-only

List labels for a project. For one known resource, use the matching get tool.

NameRequiredDescriptionDefault
pageNoPage number (default 1)
searchNoKeyword to filter labels by
summaryNoIf true, return only high-signal fields (id, iid, title, state, web_url, …). Default false keeps the full GitLab JSON.
jmespathNoOptional JMESPath expression filtering the JSON result before return.
per_pageNoItems per page (max 100, default 20)
project_idYesProject ID or URL-encoded path
with_countsNoWhether to include issue and merge request counts
include_ancestor_groupsNoInclude ancestor groups

TDQS

B3.3/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so safety is covered, but the description adds essentially no behavior beyond that: nothing on pagination limits, default page size, whether ancestor-group labels are included by default, or how with_counts affects payload size. The one useful nugget — that a targeted get tool exists for single-resource reads — is a routing hint rather than behavioral disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with the core purpose front-loaded and the alternative surfaced immediately after. Nothing is wasted or padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an eight-parameter list tool with no output schema, the description is minimal but the schema carries the parameter burden. It still leaves the agent guessing about default result shape and pagination behavior, which matters given the summary and jmespath options.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all eight parameters (page, per_page, search, summary, jmespath, with_counts, include_ancestor_groups, project_id) are already documented in the schema. The description adds no parameter semantics of its own, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource scoped to a project ("List labels for a project"), which is clearly distinct from the merge-request, issue, and branch siblings. It does not name the counterpart get tool explicitly, so the differentiation is directional rather than precise.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The second sentence gives one routing rule — fetch a single known label via the matching get tool rather than listing — which is genuine when-to-use guidance. However, no guidance is given on when to use the search/per_page/page parameters versus narrowing some other way, and no mention of the non-label siblings an agent might confuse this with.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_merge_request_changed_filesA
Read-only

List changed file paths in a merge request without diff content (merge_request_iid or source_branch required).

NameRequiredDescriptionDefault
summaryNoIf true, return only high-signal fields (id, iid, title, state, web_url, …). Default false keeps the full GitLab JSON.
jmespathNoOptional JMESPath expression filtering the JSON result before return.
project_idYesProject ID or URL-encoded path
source_branchNoSource branch name
merge_request_iidNoMerge request IID
excluded_file_patternsNoArray of regex patterns to exclude files. Examples: ["^vendor/", "\.pb\.go$"]

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already state readOnlyHint=true and openWorldHint=true, so safety is covered. The description adds useful behavior by saying no diff content is returned and one MR selector is required, but it omits pagination, ordering, and what happens if both selectors are supplied.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The definition is a single front-loaded sentence with no filler. The key scope, payload distinction, and selector requirement are all stated efficiently.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a six-parameter read-only list tool with no output schema, the description adequately conveys the return focus: changed file paths without diff content. It could more fully explain result ordering or pagination, but the schema documents the remaining parameters well.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3. The description adds a meaningful conditional constraint not expressed in the schema's required list: either merge_request_iid or source_branch must be provided.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: list changed file paths in a merge request. The phrase 'without diff content' distinguishes it from diff-oriented siblings such as list_merge_request_diffs and get_merge_request_file_diff.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear context for using this tool when only file paths are needed, and it specifies that merge_request_iid or source_branch is required. It does not explicitly name alternative tools or when not to use it, which keeps it below a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_merge_request_diffsA
Read-only

List merge request diffs with pagination (merge_request_iid or source_branch required). For one known resource, use the matching get tool.

NameRequiredDescriptionDefault
pageNoPage number for pagination (default: 1)
summaryNoIf true, return only high-signal fields (id, iid, title, state, web_url, …). Default false keeps the full GitLab JSON.
unidiffNoPresent diffs in the unified diff format. Default is false. Introduced in GitLab 16.5.
jmespathNoOptional JMESPath expression filtering the JSON result before return.
per_pageNoNumber of items per page (max: 100, default: 20)
project_idYesProject ID or URL-encoded path
source_branchNoSource branch name
merge_request_iidNoMerge request IID

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered and the description only needs to add context. It contributes the pagination behavior and the requirement that an IID or source branch be supplied, but says nothing about ordering, diff truncation, size limits, or response shape. Adequate against an already-rich annotation and schema set, but thin on behavior beyond them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, zero filler, and the invocation-critical constraint sits in the opening line ahead of the alternative-tool routing. Every clause carries information an agent needs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 8 parameters, no output schema, and readOnlyHint covering safety, the description covers the essentials: what it lists, that it paginates, and the required selector. The main shortfall is the unspecified "matching get tool," which forces the agent to disambiguate among several diff-related siblings on its own.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds a constraint the schema does not encode: it states merge_request_iid or source_branch is required, while the schema lists only project_id as required. That is real meaning beyond the schema and useful for correct invocation. It leaves page/per_page interaction and the summary/unidiff tradeoffs entirely to the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description pairs a specific verb and resource ("List merge request diffs") with a scope constraint (pagination; merge_request_iid or source_branch required), which lets an agent distinguish this list operation from the get_merge_request_diffs sibling. It stops short of naming the sibling explicitly, so differentiation is implied by the singular/plural distinction rather than stated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"For one known resource, use the matching get tool" gives a genuine when-to-use rule: list when the target is not pinned down, get when it is. The gap is that "the matching get tool" is not named, and with siblings like get_merge_request_diffs, get_merge_request_file_diff, and list_merge_request_changed_files available, the agent must infer which one is meant.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_merge_requestsA
Read-only

List merge requests (without project_id: user's MRs; with project_id: project MRs). For one known resource, use the matching get tool.

NameRequiredDescriptionDefault
wipNoWIP filter
pageNoPage number (default 1)
sortNoasc or desc
scopeNoMR scope
stateNoMR state
labelsNoLabel names
searchNoSearch terms
summaryNoIf true, return only high-signal fields (id, iid, title, state, web_url, …). Default false keeps the full GitLab JSON.
jmespathNoOptional JMESPath expression filtering the JSON result before return.
order_byNoSort field
per_pageNoItems per page (max 100, default 20)
author_idNoAuthor user ID. Mutually exclusive with author_username.
milestoneNoMilestone title
project_idNoProject ID or URL-encoded path. Omit to list the user's accessible MRs.
assignee_idNoUser ID, none, or any. Mutually exclusive with assignee_username.
reviewer_idNoReviewer user ID, none, or any. Mutually exclusive with reviewer_username.
created_afterNoCreated after
source_branchNoSource branch
target_branchNoTarget branch
updated_afterNoUpdated after
created_beforeNoCreated before
updated_beforeNoUpdated before
author_usernameNoAuthor username. Mutually exclusive with author_id.
assignee_usernameNoUsername. Mutually exclusive with assignee_id.
reviewer_usernameNoReviewer username. Mutually exclusive with reviewer_id.
with_labels_detailsNoInclude label details
approved_by_usernamesNoApproved by these usernames

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered; the description adds the scope-switching semantics, which is genuinely useful behavioral context. However it says nothing about pagination defaults, result size, or the summary/jmespath response-shaping options that materially change what comes back.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two compact sentences, front-loaded with the resource and scope rule, with zero redundant wording. Every clause carries a distinct instruction.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 27-parameter listing tool with no output schema, the description covers the key scope decision and the alternative tool but skips pagination behavior and the response-shaping options (summary, jmespath) that an agent must understand to get usable output. Adequate, not thorough.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, including enums, mutual-exclusion notes, and the summary/jmespath options, so the schema carries the parameter burden. The description only restates the project_id semantics that the schema already documents. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List merge requests') and immediately explains the two scoping modes: user's MRs when project_id is omitted, project MRs when supplied. It doesn't enumerate the filterable dimensions (state, scope, labels, dates) that distinguish it from other listing tools, so it falls short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit hand-off rule: for a single known resource, use the matching get tool (get_merge_request). It does not state when-not to use it (e.g. versus search-based sibling listing) or mention pagination expectations, but the core routing decision is spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_project_membersA
Read-only

List members of a GitLab project. Search project members by name or username. Use list_group_members for a group.

NameRequiredDescriptionDefault
pageNoPage number for pagination (default: 1)
queryNoSearch for members by name or username
summaryNoIf true, return only high-signal fields (id, iid, title, state, web_url, …). Default false keeps the full GitLab JSON.
jmespathNoOptional JMESPath expression filtering the JSON result before return.
per_pageNoNumber of items per page (default: 20, max: 100)
user_idsNoFilter by user IDs
project_idYesProject ID or URL-encoded path
skip_usersNoUser IDs to exclude
include_inheritanceNoInclude inherited members. Defaults to false.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety and reach profile is covered. The description adds only the search capability and the group alternative; it says nothing about pagination behavior, the default exclusion of inherited members, or result shape beyond what the `summary`/`jmespath` params already document.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the purpose, then the search nuance, then the sibling routing. No filler, and each sentence carries distinct information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

A read-only list tool with fully documented params and annotations declaring safety — the description covers purpose and the one real routing ambiguity. It omits that inherited members are excluded by default, which matters for a project-member listing, but no output schema is needed to explain returns since `summary` and `jmespath` handle shaping.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all nine parameters are already self-documenting. The description's 'search by name or username' merely restates the `query` param, and it offers no extra semantics (e.g., interaction between `user_ids`, `skip_users`, and `include_inheritance`), so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List members of a GitLab project') with explicit scope, then names the sibling it is not ('Use `list_group_members` for a group'). An agent can distinguish project vs group member listing without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives one explicit routing rule to the group-level alternative, which is the main ambiguity an agent would face. It does not state when to use search/filtering versus a plain listing, or note that the referenced `list_group_members` is not in the current toolset, leaving a small inference gap.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_projectsA
Read-only

List projects accessible by the current user. For one known resource, use the matching get tool.

NameRequiredDescriptionDefault
pageNoPage number (default 1)
sortNoasc or desc
ownedNoOwned by current user
topicNoTopic tag
searchNoSearch term
simpleNoLimited fields only
summaryNoIf true, return only high-signal fields (id, iid, title, state, web_url, …). Default false keeps the full GitLab JSON.
archivedNoArchived projects
jmespathNoOptional JMESPath expression filtering the JSON result before return.
order_byNoSort field
per_pageNoItems per page (max 100, default 20)
membershipNoCurrent user is a member
visibilityNopublic, internal, or private
min_access_levelNoMinimum access level
search_namespacesNoSet true when search is a full path
with_issues_enabledNoIssues enabled
with_merge_requests_enabledNoMerge requests enabled

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so safety and reach are covered. The description adds the access-scoping behavior (results limited to what the current user can see), but says nothing about pagination defaults, result volume, or the fact that the default response is full, potentially large JSON.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with zero filler, and the primary scope statement is front-loaded ahead of the alternative redirection. Nothing is redundant or buried.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 17-parameter list tool with no output schema, the description covers only the core purpose and the get-vs-list split. Subtle knobs like summary vs simple vs jmespath, and paging via page/per_page, are left entirely to the schema; adequate because of full schema coverage, but thin for the tool's complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so every one of the 17 parameters already carries its own description and enums. The description adds no meaning about the filters (owned, membership, visibility, min_access_level) or the interaction between summary, simple, and jmespath, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ("List projects") and a scope ("accessible by the current user"), which distinguishes it from the mutation siblings. The second sentence routes away from it for single-resource lookups, though it says "the matching get tool" rather than naming get_project, so differentiation is slightly indirect.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a clear when-to-use (enumerating accessible projects) and an explicit when-not (a single known resource should use the corresponding get tool). It does not address the overlap with other search-style siblings such as search_repositories or list_project_members, nor does it note when filters should be preferred over client-side filtering.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

mr_discussionsA
Read-only

List discussion items for a merge request. List complete discussion threads. Use get_merge_request_notes for flat notes.

NameRequiredDescriptionDefault
pageNoPage number (default 1)
summaryNoIf true, return only high-signal fields (id, iid, title, state, web_url, …). Default false keeps the full GitLab JSON.
jmespathNoOptional JMESPath expression filtering the JSON result before return.
per_pageNoItems per page (max 100, default 20)
project_idYesProject ID or complete URL-encoded path to project
merge_request_iidYesThe IID of a merge request

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds only the thread-vs-note distinction and says nothing about pagination semantics (whether paging applies to threads or notes), ordering, or that unresolved/resolvable state is included, which matters for a discussions listing.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences with no filler; the core listing behavior is front-loaded and the routing hint follows immediately. Nothing is repeated from the schema or annotations.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given six fully documented parameters and no output schema, the definition covers purpose and alternative routing adequately. However, with no output schema present, the description would be more complete if it sketched the shape of a discussion thread (id, notes array, resolved flag) so an agent knows what to do with the GitLab JSON.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, documenting page, per_page, summary, jmespath, project_id and merge_request_iid fully. The description adds no parameter-level meaning beyond that, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb and resource ('List discussion items for a merge request') and clarifies the granularity as 'complete discussion threads', which distinguishes it from the singular get_merge_request_discussion. The slight tension between 'discussion items' and 'threads' in the first two sentences introduces a small ambiguity about the returned unit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly names the alternative, `get_merge_request_notes`, and the condition that selects it ('flat notes'). It stops short of stating exclusions or prerequisites such as needing the MR to exist or how resolving threads interacts with the resolve_merge_request_thread sibling.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

my_issuesA
Read-only

List issues assigned to the authenticated user. Use this for issue management. Use list_issues for project-wide listing and get_issue for one issue. Requires classic read_user or fine-grained User:Read.

NameRequiredDescriptionDefault
pageNoPage number for pagination (default: 1)
stateNoReturn issues with a specific state (default: opened)
labelsNoArray of label names to filter by
searchNoSearch for specific terms in title and description
jmespathNoOptional JMESPath expression filtering the JSON result before return.
per_pageNoNumber of items per page (default: 20, max: 100)
milestoneNoMilestone title to filter by
project_idNoProject ID or URL-encoded path (optional to search across all accessible projects)
created_afterNoReturn issues created after the given time (ISO 8601)
updated_afterNoReturn issues updated after the given time (ISO 8601)
created_beforeNoReturn issues created before the given time (ISO 8601)
updated_beforeNoReturn issues updated before the given time (ISO 8601)

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so safety is covered. The description adds a genuinely useful prerequisite — the required classic read_user or fine-grained User:Read scope — which tells the agent an auth failure is possible and why. Beyond that it says nothing about pagination behavior or that results span all accessible projects when project_id is omitted.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the scoping statement, then alternatives, then auth — a sensible order with no wasted length. The sentence 'Use this for issue management' carries no information and could be cut, keeping it from a perfect score.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 12-parameter, zero-required read tool with no output schema and annotations covering safety, the description covers purpose, alternatives, and auth prerequisites. It is slightly thin on result shape and pagination expectations, but the fully-described schema closes most of that gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all twelve parameters are already documented in the schema, including pagination, state enum, date filters, and the project_id cross-project note. The description adds no parameter-level meaning, which is the baseline-3 case when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource with explicit scope: 'List issues assigned to the authenticated user.' The scope (assigned to me) is exactly what separates it from list_issues and get_issue, so an agent can identify it without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Names both alternatives and the condition that selects each: 'Use `list_issues` for project-wide listing and `get_issue` for one issue.' The one soft sentence, 'Use this for issue management,' is redundant but harmless next to the explicit routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

resolve_merge_request_threadA

Resolve a thread on a merge request. Mark an existing review thread resolved. Use update_merge_request_discussion_note to change note text.

NameRequiredDescriptionDefault
jmespathNoOptional JMESPath expression filtering the JSON result before return.
resolvedYesWhether to resolve the thread
project_idYesProject ID or complete URL-encoded path to project
discussion_idYesThe ID of a thread
merge_request_iidYesThe IID of a merge request

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations provide only openWorldHint, so the description carries most of the behavioral burden. It implies a state mutation on a review thread and what specifically changes (resolution status), which is useful, but it omits permission requirements, reversibility, and the fact that resolved=false can unresolve a thread. For a mutation tool with no destructive/readOnly annotations, that is a notable gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, front-loaded with the action, followed by a targeted disambiguation pointer. No redundant restatement of the title or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is a mutation with no output schema and only an openWorldHint annotation, so the description should do more: it does not cover the unresolve case, permission/auth expectations, or what the call returns. Adequate to invoke correctly, but incomplete for a state-changing operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all five parameters are already documented and the baseline is 3. The description adds no syntax or semantics beyond the schema; notably it does not clarify that the boolean 'resolved' also supports unresolving when false, which is the one place it could have added value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb and resource ('Resolve a thread on a merge request') and reinforces it with 'Mark an existing review thread resolved.' It also explicitly names the sibling tool to use for a different operation (editing note text), so an agent can distinguish it from update_merge_request_discussion_note without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It clearly states the use case (marking an existing thread resolved) and routes the agent to update_merge_request_discussion_note for note-text editing, which is a concrete alternative. It stops short of stating exclusions or prerequisites (e.g., what happens if the thread is already resolved, or permission requirements), so it is not a full 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_repositoriesA
Read-only

Search for GitLab projects. If the identifier is known, use a typed get or list tool.

NameRequiredDescriptionDefault
pageNoPage number (default 1)
queryNoSearch query (alias for 'search')
searchNoSearch query
jmespathNoOptional JMESPath expression filtering the JSON result before return.
per_pageNoItems per page (max 100, default 20)

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered structurally. The description adds nothing beyond that: no match behavior, no default result set size, no note that an empty result is normal for a search, and no pagination guidance despite page/per_page being present. With annotations doing the heavy lifting, a 3 is the right ceiling.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the purpose and with zero filler or repetition. It is arguably under-sized rather than concise, which keeps it off a 5, but every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Subtracting the schema (which fully documents all five parameters) and the annotations (read-only, open-world), the description covers the one thing structured fields cannot: how to choose the tool at all. It stops short of a 5 because scoping details, such as whether results span accessible projects only, are omitted for an open-world search.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The most confusing aspect, that 'query' is an alias for 'search', is documented only in the schema, not the description, and the description adds no meaning about what the search string matches against.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence states a specific verb and resource ('Search for GitLab projects'), which is clear enough to act on. It falls short of a 5 because it never says what field is searched (name, path, description) or how results differ from the sibling list_projects, so an agent still has to infer the distinction from the name alone.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The second sentence gives an explicit routing rule: when the identifier is known, use a typed get or list tool instead. That is real when-to-use and when-not guidance naming an alternative path. It does not name the concrete siblings (get_project, list_projects) or cover the case where the identifier is only partially known.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_issueA

Update an issue. Slim confirmation by default; full_response=true for the complete object. Change fields on an existing issue. Use update_issue_description_patch for a targeted description edit and create_issue_note for discussion.

NameRequiredDescriptionDefault
titleNoIssue title
labelsNoLabel names
weightNoIssue weight
due_dateNoDue date (YYYY-MM-DD)
jmespathNoOptional JMESPath expression filtering the JSON result before return.
issue_iidYesIssue IID
issue_typeNoissue, incident, test_case, or task
project_idYesProject ID or URL-encoded path
descriptionNoIssue description
state_eventNoclose or reopen
assignee_idsNoAssignee user IDs
confidentialNoConfidential
milestone_idNoMilestone ID
full_responseNoIf true, return the complete updated issue. Default is slim (iid, title, state, web_url, updated_at).
discussion_lockedNoLock discussions

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations supply only openWorldHint=true, so the description carries most of the behavioral burden. It usefully discloses the default return shape (slim: iid, title, state, web_url, updated_at) versus full_response=true — but that same detail is already in the `full_response` schema description, so the added value is limited. For a mutation tool it says nothing about permission requirements, reversibility, or side effects of `state_event` closing/reopening.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four short sentences, front-loaded with the verb+resource, and no padding. Minor redundancy: "Update an issue" and "Change fields on an existing issue" say the same thing twice, and the response-shape sentence is duplicated in the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Adequate for a 15-parameter mutation tool: field coverage lives in the schema and return shape is addressed. However, with no output schema and no annotation coverage of safety/permissions, the description should say more about the consequences of state transitions and what the slim confirmation actually omits.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so every one of the 15 parameters is already documented (enums for state_event and issue_type, date format for due_date, JMESPath filtering). The description adds no meaning beyond what the schema provides, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ("Update an issue" / "Change fields on an existing issue") that an agent can match to intent immediately. It also distinguishes two nearby siblings, but only partially — it never contrasts with other write tools in the set (update_merge_request, create_issue) or clarifies that it cannot create issues.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes the agent away from this tool for two cases: targeted description edits go to `update_issue_description_patch`, and discussion goes to `create_issue_note`. There is no when-not-to-use guidance for the broader class of writes (e.g., creating an issue, updating an MR), which keeps it below a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_issue_description_patchA

Patch an issue description (search/replace or unified diff) without resending the full body. dry_run previews; create_note summarizes.

NameRequiredDescriptionDefault
patchYesThe patch content to apply to the issue description
dry_runNoIf true, preview changes without updating the issue
jmespathNoOptional JMESPath expression filtering the JSON result before return.
issue_iidYesThe internal ID of the project issue
patch_typeYesType of patch format to apply
project_idYesProject ID or URL-encoded path
create_noteNoIf true, add a note summarizing the change after update
allow_multipleNoFor search_replace: allow multiple matches to all be replaced (default: false — fail on duplicate)

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only supply openWorldHint, so the description carries most of the burden. It usefully discloses two behavioral flags (dry_run previews, create_note summarizes after the update) but says nothing about permissions, match-failure behavior, or what happens to unmentioned description content.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with zero filler, front-loading the core action and formats before the optional behaviors. Every clause carries information an agent needs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an eight-parameter mutation tool with only openWorldHint for annotations and no output schema, the definition covers the happy path but leaves out error semantics (patch mismatch, duplicate matches) and permission requirements. Adequate but with clear gaps given the tool's complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so all eight parameters are already documented in the schema. The description's notes on dry_run and create_note largely restate the schema text and it adds nothing for allow_multiple, jmespath, or patch_type beyond naming the formats. Baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (patch) plus resource (issue description) and names the two supported formats (search/replace, unified diff). The clause 'without resending the full body' implicitly separates it from the sibling update_issue, though it never names that tool outright.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage by contrasting with a full-body update, and it explains what dry_run and create_note do. But it gives no explicit when-to-use/when-not guidance and no prerequisite or failure conditions (e.g., what happens when a search pattern doesn't match).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_merge_requestA

Update a merge request (merge_request_iid or source_branch required). Use the create tool for new resources and a note tool for comments.

NameRequiredDescriptionDefault
draftNoDraft / WIP
titleNoMR title
labelsNoMR labels
squashNoSquash commits on merge
jmespathNoOptional JMESPath expression filtering the JSON result before return.
project_idYesProject ID or URL-encoded path
descriptionNoMR description
state_eventNoclose or reopen
assignee_idsNoAssignee user IDs
milestone_idNoMilestone ID. 0 unassigns. Null is omitted.
reviewer_idsNoReviewer user IDs
source_branchNoSource branch name
target_branchNoTarget branch
merge_request_iidNoMerge request IID
remove_source_branchNoRemove source branch on merge

TDQS

A3.5/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The only annotation is openWorldHint=true, so the description carries the full behavioral burden for a mutation tool and largely drops it. It never states that this is a mutation, that changes are applied immediately without confirmation, or that state_event can close or reopen an MR, and it says nothing about which settings are left untouched when omitted.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, front-loaded with the action and the routing advice immediately after. Every clause carries information; the only minor cost is that the parenthetical constraint is buried mid-sentence rather than stated as a standalone requirement.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 15 parameters, a mutation surface, and no output schema, the definition is thinner than the tool's complexity warrants. The fully documented schema compensates for parameter meaning, but the description omits confirmation semantics and the close/reopen side effect that an agent should warn about before calling.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline would be 3, but the description adds a real constraint absent from the schema: that merge_request_iid or source_branch is required. The schema lists only project_id as required, so this note prevents a validation-level mistake. It adds nothing about the enum-constrained state_event or the merge-time flags.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

"Update a merge request" gives a specific verb plus resource, and the parenthetical identifier constraint narrows the target further. It stops short of distinguishing itself from other merge-request siblings by name (e.g. get_merge_request, create_merge_request), so an agent must infer the read/write split.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit when-not guidance is present: creation of new resources goes to the create tool, and commenting goes to a note tool. That routes the two most likely mis-selections. It does not cover the read-side alternative (get_merge_request) or prerequisites such as permissions or MR state.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

whoamiA
Read-only

Get current authenticated user details. Requires classic read_user or fine-grained User:Read. Use get_user or get_users to look up another user.

NameRequiredDescriptionDefault
jmespathNoOptional JMESPath expression filtering the JSON result before return.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint and openWorldHint, and the description adds genuinely new context: the required OAuth scopes (classic read_user or fine-grained User:Read), which an agent cannot infer from structured fields. It stops short of describing the returned payload or any rate-limit behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences with the core action front-loaded, followed by the auth prerequisite and the sibling routing. No wasted text.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-required-param read tool with annotations and full schema coverage, this covers purpose, auth prerequisites and alternatives. Only the shape of the returned user object is unspecified, which is a minor gap absent an output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the single optional jmespath parameter is fully documented in the schema; the description adds nothing about it, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Get current authenticated user details') and explicitly scopes it to the caller, distinguishing it from user-lookup siblings by naming get_user and get_users.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives both when to use this tool and when not to, routing the agent to the named alternatives for looking up another user. Nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 22 tool updatesv2.3.22
    • Changedcreate_issue5 fields changed
      • changedInput schema / properties / assignee_ids / description
        Previous value: -"Array of user IDs to assign"New value: +"Assignee user IDs"
      • changedInput schema / properties / issue_type / description
        Previous value: -"The type of issue. One of issue, incident, test_case or task."New value: +"issue, incident, test_case, or task"
      • changedInput schema / properties / labels / description
        Previous value: -"Array of label names"New value: +"Label names"
      • changedInput schema / properties / milestone_id / description
        Previous value: -"Milestone ID to assign"New value: +"Milestone ID"
      • changedInput schema / properties / weight / description
        Previous value: -"Weight of the issue (numeric, typically hours of work)"New value: +"Issue weight"
    • Changedcreate_merge_request10 fields changed
      • changedInput schema / properties / allow_collaboration / description
        Previous value: -"Allow commits from upstream members"New value: +"Allow eligible upstream members to push to the fork source branch"
      • changedInput schema / properties / assignee_ids / description
        Previous value: -"The ID of the users to assign the MR to"New value: +"Assignee user IDs"
      • changedInput schema / properties / draft / description
        Previous value: -"Create as draft merge request"New value: +"Create as draft"
      • changedInput schema / properties / labels / description
        Previous value: -"Labels for the MR"New value: +"MR labels"
      • changedInput schema / properties / remove_source_branch / description
        Previous value: -"Flag indicating if a merge request should remove the source branch when merging."New value: +"Remove source branch on merge"
      • changedInput schema / properties / reviewer_ids / description
        Previous value: -"The ID of the users to assign as reviewers of the MR"New value: +"Reviewer user IDs"
      • changedInput schema / properties / source_branch / description
        Previous value: -"Branch containing changes"New value: +"Source branch"
      • changedInput schema / properties / squash / description
        Previous value: -"If true, squash all commits into a single commit on merge."New value: +"Squash commits on merge"
      • changedInput schema / properties / target_branch / description
        Previous value: -"Branch to merge into"New value: +"Target branch"
      • changedInput schema / properties / target_project_id / description
        Previous value: -"Numeric ID of the target project."New value: +"Target project numeric ID"
    • Changeddiscover_tools1 field changed
      • changedInput schema / properties / category / description
        Previous value: -"Toolset category to activate (e.g. 'pipelines', 'wiki'). Omit to list available categories."New value: +"Toolset to activate (e.g. pipelines, wiki). Omit to list. Prefer a category over GITLAB_TOOLSETS=all. Session-only; persist `GITLAB_TOOLSETS=core,<category>` when OAUTH_STATELESS_MODE=true."
    • Changedget_issue2 fields changed
      • changedInput schema / properties / full_response / description
        Previous value: -"If true, include the complete milestone object, including its description, on the returned issue. Default returns the issue with a slim milestone (id, iid, title, state, web_url) to reduce token usage."New value: +"If true, include the complete milestone (including description). Default is slim (id, iid, title, state, web_url)."
      • changedInput schema / properties / issue_iid / description
        Previous value: -"The internal ID of the project issue"New value: +"Issue IID"
    • Changedget_merge_request3 fields changed
      • changedInput schema / properties / include_summaries / description
        Previous value: -"If true, include deployment_summary, commit_addition_summary and approval_summary (extra API calls, larger response). Default false to reduce token usage."New value: +"If true, include deployment, commit, and approval summaries (extra API calls). Default false."
      • changedInput schema / properties / merge_request_iid / description
        Previous value: -"The IID of a merge request"New value: +"Merge request IID"
      • changedInput schema / properties / project_id / description
        Previous value: -"Project ID or complete URL-encoded path to project"New value: +"Project ID or URL-encoded path"
    • Changedget_merge_request_diffs2 fields changed
      • changedInput schema / properties / merge_request_iid / description
        Previous value: -"The IID of a merge request"New value: +"Merge request IID"
      • changedInput schema / properties / project_id / description
        Previous value: -"Project ID or complete URL-encoded path to project"New value: +"Project ID or URL-encoded path"
    • Changedget_merge_request_file_diff2 fields changed
      • changedInput schema / properties / merge_request_iid / description
        Previous value: -"The IID of a merge request"New value: +"Merge request IID"
      • changedInput schema / properties / project_id / description
        Previous value: -"Project ID or complete URL-encoded path to project"New value: +"Project ID or URL-encoded path"
    • Changedget_repository_tree8 fields changed
      • addedInput schema / properties / page
        Added value: +{
        +  "description": "Offset page number from 1 (items + next_page)",
        +  "exclusiveMinimum": 0,
        +  "maximum": 9007199254740991,
        +  "type": "integer"
        +}
      • changedInput schema / properties / page_token / description
        Previous value: -"Token for keyset pagination. Use the next_page_token value returned in the previous response to retrieve the next page."New value: +"Keyset token from the previous next_page_token"
      • changedInput schema / properties / pagination / description
        Previous value: -"Pagination method. Use 'keyset' for keyset-based pagination (required for repositories with many files). Non-keyset calls keep the legacy array response for backward compatibility; that legacy response shape is deprecated and may be removed in a future major release. Keyset calls return a structured response with items and next_page_token when more pages are available."New value: +"Use keyset for large trees (items + next_page_token). Omit both page and pagination for the legacy array (deprecated)."
      • changedInput schema / properties / path / description
        Previous value: -"The path inside the repository"New value: +"Path inside the repository"
      • changedInput schema / properties / per_page / description
        Previous value: -"Number of results to show per page"New value: +"Items per page"
      • changedInput schema / properties / project_id / description
        Previous value: -"The ID or URL-encoded path of the project"New value: +"Project ID or URL-encoded path"
      • changedInput schema / properties / recursive / description
        Previous value: -"Boolean value to get a recursive tree"New value: +"Recursive tree"
      • changedInput schema / properties / ref / description
        Previous value: -"The name of a repository branch or tag. Defaults to the default branch."New value: +"Branch or tag. Defaults to the default branch."
    • Changedhelp1 field changed
      • changedInput schema / properties / topic / description
        Previous value: -"Guide to return. Omit for the overview and the list of topics. Values: overview, code-review, merge-requests, issues, pipelines, search, token-saving."New value: +"Guide to return. Omit for the overview and the list of topics."
    • Changedlist_branches2 fields changed
      • changedInput schema / properties / page / description
        Previous value: -"Page number for pagination (default: 1)"New value: +"Page number (default 1)"
      • changedInput schema / properties / per_page / description
        Previous value: -"Number of items per page (max: 100, default: 20)"New value: +"Items per page (max 100, default 20)"
    • Changedlist_commits13 fields changed
      • changedInput schema / properties / all / description
        Previous value: -"Retrieve every commit from the repository"New value: +"Every commit in the repository"
      • changedInput schema / properties / author / description
        Previous value: -"Search commits by commit author"New value: +"Commit author"
      • changedInput schema / properties / first_parent / description
        Previous value: -"Follow only the first parent commit upon seeing a merge commit"New value: +"Follow only the first parent of merges"
      • changedInput schema / properties / order / description
        Previous value: -"List commits in order"New value: +"default or topo"
      • changedInput schema / properties / page / description
        Previous value: -"Page number for pagination (default: 1)"New value: +"Page number (default 1)"
      • changedInput schema / properties / path / description
        Previous value: -"The file path"New value: +"File path"
      • changedInput schema / properties / per_page / description
        Previous value: -"Number of items per page (max: 100, default: 20)"New value: +"Items per page (max 100, default 20)"
      • changedInput schema / properties / project_id / description
        Previous value: -"Project ID or complete URL-encoded path to project"New value: +"Project ID or URL-encoded path"
      • changedInput schema / properties / ref_name / description
        Previous value: -"The name of a repository branch, tag or revision range, or if not given the default branch"New value: +"Branch, tag, or revision range. Default: default branch."
      • changedInput schema / properties / since / description
        Previous value: -"Only commits after or on this date are returned in ISO 8601 format YYYY-MM-DDTHH:MM:SSZ"New value: +"Commits on or after this ISO 8601 datetime"
      • changedInput schema / properties / trailers / description
        Previous value: -"Parse and include Git trailers for every commit"New value: +"Include Git trailers"
      • changedInput schema / properties / until / description
        Previous value: -"Only commits before or on this date are returned in ISO 8601 format YYYY-MM-DDTHH:MM:SSZ"New value: +"Commits on or before this ISO 8601 datetime"
      • changedInput schema / properties / with_stats / description
        Previous value: -"Stats about each commit are added to the response"New value: +"Include per-commit stats"
    • Changedlist_issue_discussions2 fields changed
      • changedInput schema / properties / page / description
        Previous value: -"Page number for pagination (default: 1)"New value: +"Page number (default 1)"
      • changedInput schema / properties / per_page / description
        Previous value: -"Number of items per page (max: 100, default: 20)"New value: +"Items per page (max 100, default 20)"
    • Changedlist_issues20 fields changed
      • changedInput schema / properties / assignee_id / description
        Previous value: -"Return issues assigned to the given user ID (user id, none, or any). Mutually exclusive with assignee_username."New value: +"User ID, none, or any. Mutually exclusive with assignee_username."
      • changedInput schema / properties / assignee_username / description
        Previous value: -"Return issues assigned to the given username. Mutually exclusive with assignee_id."New value: +"Username. Mutually exclusive with assignee_id."
      • changedInput schema / properties / author_id / description
        Previous value: -"Return issues created by the given user ID. Mutually exclusive with author_username."New value: +"Author user ID. Mutually exclusive with author_username."
      • changedInput schema / properties / author_username / description
        Previous value: -"Return issues created by the given username. Mutually exclusive with author_id."New value: +"Author username. Mutually exclusive with author_id."
      • changedInput schema / properties / confidential / description
        Previous value: -"Filter confidential or public issues"New value: +"Confidential or public"
      • changedInput schema / properties / created_after / description
        Previous value: -"Return issues created after the given time"New value: +"Created after"
      • changedInput schema / properties / created_before / description
        Previous value: -"Return issues created before the given time"New value: +"Created before"
      • changedInput schema / properties / due_date / description
        Previous value: -"Return issues that have the due date"New value: +"Due date"
      • changedInput schema / properties / issue_type / description
        Previous value: -"Filter to a given type of issue. One of issue, incident, test_case or task"New value: +"issue, incident, test_case, or task"
      • changedInput schema / properties / iteration_id / description
        Previous value: -"Return issues assigned to the given iteration ID. None returns issues that do not belong to an iteration. Any returns issues that belong to an iteration. "New value: +"Iteration ID, none (no iteration), or any (has an iteration)."
      • changedInput schema / properties / labels / description
        Previous value: -"Array of label names"New value: +"Label names"
      • changedInput schema / properties / page / description
        Previous value: -"Page number for pagination (default: 1)"New value: +"Page number (default 1)"
      • changedInput schema / properties / per_page / description
        Previous value: -"Number of items per page (max: 100, default: 20)"New value: +"Items per page (max 100, default 20)"
      • changedInput schema / properties / project_id / description
        Previous value: -"Project ID or URL-encoded path (optional - if not provided, lists issues across all accessible projects)"New value: +"Project ID or URL-encoded path. Omit to list issues across accessible projects."
      • changedInput schema / properties / scope / description
        Previous value: -"Return issues from a specific scope"New value: +"Issue scope"
      • changedInput schema / properties / search / description
        Previous value: -"Search for specific terms"New value: +"Search terms"
      • changedInput schema / properties / state / description
        Previous value: -"Return issues with a specific state"New value: +"Issue state"
      • changedInput schema / properties / updated_after / description
        Previous value: -"Return issues updated after the given time"New value: +"Updated after"
      • changedInput schema / properties / updated_before / description
        Previous value: -"Return issues updated before the given time"New value: +"Updated before"
      • changedInput schema / properties / with_labels_details / description
        Previous value: -"Return more details for each label"New value: +"Include label details"
    • Changedlist_labels2 fields changed
      • changedInput schema / properties / page / description
        Previous value: -"Page number for pagination (default: 1)"New value: +"Page number (default 1)"
      • changedInput schema / properties / per_page / description
        Previous value: -"Number of items per page (max: 100, default: 20)"New value: +"Items per page (max 100, default 20)"
    • Changedlist_merge_request_changed_files2 fields changed
      • changedInput schema / properties / merge_request_iid / description
        Previous value: -"The IID of a merge request"New value: +"Merge request IID"
      • changedInput schema / properties / project_id / description
        Previous value: -"Project ID or complete URL-encoded path to project"New value: +"Project ID or URL-encoded path"
    • Changedlist_merge_request_diffs2 fields changed
      • changedInput schema / properties / merge_request_iid / description
        Previous value: -"The IID of a merge request"New value: +"Merge request IID"
      • changedInput schema / properties / project_id / description
        Previous value: -"Project ID or complete URL-encoded path to project"New value: +"Project ID or URL-encoded path"
    • Changedlist_merge_requests24 fields changed
      • changedInput schema / properties / approved_by_usernames / description
        Previous value: -"Returns merge requests approved by the given usernames (array)."New value: +"Approved by these usernames"
      • changedInput schema / properties / assignee_id / description
        Previous value: -"Return MRs assigned to the given user ID (integer), 'none', or 'any'. Mutually exclusive with assignee_username."New value: +"User ID, none, or any. Mutually exclusive with assignee_username."
      • changedInput schema / properties / assignee_username / description
        Previous value: -"Returns merge requests assigned to the given username. Mutually exclusive with assignee_id."New value: +"Username. Mutually exclusive with assignee_id."
      • changedInput schema / properties / author_id / description
        Previous value: -"Returns merge requests created by the given user ID (integer). Mutually exclusive with author_username."New value: +"Author user ID. Mutually exclusive with author_username."
      • changedInput schema / properties / author_username / description
        Previous value: -"Returns merge requests created by the given username. Mutually exclusive with author_id."New value: +"Author username. Mutually exclusive with author_id."
      • changedInput schema / properties / created_after / description
        Previous value: -"Return merge requests created after the given time"New value: +"Created after"
      • changedInput schema / properties / created_before / description
        Previous value: -"Return merge requests created before the given time"New value: +"Created before"
      • changedInput schema / properties / labels / description
        Previous value: -"Array of label names"New value: +"Label names"
      • changedInput schema / properties / order_by / description
        Previous value: -"Return merge requests ordered by the given field"New value: +"Sort field"
      • changedInput schema / properties / page / description
        Previous value: -"Page number for pagination (default: 1)"New value: +"Page number (default 1)"
      • changedInput schema / properties / per_page / description
        Previous value: -"Number of items per page (max: 100, default: 20)"New value: +"Items per page (max 100, default 20)"
      • changedInput schema / properties / project_id / description
        Previous value: -"Project ID or URL-encoded path (optional - if not provided, lists all merge requests the user has access to)"New value: +"Project ID or URL-encoded path. Omit to list the user's accessible MRs."
      • changedInput schema / properties / reviewer_id / description
        Previous value: -"Returns merge requests which have the user as a reviewer. Must be an integer, 'none', or 'any'. Mutually exclusive with reviewer_username."New value: +"Reviewer user ID, none, or any. Mutually exclusive with reviewer_username."
      • changedInput schema / properties / reviewer_username / description
        Previous value: -"Returns merge requests which have the user as a reviewer by username. Mutually exclusive with reviewer_id."New value: +"Reviewer username. Mutually exclusive with reviewer_id."
      • changedInput schema / properties / scope / description
        Previous value: -"Return merge requests from a specific scope"New value: +"MR scope"
      • changedInput schema / properties / search / description
        Previous value: -"Search for specific terms"New value: +"Search terms"
      • changedInput schema / properties / sort / description
        Previous value: -"Return merge requests sorted in ascending or descending order"New value: +"asc or desc"
      • changedInput schema / properties / source_branch / description
        Previous value: -"Return merge requests from a specific source branch"New value: +"Source branch"
      • changedInput schema / properties / state / description
        Previous value: -"Return merge requests with a specific state"New value: +"MR state"
      • changedInput schema / properties / target_branch / description
        Previous value: -"Return merge requests targeting a specific branch"New value: +"Target branch"
      • changedInput schema / properties / updated_after / description
        Previous value: -"Return merge requests updated after the given time"New value: +"Updated after"
      • changedInput schema / properties / updated_before / description
        Previous value: -"Return merge requests updated before the given time"New value: +"Updated before"
      • changedInput schema / properties / wip / description
        Previous value: -"Filter merge requests against their wip status"New value: +"WIP filter"
      • changedInput schema / properties / with_labels_details / description
        Previous value: -"Return more details for each label"New value: +"Include label details"
    • Changedlist_projects15 fields changed
      • changedInput schema / properties / archived / description
        Previous value: -"Filter for archived projects"New value: +"Archived projects"
      • changedInput schema / properties / membership / description
        Previous value: -"Filter for projects where current user is a member"New value: +"Current user is a member"
      • changedInput schema / properties / min_access_level / description
        Previous value: -"Filter by minimum access level"New value: +"Minimum access level"
      • changedInput schema / properties / order_by / description
        Previous value: -"Return projects ordered by field"New value: +"Sort field"
      • changedInput schema / properties / owned / description
        Previous value: -"Filter for projects owned by current user"New value: +"Owned by current user"
      • changedInput schema / properties / page / description
        Previous value: -"Page number for pagination (default: 1)"New value: +"Page number (default 1)"
      • changedInput schema / properties / per_page / description
        Previous value: -"Number of items per page (max: 100, default: 20)"New value: +"Items per page (max 100, default 20)"
      • changedInput schema / properties / search / description
        Previous value: -"Search term for projects"New value: +"Search term"
      • changedInput schema / properties / search_namespaces / description
        Previous value: -"Needs to be true if search is full path"New value: +"Set true when search is a full path"
      • changedInput schema / properties / simple / description
        Previous value: -"Return only limited fields"New value: +"Limited fields only"
      • changedInput schema / properties / sort / description
        Previous value: -"Return projects sorted in ascending or descending order"New value: +"asc or desc"
      • changedInput schema / properties / topic / description
        Previous value: -"Filter by topic (projects tagged with this topic)"New value: +"Topic tag"
      • changedInput schema / properties / visibility / description
        Previous value: -"Filter by project visibility"New value: +"public, internal, or private"
      • changedInput schema / properties / with_issues_enabled / description
        Previous value: -"Filter projects with issues feature enabled"New value: +"Issues enabled"
      • changedInput schema / properties / with_merge_requests_enabled / description
        Previous value: -"Filter projects with merge requests feature enabled"New value: +"Merge requests enabled"
    • Changedmr_discussions2 fields changed
      • changedInput schema / properties / page / description
        Previous value: -"Page number for pagination (default: 1)"New value: +"Page number (default 1)"
      • changedInput schema / properties / per_page / description
        Previous value: -"Number of items per page (max: 100, default: 20)"New value: +"Items per page (max 100, default 20)"
    • Changedsearch_repositories2 fields changed
      • changedInput schema / properties / page / description
        Previous value: -"Page number for pagination (default: 1)"New value: +"Page number (default 1)"
      • changedInput schema / properties / per_page / description
        Previous value: -"Number of items per page (max: 100, default: 20)"New value: +"Items per page (max 100, default 20)"
    • Changedupdate_issue13 fields changed
      • changedInput schema / properties / assignee_ids / description
        Previous value: -"Array of user IDs to assign issue to"New value: +"Assignee user IDs"
      • changedInput schema / properties / confidential / description
        Previous value: -"Set the issue to be confidential"New value: +"Confidential"
      • changedInput schema / properties / description / description
        Previous value: -"The description of the issue"New value: +"Issue description"
      • changedInput schema / properties / discussion_locked / description
        Previous value: -"Flag to lock discussions"New value: +"Lock discussions"
      • changedInput schema / properties / due_date / description
        Previous value: -"Date the issue is due (YYYY-MM-DD)"New value: +"Due date (YYYY-MM-DD)"
      • changedInput schema / properties / full_response / description
        Previous value: -"If true, return the complete updated issue object. Default returns a slim confirmation (iid, title, state, web_url, updated_at) to reduce token usage."New value: +"If true, return the complete updated issue. Default is slim (iid, title, state, web_url, updated_at)."
      • changedInput schema / properties / issue_iid / description
        Previous value: -"The internal ID of the project issue"New value: +"Issue IID"
      • changedInput schema / properties / issue_type / description
        Previous value: -"The type of issue. One of issue, incident, test_case or task."New value: +"issue, incident, test_case, or task"
      • changedInput schema / properties / labels / description
        Previous value: -"Array of label names"New value: +"Label names"
      • changedInput schema / properties / milestone_id / description
        Previous value: -"Milestone ID to assign"New value: +"Milestone ID"
      • changedInput schema / properties / state_event / description
        Previous value: -"Update issue state (close/reopen)"New value: +"close or reopen"
      • changedInput schema / properties / title / description
        Previous value: -"The title of the issue"New value: +"Issue title"
      • changedInput schema / properties / weight / description
        Previous value: -"Weight of the issue (numeric, typically hours of work)"New value: +"Issue weight"
    • Changedupdate_merge_request13 fields changed
      • changedInput schema / properties / assignee_ids / description
        Previous value: -"The ID of the users to assign the MR to"New value: +"Assignee user IDs"
      • changedInput schema / properties / description / description
        Previous value: -"The description of the merge request"New value: +"MR description"
      • changedInput schema / properties / draft / description
        Previous value: -"Work in progress merge request"New value: +"Draft / WIP"
      • changedInput schema / properties / labels / description
        Previous value: -"Labels for the MR"New value: +"MR labels"
      • changedInput schema / properties / merge_request_iid / description
        Previous value: -"The IID of a merge request"New value: +"Merge request IID"
      • changedInput schema / properties / milestone_id / description
        Previous value: -"Milestone ID to assign. Set to 0 to unassign. Null is treated as omitted."New value: +"Milestone ID. 0 unassigns. Null is omitted."
      • changedInput schema / properties / project_id / description
        Previous value: -"Project ID or complete URL-encoded path to project"New value: +"Project ID or URL-encoded path"
      • changedInput schema / properties / remove_source_branch / description
        Previous value: -"Flag indicating if the source branch should be removed"New value: +"Remove source branch on merge"
      • changedInput schema / properties / reviewer_ids / description
        Previous value: -"The ID of the users to assign as reviewers of the MR"New value: +"Reviewer user IDs"
      • changedInput schema / properties / squash / description
        Previous value: -"Squash commits into a single commit when merging"New value: +"Squash commits on merge"
      • changedInput schema / properties / state_event / description
        Previous value: -"New state (close/reopen) for the MR"New value: +"close or reopen"
      • changedInput schema / properties / target_branch / description
        Previous value: -"The target branch"New value: +"Target branch"
      • changedInput schema / properties / title / description
        Previous value: -"The title of the merge request"New value: +"MR title"
  2. 12 tool updatesv2.3.8
    • Addedhelp
    • Changedlist_branches1 field changed
      • addedInput schema / properties / summary
        Added value: +{
        +  "description": "If true, return only high-signal fields (id, iid, title, state, web_url, …). Default false keeps the full GitLab JSON.",
        +  "type": "boolean"
        +}
    • Changedlist_commits1 field changed
      • addedInput schema / properties / summary
        Added value: +{
        +  "description": "If true, return only high-signal fields (id, iid, title, state, web_url, …). Default false keeps the full GitLab JSON.",
        +  "type": "boolean"
        +}
    • Changedlist_issue_discussions1 field changed
      • addedInput schema / properties / summary
        Added value: +{
        +  "description": "If true, return only high-signal fields (id, iid, title, state, web_url, …). Default false keeps the full GitLab JSON.",
        +  "type": "boolean"
        +}
    • Changedlist_issues1 field changed
      • addedInput schema / properties / summary
        Added value: +{
        +  "description": "If true, return only high-signal fields (id, iid, title, state, web_url, …). Default false keeps the full GitLab JSON.",
        +  "type": "boolean"
        +}
    • Changedlist_labels1 field changed
      • addedInput schema / properties / summary
        Added value: +{
        +  "description": "If true, return only high-signal fields (id, iid, title, state, web_url, …). Default false keeps the full GitLab JSON.",
        +  "type": "boolean"
        +}
    • Changedlist_merge_request_changed_files1 field changed
      • addedInput schema / properties / summary
        Added value: +{
        +  "description": "If true, return only high-signal fields (id, iid, title, state, web_url, …). Default false keeps the full GitLab JSON.",
        +  "type": "boolean"
        +}
    • Changedlist_merge_request_diffs1 field changed
      • addedInput schema / properties / summary
        Added value: +{
        +  "description": "If true, return only high-signal fields (id, iid, title, state, web_url, …). Default false keeps the full GitLab JSON.",
        +  "type": "boolean"
        +}
    • Changedlist_merge_requests1 field changed
      • addedInput schema / properties / summary
        Added value: +{
        +  "description": "If true, return only high-signal fields (id, iid, title, state, web_url, …). Default false keeps the full GitLab JSON.",
        +  "type": "boolean"
        +}
    • Changedlist_project_members1 field changed
      • addedInput schema / properties / summary
        Added value: +{
        +  "description": "If true, return only high-signal fields (id, iid, title, state, web_url, …). Default false keeps the full GitLab JSON.",
        +  "type": "boolean"
        +}
    • Changedlist_projects1 field changed
      • addedInput schema / properties / summary
        Added value: +{
        +  "description": "If true, return only high-signal fields (id, iid, title, state, web_url, …). Default false keeps the full GitLab JSON.",
        +  "type": "boolean"
        +}
    • Changedmr_discussions1 field changed
      • addedInput schema / properties / summary
        Added value: +{
        +  "description": "If true, return only high-signal fields (id, iid, title, state, web_url, …). Default false keeps the full GitLab JSON.",
        +  "type": "boolean"
        +}
  3. 80 tool updatesv2.2.6
    • Removedapprove_merge_request
    • Removedbulk_publish_draft_notes
    • Removedcreate_branch
    • Removedcreate_commit_status
    • Removedcreate_draft_note
    • Removedcreate_group
    • Removedcreate_issue_emoji_reaction
    • Removedcreate_issue_link
    • Removedcreate_issue_note_emoji_reaction
    • Removedcreate_label
    • Removedcreate_merge_request_discussion_note
    • Removedcreate_merge_request_emoji_reaction
    • Removedcreate_merge_request_note
    • Removedcreate_merge_request_note_emoji_reaction
    • Removedcreate_note
    • Removedcreate_or_update_file
    • Removedcreate_repository
    • Removeddelete_branch
    • Removeddelete_draft_note
    • Removeddelete_issue
    • Removeddelete_issue_emoji_reaction
    • Removeddelete_issue_link
    • Removeddelete_issue_note_emoji_reaction
    • Removeddelete_label
    • Removeddelete_merge_request_discussion_note
    • Removeddelete_merge_request_emoji_reaction
    • Removeddelete_merge_request_note
    • Removeddelete_merge_request_note_emoji_reaction
    • Removeddownload_attachment
    • Removedfork_repository
    • Removedget_branch_diffs
    • Removedget_ci_catalog_resource
    • Removedget_draft_note
    • Changedget_issue1 field changed
      • changedInput schema / properties / full_response / description
        Previous value: -"If true, return the complete issue object including the full milestone description. Default returns a slim milestone (id, iid, title, state, web_url) to reduce token usage."New value: +"If true, include the complete milestone object, including its description, on the returned issue. Default returns the issue with a slim milestone (id, iid, title, state, web_url) to reduce token usage."
    • Removedget_issue_link
    • Removedget_label
    • Removedget_merge_request_conflicts
    • Removedget_merge_request_version
    • Removedget_namespace
    • Removedget_project_events
    • Removedget_protected_branch
    • Removedget_user
    • Removedget_users
    • Removedlist_ci_catalog_resources
    • Removedlist_commit_statuses
    • Removedlist_draft_notes
    • Removedlist_events
    • Removedlist_group_iterations
    • Removedlist_group_members
    • Removedlist_group_merge_requests
    • Removedlist_group_projects
    • Removedlist_issue_emoji_reactions
    • Removedlist_issue_links
    • Removedlist_issue_note_emoji_reactions
    • Removedlist_merge_request_emoji_reactions
    • Removedlist_merge_request_note_emoji_reactions
    • Removedlist_merge_request_pipelines
    • Removedlist_merge_request_versions
    • Removedlist_namespaces
    • Removedlist_protected_branches
    • Removedlist_todos
    • Removedmark_all_todos_done
    • Removedmark_todo_done
    • Removedmerge_merge_request
    • Removedprotect_branch
    • Removedpublish_draft_note
    • Removedpush_files
    • Removedunapprove_merge_request
    • Removedunprotect_branch
    • Removedupdate_default_branch
    • Removedupdate_draft_note
    • Removedupdate_issue_note
    • Removedupdate_label
    • Removedupdate_merge_request_discussion_note
    • Removedupdate_merge_request_note
    • Removedupdate_project
    • Removedupload_markdown
    • Removedvalidate_ci_lint
    • Removedvalidate_project_ci_lint
    • Removedverify_namespace
  4. 118 tool updatesv2.1.66
    • Changedapprove_merge_request1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedbulk_publish_draft_notes1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedcreate_branch1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedcreate_commit_status1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedcreate_draft_note1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedcreate_group1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedcreate_issue1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedcreate_issue_emoji_reaction1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedcreate_issue_link1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedcreate_issue_note1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedcreate_issue_note_emoji_reaction1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedcreate_label1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedcreate_merge_request1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedcreate_merge_request_discussion_note1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedcreate_merge_request_emoji_reaction1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedcreate_merge_request_note1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedcreate_merge_request_note_emoji_reaction1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedcreate_merge_request_thread1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedcreate_note1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedcreate_or_update_file1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedcreate_repository1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changeddelete_branch1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changeddelete_draft_note1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changeddelete_issue1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changeddelete_issue_emoji_reaction1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changeddelete_issue_link1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changeddelete_issue_note_emoji_reaction1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changeddelete_label1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changeddelete_merge_request_discussion_note1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changeddelete_merge_request_emoji_reaction1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changeddelete_merge_request_note1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changeddelete_merge_request_note_emoji_reaction1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changeddiscover_tools1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changeddownload_attachment1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedfork_repository1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedget_branch1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedget_branch_diffs1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedget_ci_catalog_resource1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedget_commit1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedget_commit_diff1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedget_draft_note1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedget_file_blame1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedget_file_contents1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedget_issue1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedget_issue_link1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedget_label1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedget_merge_request1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedget_merge_request_approval_state1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedget_merge_request_conflicts1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedget_merge_request_diffs1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedget_merge_request_discussion1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedget_merge_request_file_diff1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedget_merge_request_note1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedget_merge_request_notes1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedget_merge_request_version1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedget_namespace1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedget_project1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedget_project_events1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedget_protected_branch1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedget_repository_tree1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedget_user1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedget_users1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedhealth_check1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedlist_branches1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedlist_ci_catalog_resources1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedlist_commit_statuses1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedlist_commits1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedlist_draft_notes1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedlist_events1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedlist_group_iterations1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedlist_group_members1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedlist_group_merge_requests1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedlist_group_projects1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedlist_issue_discussions1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedlist_issue_emoji_reactions1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedlist_issue_links1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedlist_issue_note_emoji_reactions1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedlist_issues1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedlist_labels1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedlist_merge_request_changed_files1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedlist_merge_request_diffs1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedlist_merge_request_emoji_reactions1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedlist_merge_request_note_emoji_reactions1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedlist_merge_request_pipelines1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedlist_merge_request_versions1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedlist_merge_requests1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedlist_namespaces1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedlist_project_members1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedlist_projects1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedlist_protected_branches1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedlist_todos1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedmark_all_todos_done1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedmark_todo_done1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedmerge_merge_request1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedmr_discussions1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedmy_issues1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedprotect_branch1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedpublish_draft_note1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedpush_files1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedresolve_merge_request_thread1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedsearch_repositories1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedunapprove_merge_request1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedunprotect_branch1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedupdate_default_branch1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedupdate_draft_note1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedupdate_issue1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedupdate_issue_description_patch1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedupdate_issue_note1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedupdate_label1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedupdate_merge_request1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedupdate_merge_request_discussion_note1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedupdate_merge_request_note1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedupdate_project1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedupload_markdown1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedvalidate_ci_lint1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedvalidate_project_ci_lint1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedverify_namespace1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
    • Changedwhoami1 field changed
      • addedInput schema / properties / jmespath
        Added value: +{
        +  "description": "Optional JMESPath expression filtering the JSON result before return.",
        +  "type": "string"
        +}
  5. 1 tool updatev2.1.63
    • Addedget_merge_request_discussion
  6. 37 tool updatesv2.1.62
    • Changedcreate_branch1 field changed
      • changedInput schema / required
        Previous value: -[
        -  "branch",
        -  "project_id"
        -]New value: +[
        +  "project_id",
        +  "branch"
        +]
    • Changedcreate_commit_status1 field changed
      • changedInput schema / required
        Previous value: -[
        -  "sha",
        -  "state",
        -  "project_id"
        -]New value: +[
        +  "project_id",
        +  "sha",
        +  "state"
        +]
    • Changedcreate_draft_note1 field changed
      • changedInput schema / required
        Previous value: -[
        -  "body",
        -  "project_id",
        -  "merge_request_iid"
        -]New value: +[
        +  "project_id",
        +  "merge_request_iid",
        +  "body"
        +]
    • Changedcreate_issue1 field changed
      • changedInput schema / required
        Previous value: -[
        -  "title",
        -  "project_id"
        -]New value: +[
        +  "project_id",
        +  "title"
        +]
    • Changedcreate_issue_emoji_reaction1 field changed
      • changedInput schema / required
        Previous value: -[
        -  "name",
        -  "project_id",
        -  "issue_iid"
        -]New value: +[
        +  "project_id",
        +  "issue_iid",
        +  "name"
        +]
    • Changedcreate_issue_note1 field changed
      • changedInput schema / required
        Previous value: -[
        -  "body",
        -  "project_id",
        -  "issue_iid"
        -]New value: +[
        +  "project_id",
        +  "issue_iid",
        +  "body"
        +]
    • Changedcreate_issue_note_emoji_reaction1 field changed
      • changedInput schema / required
        Previous value: -[
        -  "name",
        -  "project_id",
        -  "issue_iid",
        -  "note_id"
        -]New value: +[
        +  "project_id",
        +  "issue_iid",
        +  "note_id",
        +  "name"
        +]
    • Changedcreate_label1 field changed
      • changedInput schema / required
        Previous value: -[
        -  "name",
        -  "color",
        -  "project_id"
        -]New value: +[
        +  "project_id",
        +  "name",
        +  "color"
        +]
    • Changedcreate_merge_request1 field changed
      • changedInput schema / required
        Previous value: -[
        -  "title",
        -  "source_branch",
        -  "target_branch",
        -  "project_id"
        -]New value: +[
        +  "project_id",
        +  "title",
        +  "source_branch",
        +  "target_branch"
        +]
    • Changedcreate_merge_request_discussion_note1 field changed
      • changedInput schema / required
        Previous value: -[
        -  "body",
        -  "project_id",
        -  "merge_request_iid",
        -  "discussion_id"
        -]New value: +[
        +  "project_id",
        +  "merge_request_iid",
        +  "discussion_id",
        +  "body"
        +]
    • Changedcreate_merge_request_emoji_reaction1 field changed
      • changedInput schema / required
        Previous value: -[
        -  "name",
        -  "project_id",
        -  "merge_request_iid"
        -]New value: +[
        +  "project_id",
        +  "merge_request_iid",
        +  "name"
        +]
    • Changedcreate_merge_request_note1 field changed
      • changedInput schema / required
        Previous value: -[
        -  "body",
        -  "project_id",
        -  "merge_request_iid"
        -]New value: +[
        +  "project_id",
        +  "merge_request_iid",
        +  "body"
        +]
    • Changedcreate_merge_request_note_emoji_reaction1 field changed
      • changedInput schema / required
        Previous value: -[
        -  "name",
        -  "project_id",
        -  "merge_request_iid",
        -  "note_id"
        -]New value: +[
        +  "project_id",
        +  "merge_request_iid",
        +  "note_id",
        +  "name"
        +]
    • Changedcreate_merge_request_thread1 field changed
      • changedInput schema / required
        Previous value: -[
        -  "body",
        -  "project_id",
        -  "merge_request_iid"
        -]New value: +[
        +  "project_id",
        +  "merge_request_iid",
        +  "body"
        +]
    • Changedcreate_note1 field changed
      • changedInput schema / required
        Previous value: -[
        -  "noteable_type",
        -  "body",
        -  "project_id",
        -  "noteable_iid"
        -]New value: +[
        +  "project_id",
        +  "noteable_type",
        +  "noteable_iid",
        +  "body"
        +]
    • Changedcreate_or_update_file1 field changed
      • changedInput schema / required
        Previous value: -[
        -  "file_path",
        -  "content",
        -  "commit_message",
        -  "branch",
        -  "project_id"
        -]New value: +[
        +  "project_id",
        +  "file_path",
        +  "content",
        +  "commit_message",
        +  "branch"
        +]
    • Changedcreate_repository1 field changed
      • addedInput schema / properties / namespace_id / maximum
        Added value: +9007199254740991
    • Changeddelete_branch1 field changed
      • changedInput schema / required
        Previous value: -[
        -  "branch_name",
        -  "project_id"
        -]New value: +[
        +  "project_id",
        +  "branch_name"
        +]
    • Changedget_branch1 field changed
      • changedInput schema / required
        Previous value: -[
        -  "branch_name",
        -  "project_id"
        -]New value: +[
        +  "project_id",
        +  "branch_name"
        +]
    • Changedget_branch_diffs1 field changed
      • changedInput schema / required
        Previous value: -[
        -  "from",
        -  "to",
        -  "project_id"
        -]New value: +[
        +  "project_id",
        +  "from",
        +  "to"
        +]
    • Changedget_commit1 field changed
      • changedInput schema / required
        Previous value: -[
        -  "sha",
        -  "project_id"
        -]New value: +[
        +  "project_id",
        +  "sha"
        +]
    • Changedget_commit_diff1 field changed
      • changedInput schema / required
        Previous value: -[
        -  "sha",
        -  "project_id"
        -]New value: +[
        +  "project_id",
        +  "sha"
        +]
    • Changedget_file_blame5 fields changed
      • addedInput schema / properties / range_end / maximum
        Added value: +9007199254740991
      • addedInput schema / properties / range_end / minimum
        Added value: +-9007199254740991
      • addedInput schema / properties / range_start / maximum
        Added value: +9007199254740991
      • addedInput schema / properties / range_start / minimum
        Added value: +-9007199254740991
      • changedInput schema / required
        Previous value: -[
        -  "file_path",
        -  "ref"
        -]New value: +[
        +  "project_id",
        +  "file_path",
        +  "ref"
        +]
    • Changedget_protected_branch1 field changed
      • changedInput schema / required
        Previous value: -[
        -  "branch_name",
        -  "project_id"
        -]New value: +[
        +  "project_id",
        +  "branch_name"
        +]
    • Changedlist_commit_statuses1 field changed
      • changedInput schema / required
        Previous value: -[
        -  "sha",
        -  "project_id"
        -]New value: +[
        +  "project_id",
        +  "sha"
        +]
    • Changedlist_merge_request_pipelines1 field changed
      • changedInput schema / required
        Previous value: -[
        -  "merge_request_iid",
        -  "project_id"
        -]New value: +[
        +  "project_id",
        +  "merge_request_iid"
        +]
    • Changedprotect_branch7 fields changed
      • addedInput schema / properties / merge_access_level / maximum
        Added value: +9007199254740991
      • addedInput schema / properties / merge_access_level / minimum
        Added value: +-9007199254740991
      • addedInput schema / properties / push_access_level / maximum
        Added value: +9007199254740991
      • addedInput schema / properties / push_access_level / minimum
        Added value: +-9007199254740991
      • addedInput schema / properties / unprotect_access_level / maximum
        Added value: +9007199254740991
      • addedInput schema / properties / unprotect_access_level / minimum
        Added value: +-9007199254740991
      • changedInput schema / required
        Previous value: -[
        -  "branch_name"
        -]New value: +[
        +  "project_id",
        +  "branch_name"
        +]
    • Changedpush_files2 fields changed
      • removedInput schema / properties / files / items / additionalProperties
        Removed value: -false
      • changedInput schema / required
        Previous value: -[
        -  "branch",
        -  "files",
        -  "commit_message",
        -  "project_id"
        -]New value: +[
        +  "project_id",
        +  "branch",
        +  "files",
        +  "commit_message"
        +]
    • Changedunprotect_branch1 field changed
      • changedInput schema / required
        Previous value: -[
        -  "branch_name",
        -  "project_id"
        -]New value: +[
        +  "project_id",
        +  "branch_name"
        +]
    • Changedupdate_default_branch1 field changed
      • changedInput schema / required
        Previous value: -[
        -  "default_branch",
        -  "project_id"
        -]New value: +[
        +  "project_id",
        +  "default_branch"
        +]
    • Changedupdate_issue_description_patch1 field changed
      • changedInput schema / required
        Previous value: -[
        -  "patch_type",
        -  "patch",
        -  "project_id",
        -  "issue_iid"
        -]New value: +[
        +  "project_id",
        +  "issue_iid",
        +  "patch_type",
        +  "patch"
        +]
    • Changedupdate_issue_note1 field changed
      • addedInput schema / required
        Added value: +[
        +  "project_id",
        +  "issue_iid",
        +  "discussion_id",
        +  "note_id"
        +]
    • Changedupdate_merge_request_discussion_note1 field changed
      • addedInput schema / required
        Added value: +[
        +  "project_id",
        +  "merge_request_iid",
        +  "discussion_id",
        +  "note_id"
        +]
    • Changedupdate_merge_request_note1 field changed
      • changedInput schema / required
        Previous value: -[
        -  "body",
        -  "project_id",
        -  "merge_request_iid",
        -  "note_id"
        -]New value: +[
        +  "project_id",
        +  "merge_request_iid",
        +  "note_id",
        +  "body"
        +]
    • Changedupdate_project1 field changed
      • addedInput schema / required
        Added value: +[
        +  "project_id"
        +]
    • Changedvalidate_ci_lint1 field changed
      • changedInput schema / required
        Previous value: -[
        -  "content",
        -  "project_id"
        -]New value: +[
        +  "project_id",
        +  "content"
        +]
    • Changedverify_namespace2 fields changed
      • addedInput schema / properties / parent_id / maximum
        Added value: +9007199254740991
      • addedInput schema / properties / parent_id / minimum
        Added value: +-9007199254740991

TDQS

B3.2/5.0

Scored across 40 tools

Disambiguation3/5

Most tools target distinct resources, but the merge request surface has several closely related note, discussion, and diff tools (e.g., get_merge_request_discussion vs get_merge_request_note vs mr_discussions, and list_merge_request_diffs vs get_merge_request_diffs vs get_merge_request_file_diff). Descriptions provide 'use X instead' guidance, but an agent still has meaningful risk of selecting the wrong granularity.

Naming Consistency4/5

The majority of tools follow a predictable verb_noun snake_case pattern (list_issues, get_merge_request, create_issue). There are notable deviations like mr_discussions, my_issues, whoami, help, and health_check, but these are limited and still readable.

Tool Count2/5

At 40 tools, the surface is heavy for a single MCP server and includes very granular merge request diff/note variants. While GitLab is a broad domain, the presence of discover_tools implies these should be split into toolsets rather than loaded all at once.

Completeness2/5

Core GitLab workflows are only partially covered: branch creation/deletion, MR merge/approve, label management, and user lookup tools are missing, even though related tools reference them (e.g., get_user, approve_merge_request, update_merge_request_discussion_note). Agents will hit dead ends for common write operations.

Maintenance

ActivityActive
ResponsivenessSyncing

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    A
    maintenance
    MCP server for GitLab CI/CD — pipelines, jobs, schedules, branches, tags, merge requests and repository files. Works with any GitLab (SaaS gitlab.com or self-hosted) via python-gitlab.
    24
    316 PyPI
    2
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    MCP server for interacting with GitLab API, supporting both self-hosted instances and gitlab.com. Provides tools for managing issues, merge requests, code review, pipelines, milestones, releases, search, and file access.
    345 npm
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Model Context Protocol (MCP) server for GitLab — exposes 1006 GitLab REST & GraphQL API operations as MCP tools (42 meta-tools / 57 enterprise), 24 resources, 38 prompts, and 17 completion types for AI assistants. Written in Go, single static binary, stdio and HTTP transport.
    2
    46
    MIT