list_group_projects
Fetch a list of all projects within a specified GitLab group by providing the group name. Supports pagination with a configurable per-page limit.
Instructions
List projects in a group by group name.
Args:
group_name: GitLab group name or path
per_page: Number of projects per page (max 100)
token: GitLab Personal Access Token (optional)
ctx: MCP context (automatically injected)Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| group_name | Yes | ||
| per_page | No | ||
| token | No | ||
| ctx | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
Implementation Reference
- gitlab_clone_mcp_server/server.py:1332-1333 (registration)Tool registered via @mcp.tool() decorator on the async function 'list_group_projects'. Registration is implicit through FastMCP's decorator pattern.
@mcp.tool() async def list_group_projects(group_name: str, per_page: int = 50, token: str = None, ctx=None) -> str: - Handler function for 'list_group_projects'. Takes group_name, per_page, optional token and ctx. Calls GitLab API /groups/{group_name}/projects to list all projects in a group, returning formatted output.
@mcp.tool() async def list_group_projects(group_name: str, per_page: int = 50, token: str = None, ctx=None) -> str: """List projects in a group by group name. Args: group_name: GitLab group name or path per_page: Number of projects per page (max 100) token: GitLab Personal Access Token (optional) ctx: MCP context (automatically injected) """ import urllib.parse encoded_name = urllib.parse.quote(group_name, safe='') per_page = min(per_page, 100) data = await make_gitlab_request(f"/groups/{encoded_name}/projects?per_page={per_page}", ctx=ctx, token=token) if isinstance(data, dict) and "error" in data: return f"Error: {data['error']}" if not data: return f"No projects found in group '{group_name}'." projects = [] for project in data: projects.append(f"• {project['name']} ({project['path']}) - ID: {project['id']}") return f"Projects in group '{group_name}':\n" + "\n".join(projects) - Input schema via type hints and docstring: group_name (str, required), per_page (int, default 50, max 100), token (optional str), ctx (automatically injected MCP context). Output is a formatted string.
async def list_group_projects(group_name: str, per_page: int = 50, token: str = None, ctx=None) -> str: """List projects in a group by group name. Args: group_name: GitLab group name or path per_page: Number of projects per page (max 100) token: GitLab Personal Access Token (optional) ctx: MCP context (automatically injected) """ - Helper function make_gitlab_request used by list_group_projects to make authenticated HTTP requests to GitLab API v4.
async def make_gitlab_request(endpoint: str, method: str = "GET", data: dict = None, ctx=None, token: str = None) -> dict[str, Any] | None: """Make a request to GitLab API with proper error handling.""" # Priority: 1. Explicit token parameter, 2. Context headers, 3. Environment variable # If no explicit token provided, try to get from context if not token and ctx and hasattr(ctx, 'request_context') and ctx.request_context: # Try to get from request headers if hasattr(ctx.request_context, 'headers'): token = ctx.request_context.headers.get('GITLAB_TOKEN') # Fallback to environment variable if not token: token = os.getenv("GITLAB_TOKEN") if not token: return {"error": "GitLab token not provided. Please provide a token parameter, GITLAB_TOKEN in the request headers, or set the environment variable."} # Get GitLab URL (from context or environment) gitlab_url = os.getenv("GITLAB_URL", "https://gitlab.com") headers = { "PRIVATE-TOKEN": token, "Content-Type": "application/json" } url = f"{gitlab_url}/api/v4{endpoint}" async with httpx.AsyncClient() as client: try: if method == "GET": response = await client.get(url, headers=headers, timeout=30.0) elif method == "POST": response = await client.post(url, headers=headers, json=data, timeout=30.0) elif method == "PUT": response = await client.put(url, headers=headers, json=data, timeout=30.0) elif method == "DELETE": response = await client.delete(url, headers=headers, timeout=30.0) response.raise_for_status() return response.json() if response.content else {"success": True} except Exception as e: return {"error": str(e)}