Public log

@zereight/mcp-gitlab

GitLab MCP server for projects, merge requests, issues, pipelines, wiki, releases, and more

npm · fingerprint 019e21dba70332b4dfc881e2 · repository · RSS

40tools
8recorded versions
58dtracked
changed 5d ago

What changed

Changed 2026-10-25 11:07 UTC

38 descriptions rewritten, 1 tool added.

--- pinned/create_issue
+++ observed/create_issue
  {
    "annotations": {
      "openWorldHint": true
-   "description": "Create a new issue. Use this to open a new issue; use `update_issue` for an existing issue and `create_issue_note` to add discussion without changing issue fields. The operation creates remote project data, requires issue creation permission, and returns the new issue or a validation, permission, or duplicate-related error.",
+   "description": "Create a new issue. Open a new issue. Use `update_issue` for an existing issue and `create_issue_note` for discussion.",
    "inputSchema": {
      "properties": {
        "assignee_ids": {
--- pinned/create_issue_note
+++ observed/create_issue_note
  {
    "annotations": {
      "openWorldHint": true
-   "description": "Add a note to an issue, optionally replying to a discussion thread. Use this to add a note to an existing issue, optionally as a reply to a discussion; use `update_issue` for issue fields and `create_note` only when the generic endpoint is required. The operation creates remote discussion content, requires note permission, and returns the note or a missing-issue/thread/permission error.",
+   "description": "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.",
    "inputSchema": {
      "properties": {
        "body": {
--- pinned/create_merge_request
+++ observed/create_merge_request
  {
    "annotations": {
      "openWorldHint": true
-   "description": "Create a new merge request. Use this to open a new merge request from an existing source branch to a target branch; use `update_merge_request` after it exists. The operation creates remote review state, requires project access, and returns the new merge request or a validation, permission, branch, or duplicate-related error.",
+   "description": "Create a new merge request. Open a merge request from an existing source branch to a target. Use `update_merge_request` after it exists.",
    "inputSchema": {
      "properties": {
        "allow_collaboration": {
--- pinned/create_merge_request_thread
+++ observed/create_merge_request_thread
  {
    "annotations": {
      "openWorldHint": true
-   "description": "Create a new thread on a merge request. Use this to start a review thread on a merge request; use `create_merge_request_note` for an unthreaded note and `create_merge_request_discussion_note` to reply to an existing thread. The operation creates remote review content, requires note permission, and returns the discussion or a position/permission/validation error.",
+   "description": "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.",
    "inputSchema": {
      "properties": {
        "body": {
--- pinned/discover_tools
+++ observed/discover_tools
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "Discover and activate additional tool categories for this session. Available 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. Already-active categories are listed in the response. Explicit-only toolsets are omitted; list them in GITLAB_TOOLSETS. Use this when a needed opt-in category is not currently exposed; omit `category` to inspect available categories, then call it with a category to activate that group for the current session. It changes only the session's tool registry, returns the active-tool summary, and does not change GitLab data.",
+   "description": "Discover and activate additional tool categories for this session. Available 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. Already-active categories are listed in the response. Explicit-only toolsets are omitted; list them in GITLAB_TOOLSETS.",
    "inputSchema": {
      "properties": {
        "category": {
--- pinned/get_branch
+++ observed/get_branch
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "Get branch details (commit, protection status). To find resources, use the matching list or search tool. Read-only; missing resources, denied access, and rate limits return errors. `project_id`/`group_id` take a numeric ID or URL-encoded path.",
+   "description": "Get branch details (commit, protection status). To find resources, use the matching list or search tool.",
    "inputSchema": {
      "properties": {
        "branch_name": {
--- pinned/get_commit
+++ observed/get_commit
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "Get details of a specific commit. To find resources, use the matching list or search tool. Read-only; missing resources, denied access, and rate limits return errors. `project_id`/`group_id` take a numeric ID or URL-encoded path.",
+   "description": "Get details of a specific commit. To find resources, use the matching list or search tool.",
    "inputSchema": {
      "properties": {
        "jmespath": {
--- pinned/get_commit_diff
+++ observed/get_commit_diff
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "Get changes/diffs of a specific commit. Read-only; missing resources, denied access, and rate limits return errors. `project_id`/`group_id` take a numeric ID or URL-encoded path.",
+   "description": "Get changes/diffs of a specific commit. Return the file diffs for one commit. Use `get_commit` for metadata without the patch.",
    "inputSchema": {
      "properties": {
        "full_diff": {
--- pinned/get_file_contents
+++ observed/get_file_contents
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "Get contents of a file or directory from a GitLab project. Read-only; missing resources, denied access, and rate limits return errors. `project_id`/`group_id` take a numeric ID or URL-encoded path.",
+   "description": "Get contents of a file or directory from a GitLab project.",
    "inputSchema": {
      "properties": {
        "file_path": {
--- pinned/get_issue
+++ observed/get_issue
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "Get details of a specific issue. Returns the issue with a slim nested milestone by default; set full_response=true for the complete milestone object. Use this for issue management: inspect one issue's fields; use `list_issues` or `my_issues` to discover issues first. It is read-only, requires issue read permission, and returns the issue or an error when the identifier is invalid, the issue is missing, or access is denied.",
+   "description": "Get details of a specific issue. Returns the issue with a slim nested milestone by default; set full_response=true for the complete milestone object. Use this for issue management: inspect one issue. Use `list_issues` or `my_issues` to discover issues first.",
    "inputSchema": {
      "properties": {
        "full_response": {
--- pinned/get_merge_request
+++ observed/get_merge_request
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "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. Read-only; missing resources, denied access, and rate limits return errors. `project_id`/`group_id` take a numeric ID or URL-encoded path.",
+   "description": "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.",
    "inputSchema": {
      "properties": {
        "include_summaries": {
--- pinned/get_merge_request_approval_state
+++ observed/get_merge_request_approval_state
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "Get merge request approval details including approvers. Use this to inspect approval rules and approvers before deciding whether a merge request can be merged; use `approve_merge_request` to change approval state. It is read-only and returns the approval-state response, while missing requests, unsupported GitLab versions, and permission failures are reported as errors.",
+   "description": "Get merge request approval details including approvers. Inspect approval rules and approvers before merging. Use `approve_merge_request` to change approval state.",
    "inputSchema": {
      "properties": {
        "jmespath": {
--- pinned/get_merge_request_diffs
+++ observed/get_merge_request_diffs
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "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. Read-only; missing resources, denied access, and rate limits return errors. `project_id`/`group_id` take a numeric ID or URL-encoded path.",
+   "description": "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.",
    "inputSchema": {
      "properties": {
        "excluded_file_patterns": {
--- pinned/get_merge_request_discussion
+++ observed/get_merge_request_discussion
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "Get a single discussion item for a merge request. Use this to fetch one known merge request discussion by discussion identifier; use `mr_discussions` for a collection and `get_merge_request_note` for a flat note. It is read-only and returns the discussion item or an error for an invalid identifier, missing discussion, or insufficient permission.",
+   "description": "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.",
    "inputSchema": {
      "properties": {
        "discussion_id": {
--- pinned/get_merge_request_file_diff
+++ observed/get_merge_request_file_diff
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "Get diffs for specific files from a merge request (merge_request_iid or source_branch required). Read-only; missing resources, denied access, and rate limits return errors. `project_id`/`group_id` take a numeric ID or URL-encoded path.",
+   "description": "Get diffs for specific files from a merge request (merge_request_iid or source_branch required).",
    "inputSchema": {
      "properties": {
        "file_paths": {
--- pinned/get_merge_request_note
+++ observed/get_merge_request_note
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "Get a specific note for a merge request. Use this to fetch one known merge request note by note identifier; use `get_merge_request_notes` for a collection and `mr_discussions` for threaded context. It is read-only and returns the note object or an error for an invalid identifier, missing note, or insufficient permission.",
+   "description": "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.",
    "inputSchema": {
      "properties": {
        "jmespath": {
--- pinned/get_merge_request_notes
+++ observed/get_merge_request_notes
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "List notes for a merge request. Use this to list flat notes on a merge request; use `mr_discussions` when thread structure and resolution state are required. It is read-only and returns note records, while invalid identifiers, missing resources, and pagination or permission errors are reported by GitLab.",
+   "description": "List notes for a merge request. List flat notes. Use `mr_discussions` when thread structure and resolution state are required.",
    "inputSchema": {
      "properties": {
        "jmespath": {
--- pinned/get_project
+++ observed/get_project
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "Get details of a specific project. To find resources, use the matching list or search tool. Read-only; missing resources, denied access, and rate limits return errors. `project_id`/`group_id` take a numeric ID or URL-encoded path.",
+   "description": "Get details of a specific project. To find resources, use the matching list or search tool.",
    "inputSchema": {
      "properties": {
        "jmespath": {
--- pinned/get_repository_tree
+++ observed/get_repository_tree
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "List files and directories in a repository. Read-only; missing resources, denied access, and rate limits return errors. `project_id`/`group_id` take a numeric ID or URL-encoded path.",
+   "description": "List files and directories in a repository.",
    "inputSchema": {
      "properties": {
        "jmespath": {
--- pinned/health_check
+++ observed/health_check
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "Verify server status and authentication. Always reports the MCP server version (mcp_server_version). When authenticated, also reports the GitLab instance version from GET /api/v4/version (version, revision, enterprise). Version lookup failures do not fail the health check — those fields are omitted. Use this to verify server connectivity and authentication before making GitLab requests; use `whoami` when the authenticated user's identity is the goal. A 403 from GET /user with an insufficient_scope error means the token is accepted but User API scope is missing (read_user or fine-grained User:Read); the check stays ok, sets user_api_warning, and omits version metadata. Rate-limit and authentication-ban 403 responses stay unauthenticated. It does not mutate GitLab state and returns server/authentication status plus GitLab version details when available. Connection failures with no HTTP response return status error, authenticated false, and an error object (kind tls, dns, timeout, or network, plus code and message) instead of a protocol error.",
+   "description": "Verify server status and authentication. Always reports the MCP server version (mcp_server_version). When authenticated, also reports the GitLab instance version from GET /api/v4/version (version, revision, enterprise). Version lookup failures do not fail the health check — those fields are omitted.",
    "inputSchema": {
      "properties": {
        "jmespath": {

+ tool added: help

--- pinned/list_branches
+++ observed/list_branches
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "List branches in project with search filter. For one known resource, use the matching get tool. Read-only; missing resources, denied access, and rate limits return errors. `project_id`/`group_id` take a numeric ID or URL-encoded path.",
+   "description": "List branches in project with search filter. For one known resource, use the matching get tool.",
    "inputSchema": {
      "properties": {
        "jmespath": {
+       },
+       "summary": {
+         "description": "If true, return only high-signal fields (id, iid, title, state, web_url, …). Default false keeps the full GitLab JSON.",
+         "type": "boolean"
        }
      },
      "required": [
--- pinned/list_commits
+++ observed/list_commits
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "List repository commits with filtering options. For one known resource, use the matching get tool. Read-only; missing resources, denied access, and rate limits return errors. `project_id`/`group_id` take a numeric ID or URL-encoded path.",
+   "description": "List repository commits with filtering options. For one known resource, use the matching get tool.",
    "inputSchema": {
      "properties": {
        "all": {
+       "summary": {
+         "description": "If true, return only high-signal fields (id, iid, title, state, web_url, …). Default false keeps the full GitLab JSON.",
+         "type": "boolean"
+       },
        "trailers": {
          "description": "Parse and include Git trailers for every commit",
          "type": "boolean"
--- pinned/list_issue_discussions
+++ observed/list_issue_discussions
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "List discussions for an issue. Use this to inspect threaded discussions for an issue; use `list_issues` for issue records and `get_issue` for one issue's fields. It is read-only and returns discussion items, while invalid identifiers, missing issues, and permission failures are reported as errors.",
+   "description": "List discussions for an issue. List threaded discussions for an issue. Use `list_issues` or `get_issue` for issue records.",
    "inputSchema": {
      "properties": {
        "issue_iid": {
+       },
+       "summary": {
+         "description": "If true, return only high-signal fields (id, iid, title, state, web_url, …). Default false keeps the full GitLab JSON.",
+         "type": "boolean"
        }
      },
      "required": [
--- pinned/list_issues
+++ observed/list_issues
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "List issues (default: created by current user; use scope='all' for all). Use this for issue management: list GitLab issues, optionally scoped with `project_id`. Use `get_issue` when the issue iid is already known and `my_issues` for issues assigned to the current user. It is read-only and paginated, requires issue read permission, and returns issue records or GitLab errors for invalid identifiers, missing resources, or rate limits.",
+   "description": "List issues (default: created by current user; use scope='all' for all). Use this for issue management: list GitLab issues, optionally scoped with `project_id`. Use `get_issue` when the iid is known and `my_issues` for the current user's assignments.",
    "inputSchema": {
      "properties": {
        "assignee_id": {
+       "summary": {
+         "description": "If true, return only high-signal fields (id, iid, title, state, web_url, …). Default false keeps the full GitLab JSON.",
+         "type": "boolean"
+       },
        "updated_after": {
          "description": "Return issues updated after the given time",
          "type": "string"
--- pinned/list_labels
+++ observed/list_labels
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "List labels for a project. For one known resource, use the matching get tool. Read-only; missing resources, denied access, and rate limits return errors. `project_id`/`group_id` take a numeric ID or URL-encoded path.",
+   "description": "List labels for a project. For one known resource, use the matching get tool.",
    "inputSchema": {
      "properties": {
        "include_ancestor_groups": {
+       "summary": {
+         "description": "If true, return only high-signal fields (id, iid, title, state, web_url, …). Default false keeps the full GitLab JSON.",
+         "type": "boolean"
+       },
        "with_counts": {
          "description": "Whether to include issue and merge request counts",
          "type": "boolean"
--- pinned/list_merge_request_changed_files
+++ observed/list_merge_request_changed_files
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "List changed file paths in a merge request without diff content (merge_request_iid or source_branch required). Read-only; missing resources, denied access, and rate limits return errors. `project_id`/`group_id` take a numeric ID or URL-encoded path.",
+   "description": "List changed file paths in a merge request without diff content (merge_request_iid or source_branch required).",
    "inputSchema": {
      "properties": {
        "excluded_file_patterns": {
+       },
+       "summary": {
+         "description": "If true, return only high-signal fields (id, iid, title, state, web_url, …). Default false keeps the full GitLab JSON.",
+         "type": "boolean"
        }
      },
      "required": [
--- pinned/list_merge_request_diffs
+++ observed/list_merge_request_diffs
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "List merge request diffs with pagination (merge_request_iid or source_branch required). For one known resource, use the matching get tool. Read-only; missing resources, denied access, and rate limits return errors. `project_id`/`group_id` take a numeric ID or URL-encoded path.",
+   "description": "List merge request diffs with pagination (merge_request_iid or source_branch required). For one known resource, use the matching get tool.",
    "inputSchema": {
      "properties": {
        "jmespath": {
+       "summary": {
+         "description": "If true, return only high-signal fields (id, iid, title, state, web_url, …). Default false keeps the full GitLab JSON.",
+         "type": "boolean"
+       },
        "unidiff": {
          "description": "Present diffs in the unified diff format. Default is false. Introduced in GitLab 16.5.",
          "type": "boolean"
--- pinned/list_merge_requests
+++ observed/list_merge_requests
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "List merge requests (without project_id: user's MRs; with project_id: project MRs). For one known resource, use the matching get tool. Read-only; missing resources, denied access, and rate limits return errors. `project_id`/`group_id` take a numeric ID or URL-encoded path.",
+   "description": "List merge requests (without project_id: user's MRs; with project_id: project MRs). For one known resource, use the matching get tool.",
    "inputSchema": {
      "properties": {
        "approved_by_usernames": {
+       "summary": {
+         "description": "If true, return only high-signal fields (id, iid, title, state, web_url, …). Default false keeps the full GitLab JSON.",
+         "type": "boolean"
+       },
        "target_branch": {
          "description": "Return merge requests targeting a specific branch",
          "type": "string"
--- pinned/list_project_members
+++ observed/list_project_members
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "List members of a GitLab project. Read-only; missing resources, denied access, and rate limits return errors. `project_id`/`group_id` take a numeric ID or URL-encoded path.",
+   "description": "List members of a GitLab project. Search project members by name or username. Use `list_group_members` for a group.",
    "inputSchema": {
      "properties": {
        "include_inheritance": {
+       "summary": {
+         "description": "If true, return only high-signal fields (id, iid, title, state, web_url, …). Default false keeps the full GitLab JSON.",
+         "type": "boolean"
+       },
        "user_ids": {
          "description": "Filter by user IDs",
          "items": {
--- pinned/list_projects
+++ observed/list_projects
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "List projects accessible by the current user. For one known resource, use the matching get tool. Read-only; missing resources, denied access, and rate limits return errors.",
+   "description": "List projects accessible by the current user. For one known resource, use the matching get tool.",
    "inputSchema": {
      "properties": {
        "archived": {
+       "summary": {
+         "description": "If true, return only high-signal fields (id, iid, title, state, web_url, …). Default false keeps the full GitLab JSON.",
+         "type": "boolean"
+       },
        "topic": {
          "description": "Filter by topic (projects tagged with this topic)",
          "type": "string"
--- pinned/mr_discussions
+++ observed/mr_discussions
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "List discussion items for a merge request. Use this to list complete discussion threads for a merge request; use `get_merge_request_notes` when only flat notes are needed. It is read-only and returns threaded discussion items, while invalid merge request identifiers, missing resources, and permission failures are reported as errors.",
+   "description": "List discussion items for a merge request. List complete discussion threads. Use `get_merge_request_notes` for flat notes.",
    "inputSchema": {
      "properties": {
        "jmespath": {
+       },
+       "summary": {
+         "description": "If true, return only high-signal fields (id, iid, title, state, web_url, …). Default false keeps the full GitLab JSON.",
+         "type": "boolean"
        }
      },
      "required": [
--- pinned/my_issues
+++ observed/my_issues
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "List issues assigned to the authenticated user. Use this for issue management: list issues assigned to the authenticated user. Use `list_issues` for project-wide or author-scoped listing and `get_issue` for one issue. Resolving the current user requires classic read_user or fine-grained User:Read. It is read-only and paginated, requires authentication, and returns assigned issue records or permission/rate-limit errors.",
+   "description": "List issues assigned to the authenticated user. Use this for issue management: list issues assigned to the authenticated user. Use `list_issues` for project-wide listing and `get_issue` for one issue. Requires classic read_user or fine-grained User:Read.",
    "inputSchema": {
      "properties": {
        "created_after": {
--- pinned/resolve_merge_request_thread
+++ observed/resolve_merge_request_thread
  {
    "annotations": {
      "openWorldHint": true
-   "description": "Resolve a thread on a merge request. Use this to mark an existing merge request review thread resolved; use `update_merge_request_discussion_note` when the note text itself must change. The operation changes review state, requires permission to resolve discussions, and returns the updated discussion or a missing-thread/permission error.",
+   "description": "Resolve a thread on a merge request. Mark an existing review thread resolved. Use `update_merge_request_discussion_note` to change note text.",
    "inputSchema": {
      "properties": {
        "discussion_id": {
--- pinned/search_repositories
+++ observed/search_repositories
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "Search for GitLab projects. If the identifier is known, use a typed get or list tool. Read-only; missing resources, denied access, and rate limits return errors.",
+   "description": "Search for GitLab projects. If the identifier is known, use a typed get or list tool.",
    "inputSchema": {
      "properties": {
        "jmespath": {
--- pinned/update_issue
+++ observed/update_issue
  {
    "annotations": {
      "openWorldHint": true
-   "description": "Update an issue. Returns a slim confirmation by default; set full_response=true for the complete updated issue object. Use this to change fields on an existing issue; use `update_issue_description_patch` for a targeted description edit that avoids sending the full body, and use `create_issue_note` for discussion. The operation mutates issue state, requires issue-edit permission, and returns the updated issue or a validation/permission/conflict error.",
+   "description": "Update an issue. Returns a slim confirmation by default; set full_response=true for the complete updated issue object. Change fields on an existing issue. Use `update_issue_description_patch` for a targeted description edit and `create_issue_note` for discussion.",
    "inputSchema": {
      "properties": {
        "assignee_ids": {
--- pinned/update_issue_description_patch
+++ observed/update_issue_description_patch
  {
    "annotations": {
      "openWorldHint": true
-   "description": "Apply a patch (search/replace or unified diff) to an issue description. Reduces token usage by allowing small changes without sending the full description. Supports dry_run to preview changes and create_note to summarize updates. Use this for a targeted search/replace or unified-diff change to an issue description; use `dry_run` before applying an uncertain patch and `create_note` when an audit summary is wanted. It changes the issue description when not dry-running, requires issue-edit permission, and returns the patch result or a mismatch/validation/permission error.",
+   "description": "Apply a patch (search/replace or unified diff) to an issue description. Reduces token usage by allowing small changes without sending the full description. Supports dry_run to preview changes and create_note to summarize updates.",
    "inputSchema": {
      "properties": {
        "allow_multiple": {
--- pinned/update_merge_request
+++ observed/update_merge_request
  {
    "annotations": {
      "openWorldHint": true
-   "description": "Update a merge request (merge_request_iid or source_branch required). Use the create tool for new resources and a note tool for comments. Changes GitLab data; needs permission and returns validation or conflict errors. `project_id`/`group_id` take a numeric ID or URL-encoded path.",
+   "description": "Update a merge request (merge_request_iid or source_branch required). Use the create tool for new resources and a note tool for comments.",
    "inputSchema": {
      "properties": {
        "assignee_ids": {
--- pinned/whoami
+++ observed/whoami
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "Get current authenticated user details. Use this to identify the authenticated GitLab user; use `get_user` or `get_users` when looking up another user. It requires classic read_user or fine-grained User:Read. It is read-only and returns the current user profile, while missing credentials or GitLab permission failures are reported as errors.",
+   "description": "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.",
    "inputSchema": {
      "properties": {
        "jmespath": {

Changed 2026-10-15 11:13 UTC

19 descriptions rewritten.

--- pinned/get_branch
+++ observed/get_branch
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "Get branch details (commit, protection status). Use this for a known resource or result; choose the corresponding list or search tool when you need to discover multiple resources. It is read-only and does not mutate GitLab data; missing resources, invalid identifiers, insufficient permission, and rate limits are returned as errors. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented.",
+   "description": "Get branch details (commit, protection status). To find resources, use the matching list or search tool. Read-only; missing resources, denied access, and rate limits return errors. `project_id`/`group_id` take a numeric ID or URL-encoded path.",
    "inputSchema": {
      "properties": {
        "branch_name": {
--- pinned/get_commit
+++ observed/get_commit
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "Get details of a specific commit. Use this for a known resource or result; choose the corresponding list or search tool when you need to discover multiple resources. It is read-only and does not mutate GitLab data; missing resources, invalid identifiers, insufficient permission, and rate limits are returned as errors. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented.",
+   "description": "Get details of a specific commit. To find resources, use the matching list or search tool. Read-only; missing resources, denied access, and rate limits return errors. `project_id`/`group_id` take a numeric ID or URL-encoded path.",
    "inputSchema": {
      "properties": {
        "jmespath": {
--- pinned/get_commit_diff
+++ observed/get_commit_diff
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "Get changes/diffs of a specific commit. Use this for a known resource or result; choose the corresponding list or search tool when you need to discover multiple resources. It is read-only and does not mutate GitLab data; missing resources, invalid identifiers, insufficient permission, and rate limits are returned as errors. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented.",
+   "description": "Get changes/diffs of a specific commit. Read-only; missing resources, denied access, and rate limits return errors. `project_id`/`group_id` take a numeric ID or URL-encoded path.",
    "inputSchema": {
      "properties": {
        "full_diff": {
--- pinned/get_file_contents
+++ observed/get_file_contents
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "Get contents of a file or directory from a GitLab project. Use this for a known resource or result; choose the corresponding list or search tool when you need to discover multiple resources. It is read-only and does not mutate GitLab data; missing resources, invalid identifiers, insufficient permission, and rate limits are returned as errors. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented.",
+   "description": "Get contents of a file or directory from a GitLab project. Read-only; missing resources, denied access, and rate limits return errors. `project_id`/`group_id` take a numeric ID or URL-encoded path.",
    "inputSchema": {
      "properties": {
        "file_path": {
--- pinned/get_merge_request
+++ observed/get_merge_request
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "Get details of a merge request (merge_request_iid or source_branch required). Set include_summaries=true for deployment/commit/approval summaries. Use this for a known resource or result; choose the corresponding list or search tool when you need to discover multiple resources. It is read-only and does not mutate GitLab data; missing resources, invalid identifiers, insufficient permission, and rate limits are returned as errors. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented.",
+   "description": "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. Read-only; missing resources, denied access, and rate limits return errors. `project_id`/`group_id` take a numeric ID or URL-encoded path.",
    "inputSchema": {
      "properties": {
        "include_summaries": {
--- pinned/get_merge_request_diffs
+++ observed/get_merge_request_diffs
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "Get the changes/diffs of a merge request (merge_request_iid or source_branch required). Use this for a known resource or result; choose the corresponding list or search tool when you need to discover multiple resources. It is read-only and does not mutate GitLab data; missing resources, invalid identifiers, insufficient permission, and rate limits are returned as errors. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented.",
+   "description": "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. Read-only; missing resources, denied access, and rate limits return errors. `project_id`/`group_id` take a numeric ID or URL-encoded path.",
    "inputSchema": {
      "properties": {
        "excluded_file_patterns": {
--- pinned/get_merge_request_file_diff
+++ observed/get_merge_request_file_diff
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "Get diffs for specific files from a merge request (merge_request_iid or source_branch required). Use this for a known resource or result; choose the corresponding list or search tool when you need to discover multiple resources. It is read-only and does not mutate GitLab data; missing resources, invalid identifiers, insufficient permission, and rate limits are returned as errors. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented.",
+   "description": "Get diffs for specific files from a merge request (merge_request_iid or source_branch required). Read-only; missing resources, denied access, and rate limits return errors. `project_id`/`group_id` take a numeric ID or URL-encoded path.",
    "inputSchema": {
      "properties": {
        "file_paths": {
--- pinned/get_project
+++ observed/get_project
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "Get details of a specific project. Use this for a known resource or result; choose the corresponding list or search tool when you need to discover multiple resources. It is read-only and does not mutate GitLab data; missing resources, invalid identifiers, insufficient permission, and rate limits are returned as errors. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented.",
+   "description": "Get details of a specific project. To find resources, use the matching list or search tool. Read-only; missing resources, denied access, and rate limits return errors. `project_id`/`group_id` take a numeric ID or URL-encoded path.",
    "inputSchema": {
      "properties": {
        "jmespath": {
--- pinned/get_repository_tree
+++ observed/get_repository_tree
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "List files and directories in a repository. Use this for a known resource or result; choose the corresponding list or search tool when you need to discover multiple resources. It is read-only and does not mutate GitLab data; missing resources, invalid identifiers, insufficient permission, and rate limits are returned as errors. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented.",
+   "description": "List files and directories in a repository. Read-only; missing resources, denied access, and rate limits return errors. `project_id`/`group_id` take a numeric ID or URL-encoded path.",
    "inputSchema": {
      "properties": {
        "jmespath": {
--- pinned/list_branches
+++ observed/list_branches
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "List branches in project with search filter. Use this for a collection of resources; choose the corresponding get tool when you already know the single resource to inspect. It is read-only and does not mutate GitLab data; missing resources, invalid identifiers, insufficient permission, and rate limits are returned as errors. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented.",
+   "description": "List branches in project with search filter. For one known resource, use the matching get tool. Read-only; missing resources, denied access, and rate limits return errors. `project_id`/`group_id` take a numeric ID or URL-encoded path.",
    "inputSchema": {
      "properties": {
        "jmespath": {
--- pinned/list_commits
+++ observed/list_commits
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "List repository commits with filtering options. Use this for a collection of resources; choose the corresponding get tool when you already know the single resource to inspect. It is read-only and does not mutate GitLab data; missing resources, invalid identifiers, insufficient permission, and rate limits are returned as errors. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented.",
+   "description": "List repository commits with filtering options. For one known resource, use the matching get tool. Read-only; missing resources, denied access, and rate limits return errors. `project_id`/`group_id` take a numeric ID or URL-encoded path.",
    "inputSchema": {
      "properties": {
        "all": {
--- pinned/list_labels
+++ observed/list_labels
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "List labels for a project. Use this for a collection of resources; choose the corresponding get tool when you already know the single resource to inspect. It is read-only and does not mutate GitLab data; missing resources, invalid identifiers, insufficient permission, and rate limits are returned as errors. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented.",
+   "description": "List labels for a project. For one known resource, use the matching get tool. Read-only; missing resources, denied access, and rate limits return errors. `project_id`/`group_id` take a numeric ID or URL-encoded path.",
    "inputSchema": {
      "properties": {
        "include_ancestor_groups": {
--- pinned/list_merge_request_changed_files
+++ observed/list_merge_request_changed_files
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "List changed file paths in a merge request without diff content (merge_request_iid or source_branch required). Use this for a collection of resources; choose the corresponding get tool when you already know the single resource to inspect. It is read-only and does not mutate GitLab data; missing resources, invalid identifiers, insufficient permission, and rate limits are returned as errors. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented.",
+   "description": "List changed file paths in a merge request without diff content (merge_request_iid or source_branch required). Read-only; missing resources, denied access, and rate limits return errors. `project_id`/`group_id` take a numeric ID or URL-encoded path.",
    "inputSchema": {
      "properties": {
        "excluded_file_patterns": {
--- pinned/list_merge_request_diffs
+++ observed/list_merge_request_diffs
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "List merge request diffs with pagination (merge_request_iid or source_branch required). Use this for a collection of resources; choose the corresponding get tool when you already know the single resource to inspect. It is read-only and does not mutate GitLab data; missing resources, invalid identifiers, insufficient permission, and rate limits are returned as errors. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented.",
+   "description": "List merge request diffs with pagination (merge_request_iid or source_branch required). For one known resource, use the matching get tool. Read-only; missing resources, denied access, and rate limits return errors. `project_id`/`group_id` take a numeric ID or URL-encoded path.",
    "inputSchema": {
      "properties": {
        "jmespath": {
--- pinned/list_merge_requests
+++ observed/list_merge_requests
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "List merge requests (without project_id: user's MRs; with project_id: project MRs). Use this for a collection of resources; choose the corresponding get tool when you already know the single resource to inspect. It is read-only and does not mutate GitLab data; missing resources, invalid identifiers, insufficient permission, and rate limits are returned as errors. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented.",
+   "description": "List merge requests (without project_id: user's MRs; with project_id: project MRs). For one known resource, use the matching get tool. Read-only; missing resources, denied access, and rate limits return errors. `project_id`/`group_id` take a numeric ID or URL-encoded path.",
    "inputSchema": {
      "properties": {
        "approved_by_usernames": {
--- pinned/list_project_members
+++ observed/list_project_members
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "List members of a GitLab project. Use this for a collection of resources; choose the corresponding get tool when you already know the single resource to inspect. It is read-only and does not mutate GitLab data; missing resources, invalid identifiers, insufficient permission, and rate limits are returned as errors. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented.",
+   "description": "List members of a GitLab project. Read-only; missing resources, denied access, and rate limits return errors. `project_id`/`group_id` take a numeric ID or URL-encoded path.",
    "inputSchema": {
      "properties": {
        "include_inheritance": {
--- pinned/list_projects
+++ observed/list_projects
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "List projects accessible by the current user. Use this for a collection of resources; choose the corresponding get tool when you already know the single resource to inspect. It is read-only and does not mutate GitLab data; missing resources, invalid identifiers, insufficient permission, and rate limits are returned as errors. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented.",
+   "description": "List projects accessible by the current user. For one known resource, use the matching get tool. Read-only; missing resources, denied access, and rate limits return errors.",
    "inputSchema": {
      "properties": {
        "archived": {
--- pinned/search_repositories
+++ observed/search_repositories
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "Search for GitLab projects. Use this to discover matching content; choose a typed get or list tool when the target identifier is already known. It is read-only and does not mutate GitLab data; missing resources, invalid identifiers, insufficient permission, and rate limits are returned as errors. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented.",
+   "description": "Search for GitLab projects. If the identifier is known, use a typed get or list tool. Read-only; missing resources, denied access, and rate limits return errors.",
    "inputSchema": {
      "properties": {
        "jmespath": {
--- pinned/update_merge_request
+++ observed/update_merge_request
  {
    "annotations": {
      "openWorldHint": true
-   "description": "Update a merge request (merge_request_iid or source_branch required). Use this for an existing resource; choose the corresponding create tool for a new resource and a note tool for discussion-only text. It changes remote GitLab state and requires the necessary project or group permission; GitLab returns validation, conflict, permission, or rate-limit errors instead of silently applying an invalid request. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented.",
+   "description": "Update a merge request (merge_request_iid or source_branch required). Use the create tool for new resources and a note tool for comments. Changes GitLab data; needs permission and returns validation or conflict errors. `project_id`/`group_id` take a numeric ID or URL-encoded path.",
    "inputSchema": {
      "properties": {
        "assignee_ids": {

Changed 2026-10-14 11:36 UTC

1 description rewritten.

--- pinned/discover_tools
+++ observed/discover_tools
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "Discover and activate additional tool categories for this session. Available 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. Already-active categories are listed in the response. Use this when a needed opt-in category is not currently exposed; omit `category` to inspect available categories, then call it with a category to activate that group for the current session. It changes only the session's tool registry, returns the active-tool summary, and does not change GitLab data.",
+   "description": "Discover and activate additional tool categories for this session. Available 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. Already-active categories are listed in the response. Explicit-only toolsets are omitted; list them in GITLAB_TOOLSETS. Use this when a needed opt-in category is not currently exposed; omit `category` to inspect available categories, then call it with a category to activate that group for the current session. It changes only the session's tool registry, returns the active-tool summary, and does not change GitLab data.",
    "inputSchema": {
      "properties": {
        "category": {

Changed 2026-10-12 15:04 UTC

1 description rewritten.

--- pinned/health_check
+++ observed/health_check
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "Verify server status and authentication. Always reports the MCP server version (mcp_server_version). When authenticated, also reports the GitLab instance version from GET /api/v4/version (version, revision, enterprise). Version lookup failures do not fail the health check — those fields are omitted. Use this to verify server connectivity and authentication before making GitLab requests; use `whoami` when the authenticated user's identity is the goal. A 403 from GET /user with an insufficient_scope error means the token is accepted but User API scope is missing (read_user or fine-grained User:Read); the check stays ok, sets user_api_warning, and omits version metadata. Rate-limit and authentication-ban 403 responses stay unauthenticated. It does not mutate GitLab state and returns server/authentication status plus GitLab version details when available.",
+   "description": "Verify server status and authentication. Always reports the MCP server version (mcp_server_version). When authenticated, also reports the GitLab instance version from GET /api/v4/version (version, revision, enterprise). Version lookup failures do not fail the health check — those fields are omitted. Use this to verify server connectivity and authentication before making GitLab requests; use `whoami` when the authenticated user's identity is the goal. A 403 from GET /user with an insufficient_scope error means the token is accepted but User API scope is missing (read_user or fine-grained User:Read); the check stays ok, sets user_api_warning, and omits version metadata. Rate-limit and authentication-ban 403 responses stay unauthenticated. It does not mutate GitLab state and returns server/authentication status plus GitLab version details when available. Connection failures with no HTTP response return status error, authenticated false, and an error object (kind tls, dns, timeout, or network, plus code and message) instead of a protocol error.",
    "inputSchema": {
      "properties": {
        "jmespath": {

Changed 2026-10-10 12:17 UTC

9 descriptions rewritten.

--- pinned/get_merge_request
+++ observed/get_merge_request
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "Get details of a merge request (mergeRequestIid or branchName required). Set include_summaries=true for deployment/commit/approval summaries. Use this for a known resource or result; choose the corresponding list or search tool when you need to discover multiple resources. It is read-only and does not mutate GitLab data; missing resources, invalid identifiers, insufficient permission, and rate limits are returned as errors. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented.",
+   "description": "Get details of a merge request (merge_request_iid or source_branch required). Set include_summaries=true for deployment/commit/approval summaries. Use this for a known resource or result; choose the corresponding list or search tool when you need to discover multiple resources. It is read-only and does not mutate GitLab data; missing resources, invalid identifiers, insufficient permission, and rate limits are returned as errors. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented.",
    "inputSchema": {
      "properties": {
        "include_summaries": {
--- pinned/get_merge_request_diffs
+++ observed/get_merge_request_diffs
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "Get the changes/diffs of a merge request (mergeRequestIid or branchName required). Use this for a known resource or result; choose the corresponding list or search tool when you need to discover multiple resources. It is read-only and does not mutate GitLab data; missing resources, invalid identifiers, insufficient permission, and rate limits are returned as errors. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented.",
+   "description": "Get the changes/diffs of a merge request (merge_request_iid or source_branch required). Use this for a known resource or result; choose the corresponding list or search tool when you need to discover multiple resources. It is read-only and does not mutate GitLab data; missing resources, invalid identifiers, insufficient permission, and rate limits are returned as errors. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented.",
    "inputSchema": {
      "properties": {
        "excluded_file_patterns": {
--- pinned/get_merge_request_file_diff
+++ observed/get_merge_request_file_diff
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "Get diffs for specific files from a merge request (mergeRequestIid or branchName required). Use this for a known resource or result; choose the corresponding list or search tool when you need to discover multiple resources. It is read-only and does not mutate GitLab data; missing resources, invalid identifiers, insufficient permission, and rate limits are returned as errors. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented.",
+   "description": "Get diffs for specific files from a merge request (merge_request_iid or source_branch required). Use this for a known resource or result; choose the corresponding list or search tool when you need to discover multiple resources. It is read-only and does not mutate GitLab data; missing resources, invalid identifiers, insufficient permission, and rate limits are returned as errors. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented.",
    "inputSchema": {
      "properties": {
        "file_paths": {
--- pinned/health_check
+++ observed/health_check
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "Verify server status and authentication. Always reports the MCP server version (mcp_server_version). When authenticated, also reports the GitLab instance version from GET /api/v4/version (version, revision, enterprise). Version lookup failures do not fail the health check — those fields are omitted. Use this to verify server connectivity and authentication before making GitLab requests; use `whoami` when the authenticated user's identity is the goal. It does not mutate GitLab state and returns server/authentication status plus GitLab version details when available.",
+   "description": "Verify server status and authentication. Always reports the MCP server version (mcp_server_version). When authenticated, also reports the GitLab instance version from GET /api/v4/version (version, revision, enterprise). Version lookup failures do not fail the health check — those fields are omitted. Use this to verify server connectivity and authentication before making GitLab requests; use `whoami` when the authenticated user's identity is the goal. A 403 from GET /user with an insufficient_scope error means the token is accepted but User API scope is missing (read_user or fine-grained User:Read); the check stays ok, sets user_api_warning, and omits version metadata. Rate-limit and authentication-ban 403 responses stay unauthenticated. It does not mutate GitLab state and returns server/authentication status plus GitLab version details when available.",
    "inputSchema": {
      "properties": {
        "jmespath": {
--- pinned/list_merge_request_changed_files
+++ observed/list_merge_request_changed_files
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "List changed file paths in a merge request without diff content (mergeRequestIid or branchName required). Use this for a collection of resources; choose the corresponding get tool when you already know the single resource to inspect. It is read-only and does not mutate GitLab data; missing resources, invalid identifiers, insufficient permission, and rate limits are returned as errors. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented.",
+   "description": "List changed file paths in a merge request without diff content (merge_request_iid or source_branch required). Use this for a collection of resources; choose the corresponding get tool when you already know the single resource to inspect. It is read-only and does not mutate GitLab data; missing resources, invalid identifiers, insufficient permission, and rate limits are returned as errors. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented.",
    "inputSchema": {
      "properties": {
        "excluded_file_patterns": {
--- pinned/list_merge_request_diffs
+++ observed/list_merge_request_diffs
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "List merge request diffs with pagination (mergeRequestIid or branchName required). Use this for a collection of resources; choose the corresponding get tool when you already know the single resource to inspect. It is read-only and does not mutate GitLab data; missing resources, invalid identifiers, insufficient permission, and rate limits are returned as errors. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented.",
+   "description": "List merge request diffs with pagination (merge_request_iid or source_branch required). Use this for a collection of resources; choose the corresponding get tool when you already know the single resource to inspect. It is read-only and does not mutate GitLab data; missing resources, invalid identifiers, insufficient permission, and rate limits are returned as errors. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented.",
    "inputSchema": {
      "properties": {
        "jmespath": {
--- pinned/my_issues
+++ observed/my_issues
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "List issues assigned to the authenticated user. Use this for issue management: list issues assigned to the authenticated user. Use `list_issues` for project-wide or author-scoped listing and `get_issue` for one issue. It is read-only and paginated, requires authentication, and returns assigned issue records or permission/rate-limit errors.",
+   "description": "List issues assigned to the authenticated user. Use this for issue management: list issues assigned to the authenticated user. Use `list_issues` for project-wide or author-scoped listing and `get_issue` for one issue. Resolving the current user requires classic read_user or fine-grained User:Read. It is read-only and paginated, requires authentication, and returns assigned issue records or permission/rate-limit errors.",
    "inputSchema": {
      "properties": {
        "created_after": {
--- pinned/update_merge_request
+++ observed/update_merge_request
  {
    "annotations": {
      "openWorldHint": true
-   "description": "Update a merge request (mergeRequestIid or branchName required). Use this for an existing resource; choose the corresponding create tool for a new resource and a note tool for discussion-only text. It changes remote GitLab state and requires the necessary project or group permission; GitLab returns validation, conflict, permission, or rate-limit errors instead of silently applying an invalid request. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented.",
+   "description": "Update a merge request (merge_request_iid or source_branch required). Use this for an existing resource; choose the corresponding create tool for a new resource and a note tool for discussion-only text. It changes remote GitLab state and requires the necessary project or group permission; GitLab returns validation, conflict, permission, or rate-limit errors instead of silently applying an invalid request. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented.",
    "inputSchema": {
      "properties": {
        "assignee_ids": {
--- pinned/whoami
+++ observed/whoami
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "Get current authenticated user details. Use this to identify the authenticated GitLab user; use `get_user` or `get_users` when looking up another user. It is read-only and returns the current user profile, while missing credentials or GitLab permission failures are reported as errors.",
+   "description": "Get current authenticated user details. Use this to identify the authenticated GitLab user; use `get_user` or `get_users` when looking up another user. It requires classic read_user or fine-grained User:Read. It is read-only and returns the current user profile, while missing credentials or GitLab permission failures are reported as errors.",
    "inputSchema": {
      "properties": {
        "jmespath": {

Changed 2026-10-08 13:12 UTC

2 descriptions rewritten, 79 tools removed.

--- pinned/discover_tools
+++ observed/discover_tools
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "Discover and activate additional tool categories for this session. Available categories: merge_requests, issues, repositories, branches, projects, labels, ci, groups, pipelines, milestones, wiki, releases, tags, snippets, users, workitems, webhooks, search, variables, dependency_proxy, vulnerabilities, orbit. Already-active categories are listed in the response. Use this when a needed opt-in category is not currently exposed; omit `category` to inspect available categories, then call it with a category to activate that group for the current session. It changes only the session's tool registry, returns the active-tool summary, and does not change GitLab data.",
+   "description": "Discover and activate additional tool categories for this session. Available 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. Already-active categories are listed in the response. Use this when a needed opt-in category is not currently exposed; omit `category` to inspect available categories, then call it with a category to activate that group for the current session. It changes only the session's tool registry, returns the active-tool summary, and does not change GitLab data.",
    "inputSchema": {
      "properties": {
        "category": {
--- pinned/get_issue
+++ observed/get_issue
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "Get details of a specific issue. Returns a slim milestone by default; set full_response=true for the complete milestone object. Use this for issue management: inspect one issue's fields; use `list_issues` or `my_issues` to discover issues first. It is read-only, requires issue read permission, and returns the issue or an error when the identifier is invalid, the issue is missing, or access is denied.",
+   "description": "Get details of a specific issue. Returns the issue with a slim nested milestone by default; set full_response=true for the complete milestone object. Use this for issue management: inspect one issue's fields; use `list_issues` or `my_issues` to discover issues first. It is read-only, requires issue read permission, and returns the issue or an error when the identifier is invalid, the issue is missing, or access is denied.",
    "inputSchema": {
      "properties": {
        "full_response": {
-         "description": "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.",
+         "description": "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.",
          "type": "boolean"
        },
        "issue_iid": {

tool removed: approve_merge_request

tool removed: bulk_publish_draft_notes

tool removed: create_branch

tool removed: create_commit_status

tool removed: create_draft_note

tool removed: create_group

tool removed: create_issue_emoji_reaction

tool removed: create_issue_link

tool removed: create_issue_note_emoji_reaction

tool removed: create_label

tool removed: create_merge_request_discussion_note

tool removed: create_merge_request_emoji_reaction

tool removed: create_merge_request_note

tool removed: create_merge_request_note_emoji_reaction

tool removed: create_note

tool removed: create_or_update_file

tool removed: create_repository

tool removed: delete_branch

tool removed: delete_draft_note

tool removed: delete_issue

tool removed: delete_issue_emoji_reaction

tool removed: delete_issue_link

tool removed: delete_issue_note_emoji_reaction

tool removed: delete_label

tool removed: delete_merge_request_discussion_note

tool removed: delete_merge_request_emoji_reaction

tool removed: delete_merge_request_note

tool removed: delete_merge_request_note_emoji_reaction

tool removed: download_attachment

tool removed: fork_repository

tool removed: get_branch_diffs

tool removed: get_ci_catalog_resource

tool removed: get_draft_note

tool removed: get_issue_link

tool removed: get_label

tool removed: get_merge_request_conflicts

tool removed: get_merge_request_version

tool removed: get_namespace

tool removed: get_project_events

tool removed: get_protected_branch

tool removed: get_user

tool removed: get_users

tool removed: list_ci_catalog_resources

tool removed: list_commit_statuses

tool removed: list_draft_notes

tool removed: list_events

tool removed: list_group_iterations

tool removed: list_group_members

tool removed: list_group_merge_requests

tool removed: list_group_projects

tool removed: list_issue_emoji_reactions

tool removed: list_issue_links

tool removed: list_issue_note_emoji_reactions

tool removed: list_merge_request_emoji_reactions

tool removed: list_merge_request_note_emoji_reactions

tool removed: list_merge_request_pipelines

tool removed: list_merge_request_versions

tool removed: list_namespaces

tool removed: list_protected_branches

tool removed: list_todos

tool removed: mark_all_todos_done

tool removed: mark_todo_done

tool removed: merge_merge_request

tool removed: protect_branch

tool removed: publish_draft_note

tool removed: push_files

tool removed: unapprove_merge_request

tool removed: unprotect_branch

tool removed: update_default_branch

tool removed: update_draft_note

tool removed: update_issue_note

tool removed: update_label

tool removed: update_merge_request_discussion_note

tool removed: update_merge_request_note

tool removed: update_project

tool removed: upload_markdown

tool removed: validate_ci_lint

tool removed: validate_project_ci_lint

tool removed: verify_namespace

Changed 2026-10-05 14:12 UTC

5 descriptions rewritten, 112 schema or annotation changes with the description left byte-identical, 1 tool added.

--- pinned/approve_merge_request
+++ observed/approve_merge_request
  {
    "annotations": {
      "openWorldHint": true
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The IID of the merge request to approve",
          "type": "string"
--- pinned/bulk_publish_draft_notes
+++ observed/bulk_publish_draft_notes
  {
    "annotations": {
      "openWorldHint": true
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The IID of a merge request",
          "type": "string"
--- pinned/create_branch
+++ observed/create_branch
  {
    "annotations": {
      "openWorldHint": true
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "project_id": {
          "description": "Project ID or complete URL-encoded path to project",
          "type": "string"
-       "branch",
-       "project_id"
+       "project_id",
+       "branch"
      ],
      "type": "object"
    },
--- pinned/create_commit_status
+++ observed/create_commit_status
  {
    "annotations": {
      "openWorldHint": true
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "name": {
          "description": "Status name. GitLab defaults to 'default' when omitted.",
          "maxLength": 255,
+       "project_id",
        "sha",
-       "state",
-       "project_id"
+       "state"
      ],
      "type": "object"
    },
--- pinned/create_draft_note
+++ observed/create_draft_note
  {
    "annotations": {
      "openWorldHint": true
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The IID of a merge request",
          "type": "string"
-       "body",
        "project_id",
-       "merge_request_iid"
+       "merge_request_iid",
+       "body"
      ],
      "type": "object"
    },
--- pinned/create_group
+++ observed/create_group
  {
    "annotations": {
      "openWorldHint": true
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "name": {
          "description": "The name of the group",
          "type": "string"
--- pinned/create_issue
+++ observed/create_issue
  {
    "annotations": {
      "openWorldHint": true
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "labels": {
          "description": "Array of label names",
          "items": {
-       "title",
-       "project_id"
+       "project_id",
+       "title"
      ],
      "type": "object"
    },
--- pinned/create_issue_emoji_reaction
+++ observed/create_issue_emoji_reaction
  {
    "annotations": {
      "openWorldHint": true
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "name": {
          "description": "Name of the emoji without colons (e.g. 'thumbsup', 'rocket', 'eyes')",
          "type": "string"
-       "name",
        "project_id",
-       "issue_iid"
+       "issue_iid",
+       "name"
      ],
      "type": "object"
    },
--- pinned/create_issue_link
+++ observed/create_issue_link
  {
    "annotations": {
      "openWorldHint": true
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "link_type": {
          "description": "The type of the relation, defaults to relates_to",
          "enum": [
--- pinned/create_issue_note
+++ observed/create_issue_note
  {
    "annotations": {
      "openWorldHint": true
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "project_id": {
          "description": "Project ID or complete URL-encoded path to project",
          "type": "string"
-       "body",
        "project_id",
-       "issue_iid"
+       "issue_iid",
+       "body"
      ],
      "type": "object"
    },
--- pinned/create_issue_note_emoji_reaction
+++ observed/create_issue_note_emoji_reaction
  {
    "annotations": {
      "openWorldHint": true
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "name": {
          "description": "Name of the emoji without colons (e.g. 'thumbsup', 'rocket', 'eyes')",
          "type": "string"
-       "name",
        "project_id",
        "issue_iid",
-       "note_id"
+       "note_id",
+       "name"
      ],
      "type": "object"
    },
--- pinned/create_label
+++ observed/create_label
  {
    "annotations": {
      "openWorldHint": true
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "name": {
          "description": "The name of the label",
          "type": "string"
+       "project_id",
        "name",
-       "color",
-       "project_id"
+       "color"
      ],
      "type": "object"
    },
--- pinned/create_merge_request
+++ observed/create_merge_request
  {
    "annotations": {
      "openWorldHint": true
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "labels": {
          "description": "Labels for the MR",
          "items": {
+       "project_id",
        "title",
        "source_branch",
-       "target_branch",
-       "project_id"
+       "target_branch"
      ],
      "type": "object"
    },
--- pinned/create_merge_request_discussion_note
+++ observed/create_merge_request_discussion_note
  {
    "annotations": {
      "openWorldHint": true
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The IID of a merge request",
          "type": "string"
-       "body",
        "project_id",
        "merge_request_iid",
-       "discussion_id"
+       "discussion_id",
+       "body"
      ],
      "type": "object"
    },
--- pinned/create_merge_request_emoji_reaction
+++ observed/create_merge_request_emoji_reaction
  {
    "annotations": {
      "openWorldHint": true
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The IID of a merge request",
          "type": "string"
-       "name",
        "project_id",
-       "merge_request_iid"
+       "merge_request_iid",
+       "name"
      ],
      "type": "object"
    },
--- pinned/create_merge_request_note
+++ observed/create_merge_request_note
  {
    "annotations": {
      "openWorldHint": true
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The IID of a merge request",
          "type": "string"
-       "body",
        "project_id",
-       "merge_request_iid"
+       "merge_request_iid",
+       "body"
      ],
      "type": "object"
    },
--- pinned/create_merge_request_note_emoji_reaction
+++ observed/create_merge_request_note_emoji_reaction
  {
    "annotations": {
      "openWorldHint": true
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The IID of a merge request",
          "type": "string"
-       "name",
        "project_id",
        "merge_request_iid",
-       "note_id"
+       "note_id",
+       "name"
      ],
      "type": "object"
    },
--- pinned/create_merge_request_thread
+++ observed/create_merge_request_thread
  {
    "annotations": {
      "openWorldHint": true
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The IID of a merge request",
          "type": "string"
-       "body",
        "project_id",
-       "merge_request_iid"
+       "merge_request_iid",
+       "body"
      ],
      "type": "object"
    },
--- pinned/create_note
+++ observed/create_note
  {
    "annotations": {
      "openWorldHint": true
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "noteable_iid": {
          "description": "IID of the issue or merge request",
          "type": "string"
-       "noteable_type",
-       "body",
        "project_id",
-       "noteable_iid"
+       "noteable_type",
+       "noteable_iid",
+       "body"
      ],
      "type": "object"
    },
--- pinned/create_or_update_file
+++ observed/create_or_update_file
  {
    "annotations": {
      "openWorldHint": true
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "last_commit_id": {
          "description": "Last known file commit ID",
          "type": "string"
+       "project_id",
        "file_path",
        "content",
        "commit_message",
-       "branch",
-       "project_id"
+       "branch"
      ],
      "type": "object"
    },
--- pinned/create_repository
+++ observed/create_repository
  {
    "annotations": {
      "openWorldHint": true
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "name": {
          "description": "Repository name",
          "type": "string"
+         "maximum": 9007199254740991,
          "minimum": 1,
          "type": "integer"
        },
--- pinned/delete_branch
+++ observed/delete_branch
  {
    "annotations": {
      "destructiveHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "project_id": {
          "description": "Project ID or complete URL-encoded path to project",
          "type": "string"
-       "branch_name",
-       "project_id"
+       "project_id",
+       "branch_name"
      ],
      "type": "object"
    },
--- pinned/delete_draft_note
+++ observed/delete_draft_note
  {
    "annotations": {
      "destructiveHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The IID of a merge request",
          "type": "string"
--- pinned/delete_issue
+++ observed/delete_issue
  {
    "annotations": {
      "destructiveHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "project_id": {
          "description": "Project ID or URL-encoded path",
          "type": "string"
--- pinned/delete_issue_emoji_reaction
+++ observed/delete_issue_emoji_reaction
  {
    "annotations": {
      "destructiveHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "project_id": {
          "description": "Project ID or complete URL-encoded path to project",
          "type": "string"
--- pinned/delete_issue_link
+++ observed/delete_issue_link
  {
    "annotations": {
      "destructiveHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "project_id": {
          "description": "Project ID or URL-encoded path",
          "type": "string"
--- pinned/delete_issue_note_emoji_reaction
+++ observed/delete_issue_note_emoji_reaction
  {
    "annotations": {
      "destructiveHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "note_id": {
          "description": "The ID of a note (comment or thread reply)",
          "type": "string"
--- pinned/delete_label
+++ observed/delete_label
  {
    "annotations": {
      "destructiveHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "label_id": {
          "description": "The ID or title of a project's label",
          "type": "string"
--- pinned/delete_merge_request_discussion_note
+++ observed/delete_merge_request_discussion_note
  {
    "annotations": {
      "destructiveHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The IID of a merge request",
          "type": "string"
--- pinned/delete_merge_request_emoji_reaction
+++ observed/delete_merge_request_emoji_reaction
  {
    "annotations": {
      "destructiveHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The IID of a merge request",
          "type": "string"
--- pinned/delete_merge_request_note
+++ observed/delete_merge_request_note
  {
    "annotations": {
      "destructiveHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The IID of a merge request",
          "type": "string"
--- pinned/delete_merge_request_note_emoji_reaction
+++ observed/delete_merge_request_note_emoji_reaction
  {
    "annotations": {
      "destructiveHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The IID of a merge request",
          "type": "string"
--- pinned/discover_tools
+++ observed/discover_tools
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "Discover and activate additional tool categories for this session. Available categories: merge_requests, issues, repositories, branches, projects, labels, ci, groups, pipelines, milestones, wiki, releases, tags, users, workitems, webhooks, search, variables, dependency_proxy, vulnerabilities. Already-active categories are listed in the response. Use this when a needed opt-in category is not currently exposed; omit `category` to inspect available categories, then call it with a category to activate that group for the current session. It changes only the session's tool registry, returns the active-tool summary, and does not change GitLab data.",
+   "description": "Discover and activate additional tool categories for this session. Available categories: merge_requests, issues, repositories, branches, projects, labels, ci, groups, pipelines, milestones, wiki, releases, tags, snippets, users, workitems, webhooks, search, variables, dependency_proxy, vulnerabilities, orbit. Already-active categories are listed in the response. Use this when a needed opt-in category is not currently exposed; omit `category` to inspect available categories, then call it with a category to activate that group for the current session. It changes only the session's tool registry, returns the active-tool summary, and does not change GitLab data.",
    "inputSchema": {
      "properties": {
        "category": {
+       },
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
        }
      },
      "type": "object"
--- pinned/download_attachment
+++ observed/download_attachment
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "local_path": {
          "description": "Local path to save the file (optional, defaults to current directory)",
          "type": "string"
--- pinned/fork_repository
+++ observed/fork_repository
  {
    "annotations": {
      "openWorldHint": true
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "namespace": {
          "description": "Namespace to fork to (full path)",
          "type": "string"
--- pinned/get_branch
+++ observed/get_branch
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "project_id": {
          "description": "Project ID or complete URL-encoded path to project",
          "type": "string"
-       "branch_name",
-       "project_id"
+       "project_id",
+       "branch_name"
      ],
      "type": "object"
    },
--- pinned/get_branch_diffs
+++ observed/get_branch_diffs
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "project_id": {
          "description": "Project ID or complete URL-encoded path to project",
          "type": "string"
+       "project_id",
        "from",
-       "to",
-       "project_id"
+       "to"
      ],
      "type": "object"
    },
--- pinned/get_ci_catalog_resource
+++ observed/get_ci_catalog_resource
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "version_limit": {
          "description": "Number of versions to include (default: 5, max: 20)",
          "maximum": 20,
--- pinned/get_commit
+++ observed/get_commit
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "project_id": {
          "description": "Project ID or complete URL-encoded path to project",
          "type": "string"
-       "sha",
-       "project_id"
+       "project_id",
+       "sha"
      ],
      "type": "object"
    },
--- pinned/get_commit_diff
+++ observed/get_commit_diff
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "project_id": {
          "description": "Project ID or complete URL-encoded path to project",
          "type": "string"
-       "sha",
-       "project_id"
+       "project_id",
+       "sha"
      ],
      "type": "object"
    },
--- pinned/get_draft_note
+++ observed/get_draft_note
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The IID of a merge request",
          "type": "string"
--- pinned/get_file_blame
+++ observed/get_file_blame
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "project_id": {
          "description": "Project ID or complete URL-encoded path to project",
          "type": "string"
+         "maximum": 9007199254740991,
+         "minimum": -9007199254740991,
          "type": "integer"
        },
        "range_start": {
+         "maximum": 9007199254740991,
+         "minimum": -9007199254740991,
          "type": "integer"
        },
        "ref": {
+       "project_id",
        "file_path",
        "ref"
      ],
--- pinned/get_file_contents
+++ observed/get_file_contents
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "path": {
          "description": "Alias of file_path",
          "type": "string"
--- pinned/get_issue
+++ observed/get_issue
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "Get details of a specific issue. Returns a slim milestone by default; set full_response=true for the complete milestone object. Use this for a known resource or result; choose the corresponding list or search tool when you need to discover multiple resources. It is read-only and does not mutate GitLab data; missing resources, invalid identifiers, insufficient permission, and rate limits are returned as errors. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented.",
+   "description": "Get details of a specific issue. Returns a slim milestone by default; set full_response=true for the complete milestone object. Use this for issue management: inspect one issue's fields; use `list_issues` or `my_issues` to discover issues first. It is read-only, requires issue read permission, and returns the issue or an error when the identifier is invalid, the issue is missing, or access is denied.",
    "inputSchema": {
      "properties": {
        "full_response": {
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "project_id": {
          "description": "Project ID or URL-encoded path",
          "type": "string"
--- pinned/get_issue_link
+++ observed/get_issue_link
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "project_id": {
          "description": "Project ID or URL-encoded path",
          "type": "string"
--- pinned/get_label
+++ observed/get_label
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "label_id": {
          "description": "The ID or title of a project's label",
          "type": "string"
--- pinned/get_merge_request
+++ observed/get_merge_request
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The IID of a merge request",
          "type": "string"
--- pinned/get_merge_request_approval_state
+++ observed/get_merge_request_approval_state
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The IID of the merge request",
          "type": "string"
--- pinned/get_merge_request_conflicts
+++ observed/get_merge_request_conflicts
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The IID of the merge request",
          "type": "string"
--- pinned/get_merge_request_diffs
+++ observed/get_merge_request_diffs
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The IID of a merge request",
          "type": "string"

+ tool added: get_merge_request_discussion

--- pinned/get_merge_request_file_diff
+++ observed/get_merge_request_file_diff
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The IID of a merge request",
          "type": "string"
--- pinned/get_merge_request_note
+++ observed/get_merge_request_note
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The IID of a merge request",
          "type": "string"
--- pinned/get_merge_request_notes
+++ observed/get_merge_request_notes
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The IID of a merge request",
          "type": "string"
--- pinned/get_merge_request_version
+++ observed/get_merge_request_version
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The internal ID of the merge request",
          "type": "string"
--- pinned/get_namespace
+++ observed/get_namespace
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "namespace_id": {
          "description": "Namespace ID or full path",
          "type": "string"
--- pinned/get_project
+++ observed/get_project
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "project_id": {
          "description": "Project ID or URL-encoded path",
          "type": "string"
--- pinned/get_project_events
+++ observed/get_project_events
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "page": {
          "description": "Returns the specified results page. Default: 1",
          "type": "number"
--- pinned/get_protected_branch
+++ observed/get_protected_branch
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "project_id": {
          "description": "Project ID or complete URL-encoded path to project",
          "type": "string"
-       "branch_name",
-       "project_id"
+       "project_id",
+       "branch_name"
      ],
      "type": "object"
    },
--- pinned/get_repository_tree
+++ observed/get_repository_tree
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "page_token": {
          "description": "Token for keyset pagination. Use the next_page_token value returned in the previous response to retrieve the next page.",
          "type": "string"
--- pinned/get_user
+++ observed/get_user
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "user_id": {
          "description": "The ID of the user",
          "type": "string"
--- pinned/get_users
+++ observed/get_users
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "usernames": {
          "description": "Array of usernames to search for",
          "items": {
--- pinned/health_check
+++ observed/health_check
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "Verify server status and authentication. When authenticated, also reports the GitLab instance version from GET /api/v4/version (version, revision, enterprise). Version lookup failures do not fail the health check — those fields are omitted. Use this to verify server connectivity and authentication before making GitLab requests; use `whoami` when the authenticated user's identity is the goal. It does not mutate GitLab state and returns server/authentication status plus GitLab version details when available.",
+   "description": "Verify server status and authentication. Always reports the MCP server version (mcp_server_version). When authenticated, also reports the GitLab instance version from GET /api/v4/version (version, revision, enterprise). Version lookup failures do not fail the health check — those fields are omitted. Use this to verify server connectivity and authentication before making GitLab requests; use `whoami` when the authenticated user's identity is the goal. It does not mutate GitLab state and returns server/authentication status plus GitLab version details when available.",
    "inputSchema": {
-     "properties": {},
+     "properties": {
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       }
+     },
      "type": "object"
    },
    "name": "health_check"
--- pinned/list_branches
+++ observed/list_branches
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "page": {
          "description": "Page number for pagination (default: 1)",
          "type": "number"
--- pinned/list_ci_catalog_resources
+++ observed/list_ci_catalog_resources
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "scope": {
          "description": "Catalog resource scope",
          "enum": [
--- pinned/list_commit_statuses
+++ observed/list_commit_statuses
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "name": {
          "description": "Filter statuses by status name or context",
          "type": "string"
-       "sha",
-       "project_id"
+       "project_id",
+       "sha"
      ],
      "type": "object"
    },
--- pinned/list_commits
+++ observed/list_commits
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "order": {
          "description": "List commits in order",
          "enum": [
--- pinned/list_draft_notes
+++ observed/list_draft_notes
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The IID of a merge request",
          "type": "string"
--- pinned/list_events
+++ observed/list_events
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "page": {
          "description": "Returns the specified results page. Default: 1",
          "type": "number"
--- pinned/list_group_iterations
+++ observed/list_group_iterations
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "page": {
          "description": "Page number for pagination (default: 1)",
          "type": "number"
--- pinned/list_group_members
+++ observed/list_group_members
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "page": {
          "description": "Page number for pagination (default: 1)",
          "type": "number"
--- pinned/list_group_merge_requests
+++ observed/list_group_merge_requests
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "labels": {
          "description": "Array of label names",
          "items": {
--- pinned/list_group_projects
+++ observed/list_group_projects
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "min_access_level": {
          "description": "Filter by minimum access level",
          "type": "number"
--- pinned/list_issue_discussions
+++ observed/list_issue_discussions
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "page": {
          "description": "Page number for pagination (default: 1)",
          "type": "number"
--- pinned/list_issue_emoji_reactions
+++ observed/list_issue_emoji_reactions
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "project_id": {
          "description": "Project ID or complete URL-encoded path to project",
          "type": "string"
--- pinned/list_issue_links
+++ observed/list_issue_links
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "project_id": {
          "description": "Project ID or URL-encoded path",
          "type": "string"
--- pinned/list_issue_note_emoji_reactions
+++ observed/list_issue_note_emoji_reactions
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "note_id": {
          "description": "The ID of a note (comment or thread reply)",
          "type": "string"
--- pinned/list_issues
+++ observed/list_issues
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "List issues (default: created by current user; use scope='all' for all). Use this for a collection of resources; choose the corresponding get tool when you already know the single resource to inspect. It is read-only and does not mutate GitLab data; missing resources, invalid identifiers, insufficient permission, and rate limits are returned as errors. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented.",
+   "description": "List issues (default: created by current user; use scope='all' for all). Use this for issue management: list GitLab issues, optionally scoped with `project_id`. Use `get_issue` when the issue iid is already known and `my_issues` for issues assigned to the current user. It is read-only and paginated, requires issue read permission, and returns issue records or GitLab errors for invalid identifiers, missing resources, or rate limits.",
    "inputSchema": {
      "properties": {
        "assignee_id": {
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "labels": {
          "description": "Array of label names",
          "items": {
--- pinned/list_labels
+++ observed/list_labels
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "page": {
          "description": "Page number for pagination (default: 1)",
          "type": "number"
--- pinned/list_merge_request_changed_files
+++ observed/list_merge_request_changed_files
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The IID of a merge request",
          "type": "string"
--- pinned/list_merge_request_diffs
+++ observed/list_merge_request_diffs
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The IID of a merge request",
          "type": "string"
--- pinned/list_merge_request_emoji_reactions
+++ observed/list_merge_request_emoji_reactions
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The IID of a merge request",
          "type": "string"
--- pinned/list_merge_request_note_emoji_reactions
+++ observed/list_merge_request_note_emoji_reactions
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The IID of a merge request",
          "type": "string"
--- pinned/list_merge_request_pipelines
+++ observed/list_merge_request_pipelines
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The internal ID of the merge request",
          "type": "string"
-       "merge_request_iid",
-       "project_id"
+       "project_id",
+       "merge_request_iid"
      ],
      "type": "object"
    },
--- pinned/list_merge_request_versions
+++ observed/list_merge_request_versions
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The internal ID of the merge request",
          "type": "string"
--- pinned/list_merge_requests
+++ observed/list_merge_requests
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "labels": {
          "description": "Array of label names",
          "items": {
--- pinned/list_namespaces
+++ observed/list_namespaces
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "owned": {
          "description": "Filter for namespaces owned by current user",
          "type": "boolean"
--- pinned/list_project_members
+++ observed/list_project_members
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "page": {
          "description": "Page number for pagination (default: 1)",
          "type": "number"
--- pinned/list_projects
+++ observed/list_projects
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "membership": {
          "description": "Filter for projects where current user is a member",
          "type": "boolean"
--- pinned/list_protected_branches
+++ observed/list_protected_branches
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "page": {
          "description": "Page number for pagination (default: 1)",
          "type": "number"
--- pinned/list_todos
+++ observed/list_todos
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "page": {
          "description": "Page number for pagination (default: 1)",
          "type": "number"
--- pinned/mark_all_todos_done
+++ observed/mark_all_todos_done
  {
    "annotations": {
      "openWorldHint": true
-     "properties": {},
+     "properties": {
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       }
+     },
      "type": "object"
    },
    "name": "mark_all_todos_done"
--- pinned/mark_todo_done
+++ observed/mark_todo_done
  {
    "annotations": {
      "openWorldHint": true
+       },
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
        }
      },
      "required": [
--- pinned/merge_merge_request
+++ observed/merge_merge_request
  {
    "annotations": {
      "destructiveHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_commit_message": {
          "description": "Custom merge commit message",
          "type": "string"
--- pinned/mr_discussions
+++ observed/mr_discussions
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The IID of a merge request",
          "type": "string"
--- pinned/my_issues
+++ observed/my_issues
  {
    "annotations": {
      "openWorldHint": true,
-   "description": "List issues assigned to the authenticated user. Use this for the specific operation described; choose a sibling tool when you need a different resource or lifecycle action. It is read-only and does not mutate GitLab data; missing resources, invalid identifiers, insufficient permission, and rate limits are returned as errors. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented.",
+   "description": "List issues assigned to the authenticated user. Use this for issue management: list issues assigned to the authenticated user. Use `list_issues` for project-wide or author-scoped listing and `get_issue` for one issue. It is read-only and paginated, requires authentication, and returns assigned issue records or permission/rate-limit errors.",
    "inputSchema": {
      "properties": {
        "created_after": {
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "labels": {
          "description": "Array of label names to filter by",
          "items": {
--- pinned/protect_branch
+++ observed/protect_branch
  {
    "annotations": {
      "destructiveHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_access_level": {
          "description": "Access level for merging (0=No access, 30=Developer, 40=Maintainer, 60=Admin). GitLab default applies when omitted.",
+         "maximum": 9007199254740991,
+         "minimum": -9007199254740991,
          "type": "integer"
        },
        "name": {
+         "maximum": 9007199254740991,
+         "minimum": -9007199254740991,
          "type": "integer"
        },
        "unprotect_access_level": {
+         "maximum": 9007199254740991,
+         "minimum": -9007199254740991,
          "type": "integer"
        }
      },
+       "project_id",
        "branch_name"
      ],
      "type": "object"
--- pinned/publish_draft_note
+++ observed/publish_draft_note
  {
    "annotations": {
      "openWorldHint": true
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The IID of a merge request",
          "type": "string"
--- pinned/push_files
+++ observed/push_files
  {
    "annotations": {
      "destructiveHint": true,
-           "additionalProperties": false,
            "properties": {
              "action": {
                "description": "Commit action for this file. Defaults to 'create'.",
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "project_id": {
          "description": "Project ID or complete URL-encoded path to project",
          "type": "string"
+       "project_id",
        "branch",
        "files",
-       "commit_message",
-       "project_id"
+       "commit_message"
      ],
      "type": "object"
    },
--- pinned/resolve_merge_request_thread
+++ observed/resolve_merge_request_thread
  {
    "annotations": {
      "openWorldHint": true
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The IID of a merge request",
          "type": "string"
--- pinned/search_repositories
+++ observed/search_repositories
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "page": {
          "description": "Page number for pagination (default: 1)",
          "type": "number"
--- pinned/unapprove_merge_request
+++ observed/unapprove_merge_request
  {
    "annotations": {
      "openWorldHint": true
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The IID of the merge request to unapprove",
          "type": "string"
--- pinned/unprotect_branch
+++ observed/unprotect_branch
  {
    "annotations": {
      "destructiveHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "project_id": {
          "description": "Project ID or complete URL-encoded path to project",
          "type": "string"
-       "branch_name",
-       "project_id"
+       "project_id",
+       "branch_name"
      ],
      "type": "object"
    },
--- pinned/update_default_branch
+++ observed/update_default_branch
  {
    "annotations": {
      "destructiveHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "project_id": {
          "description": "Project ID or complete URL-encoded path to project",
          "type": "string"
-       "default_branch",
-       "project_id"
+       "project_id",
+       "default_branch"
      ],
      "type": "object"
    },
--- pinned/update_draft_note
+++ observed/update_draft_note
  {
    "annotations": {
      "openWorldHint": true
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The IID of a merge request",
          "type": "string"
--- pinned/update_issue
+++ observed/update_issue
  {
    "annotations": {
      "openWorldHint": true
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "labels": {
          "description": "Array of label names",
          "items": {
--- pinned/update_issue_description_patch
+++ observed/update_issue_description_patch
  {
    "annotations": {
      "openWorldHint": true
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "patch": {
          "description": "The patch content to apply to the issue description",
          "maxLength": 50000,
-       "patch_type",
-       "patch",
        "project_id",
-       "issue_iid"
+       "issue_iid",
+       "patch_type",
+       "patch"
      ],
      "type": "object"
    },
--- pinned/update_issue_note
+++ observed/update_issue_note
  {
    "annotations": {
      "openWorldHint": true
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "note_id": {
          "description": "The ID of a thread note",
          "type": "string"
+     "required": [
+       "project_id",
+       "issue_iid",
+       "discussion_id",
+       "note_id"
+     ],
      "type": "object"
    },
    "name": "update_issue_note"
--- pinned/update_label
+++ observed/update_label
  {
    "annotations": {
      "openWorldHint": true
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "label_id": {
          "description": "The ID or title of a project's label",
          "type": "string"
--- pinned/update_merge_request
+++ observed/update_merge_request
  {
    "annotations": {
      "openWorldHint": true
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "labels": {
          "description": "Labels for the MR",
          "items": {
--- pinned/update_merge_request_discussion_note
+++ observed/update_merge_request_discussion_note
  {
    "annotations": {
      "openWorldHint": true
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The IID of a merge request",
          "type": "string"
+     "required": [
+       "project_id",
+       "merge_request_iid",
+       "discussion_id",
+       "note_id"
+     ],
      "type": "object"
    },
    "name": "update_merge_request_discussion_note"
--- pinned/update_merge_request_note
+++ observed/update_merge_request_note
  {
    "annotations": {
      "openWorldHint": true
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_request_iid": {
          "description": "The IID of a merge request",
          "type": "string"
-       "body",
        "project_id",
        "merge_request_iid",
-       "note_id"
+       "note_id",
+       "body"
      ],
      "type": "object"
    },
--- pinned/update_project
+++ observed/update_project
  {
    "annotations": {
      "openWorldHint": true
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "merge_method": {
          "description": "Merge method",
          "enum": [
+     "required": [
+       "project_id"
+     ],
      "type": "object"
    },
    "name": "update_project"
--- pinned/upload_markdown
+++ observed/upload_markdown
  {
    "annotations": {
      "openWorldHint": true
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "project_id": {
          "description": "Project ID or URL-encoded path of the project",
          "type": "string"
--- pinned/validate_ci_lint
+++ observed/validate_ci_lint
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "project_id": {
          "description": "Project ID or URL-encoded path",
          "type": "string"
-       "content",
-       "project_id"
+       "project_id",
+       "content"
      ],
      "type": "object"
    },
--- pinned/validate_project_ci_lint
+++ observed/validate_project_ci_lint
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "project_id": {
          "description": "Project ID or URL-encoded path",
          "type": "string"
--- pinned/verify_namespace
+++ observed/verify_namespace
  {
    "annotations": {
      "openWorldHint": true,
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       },
        "parent_id": {
          "description": "Parent namespace ID; required to correctly resolve paths in nested namespaces where the same path may exist under different parents",
+         "maximum": 9007199254740991,
+         "minimum": -9007199254740991,
          "type": "integer"
        },
        "path": {
--- pinned/whoami
+++ observed/whoami
  {
    "annotations": {
      "openWorldHint": true,
-     "properties": {},
+     "properties": {
+       "jmespath": {
+         "description": "Optional JMESPath expression filtering the JSON result before return.",
+         "type": "string"
+       }
+     },
      "type": "object"
    },
    "name": "whoami"

Current tools

Show all 40 tool fingerprints
create_issue
64947ecf63d7b14e
create_issue_note
4a21793a70053e26
create_merge_request
4102e56c43329804
create_merge_request_thread
2ff5dff78127ad62
discover_tools
89682a45b34b0e9c
get_branch
8d5fc48d0092b485
get_commit
54a0cc764690d03a
get_commit_diff
7c137a07485d94b2
get_file_blame
cc5464f2f025ac28
get_file_contents
2b625c50b444bb39
get_issue
f05934ab6cfc851f
get_merge_request
fe1e2a7379459451
get_merge_request_approval_state
385aa25b72a4ec07
get_merge_request_diffs
2bbafa020e37a558
get_merge_request_discussion
efc6984b7b699e7c
get_merge_request_file_diff
45c6a525547ce743
get_merge_request_note
8c0a70fb891b7e0a
get_merge_request_notes
c9e3c69b56c63f9e
get_project
4c253ea376d4bf82
get_repository_tree
bcc31e6bf8474510
health_check
28dec7d79f8fc0f3
help
aa984656b516980f
list_branches
1768385731787d5e
list_commits
441bd38903ea6945
list_issue_discussions
c7719c524eaf01aa
list_issues
d324cd53c18c39fc
list_labels
44661b9035feaa4c
list_merge_request_changed_files
b9e784e7498a938c
list_merge_request_diffs
4d4bc6fea899b130
list_merge_requests
fbbfe8bc3625e8d3
list_project_members
877fce0060b8e6ff
list_projects
e6ad4b2e2327b60a
mr_discussions
3f6d8faae5892469
my_issues
0cdd4a19d1656917
resolve_merge_request_thread
324b14bad0765e68
search_repositories
2632b31f57913868
update_issue
895135f4ebf19e75
update_issue_description_patch
f5eba3572c4f6cdb
update_merge_request
b4b79c9b8bfd74e2
whoami
ad43793445dc8c73

Watch this server yourself

If you run this server, put the proxy in front of it. It pins these exact fingerprints on first connect and stops the session if they move.

npx -y mcp-pin@0.2.3 -- <your @zereight/mcp-gitlab command>

Or subscribe to this page's RSS feed to be told when it changes.

Badge

mcp-pin status badge for @zereight/mcp-gitlab

The badge states one fact about time and nothing else. It never claims a server is safe.

[![mcp-pin](https://mcp-pin.gautamkhosla.com/badge/4914d06c4a8c19cf.svg)](https://mcp-pin.gautamkhosla.com/servers/4914d06c4a8c19cf.html)