Add list_projects MCP tool to GitLab MCP server

Note

Before picking up this work: this issue adds an MCP tool. Please follow the Adding a new tool guidance first. That includes creating an MCP Tool Proposal, using verb_object naming (get_ / list_ / save_ / delete_), and the shared resource-identification input base classes.

Summary

Add an MCP server tool (for example, list_projects) that returns a list of GitLab projects accessible to the authenticated user, so MCP clients and Duo Agent Platform agents can dynamically discover projects without hard-coding project IDs or paths.

Parent epic: &20529 (closed)


Problem to solve

Today, the GitLab MCP server exposes several tools (for example, create_issue, get_issue, create_merge_request, get_merge_request_*, get_pipeline_jobs, search, semantic_code_search, etc.), but there is no dedicated tool to list projects via MCP.

The search tool can use scope="projects" to search projects, but:

  • It requires a search term.
  • It is not a simple “list all projects I can work with” primitive.
  • It is awkward for agents that need a generic “show me my projects / projects under this group” capability.

For MCP-based agents and external MCP clients that orchestrate work across multiple GitLab projects, it is hard to:

  • Discover which projects are available to the current user.
  • Present a selectable list of projects to the end user.
  • Build flows like “select a project, then list issues / pipelines / run searches for that project” without hard-coding project IDs or full paths.

This is particularly limiting for Duo Agent Platform + MCP workflows where agents should be able to reason over “my projects” or “projects under a given group” in a generic way.


Proposal

Add a new MCP server tool, tentatively named list_projects, exposed by the GitLab MCP server.

Tool name

  • list_projects

User-facing description (suggested)

List GitLab projects accessible to the current user, optionally filtered by group, search term, visibility, or archived flag.
Useful for presenting a project picker to the user or for discovering projects to operate on with other MCP tools.

Backing API: build as Base::GraphqlTool + Base::GraphqlService on Query.projects (Resolvers::ProjectsResolver). The resolver covers every requested filter: search, membership: true ("my projects"), namespace_path (the group_id param, group/user full-path scoping), visibility_level (VisibilityLevelsEnum), archived (Projects::ArchivedEnum), plus min_access_level/topics/sort. It supports both global ("all accessible") and group-scoped listing. Returns a ProjectType connection (id, fullPath, name, description, visibility, archived), with cursor pagination (first/after).

Input parameters

  • group_id (string, optional):
    ID or full path of a group to scope the project list.
  • search (string, optional):
    Filter by project name or path.
  • visibility (string, optional):
    One of public, internal, private.
  • archived (boolean, optional):
    Filter by archived state.
  • after (string, optional):
    Cursor for pagination (GraphQL after); page size via first.

(group_id maps to namespace_path, visibility to visibility_level; follow Query.projects conventions.)

Output

A structured list of projects, designed to be easy for agents to parse and use in follow-up calls. For each project, include at least:

  • id
  • full_path
  • name
  • description (optional)
  • visibility
  • archived

This allows:

  • Duo agents and external MCP clients to show a project picker.
  • Follow-up tool calls (for example, search, semantic_code_search, or future tools) to use either id or full_path directly.

Resolved

  • Backed by GraphQL (Query.projects), not REST — see Backing API above.
  • Support both global and group-scoped listing; Query.projects handles both (pass namespace_path or not), so no need to start group-only.

Open question for the team

  • What page-size cap (first) do we want to protect performance on large instances?

Use cases

  1. Agent prompts user to select a project

    • Agent calls list_projects with optional group_id.
    • Presents a list of candidate projects to the user (name + path).
    • User selects one project.
    • Agent then:
      • Lists issues via existing or future tools, and/or
      • Uses other MCP tools (search, semantic_code_search, etc.) scoped to the selected project.
  2. Multi-project analysis flows

    • Custom agent: “Show me all active projects under group X with ‘billing’ in the name.”
    • Calls list_projects with group_id = X, search = "billing", and archived = false.
    • Iterates over the returned projects to perform follow-up actions (for example, list issues, analyze pipelines, etc.).
  3. External MCP clients (Cursor, Claude Code, etc.)

    • User connects an MCP-compatible client to the GitLab MCP server.

    • User asks: “Which GitLab projects can you see?” or “List projects under group foo/bar.”

    • Client uses list_projects to:

      • Render a project picker.
      • Use the selected project with other GitLab MCP tools.

Sources

Edited by 🤖 GitLab Bot 🤖