Skip to main content
Glama

list_issues

Retrieve and filter GitLab project issues by assignee, author, labels, milestones, and more using customizable search parameters to streamline issue tracking and management.

Instructions

Get issues for a GitLab project

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
assignee_idNo
author_idNo
created_afterNo
created_beforeNo
iidNo
labelsNo
milestoneNo
order_byNo
pageNo
per_pageNo
project_idNo
scopeNo
searchNo
sortNo
stateNo
updated_afterNo
updated_beforeNo

Implementation Reference

  • Handler for the list_issues tool that validates input, calls the GitLab API via gitlabApi.listIssues, and formats the response.
    case "list_issues": {
      // Parse and validate the arguments
      const args = ListIssuesSchema.parse(request.params.arguments);
    
      // Additional validation for pagination parameters
      if (args.per_page && (args.per_page < 1 || args.per_page > 100)) {
        throw new Error("per_page must be between 1 and 100");
      }
    
      if (args.page && args.page < 1) {
        throw new Error("page must be greater than 0");
      }
    
      // Validate date formats if provided
      const dateFields = [
        "created_after",
        "created_before",
        "updated_after",
        "updated_before",
      ];
      dateFields.forEach((field) => {
        const value = args[field as keyof typeof args];
        if (
          typeof value === 'string' &&
          !isValidISODate(value)
        ) {
          throw new Error(
            `${field} must be a valid ISO 8601 date (YYYY-MM-DDTHH:MM:SSZ)`
          );
        }
      });
    
      // Extract project_id and options
      const { project_id, ...options } = args;
    
      // Call the API function
      const issues = await gitlabApi.listIssues(project_id, options);
    
      // Format and return the response
      return formatIssuesResponse(issues);
    }
  • Zod schema defining the input parameters and validation for the list_issues tool.
    export const ListIssuesSchema = z.object({
      project_id: z.string(),
      iid: z.union([z.number(), z.string()]).optional(),
      state: z.enum(['opened', 'closed', 'all']).optional(),
      labels: z.string().optional(),
      milestone: z.string().optional(),
      scope: z.enum(['created_by_me', 'assigned_to_me', 'all']).optional(),
      author_id: z.number().optional(),
      assignee_id: z.number().optional(),
      search: z.string().optional(),
      created_after: z.string().optional(),
      created_before: z.string().optional(),
      updated_after: z.string().optional(),
      updated_before: z.string().optional(),
      order_by: z.string().optional(),
      sort: z.enum(['asc', 'desc']).optional(),
      page: z.number().optional(),
      per_page: z.number().optional()
    });
  • src/index.ts:180-185 (registration)
    Registration of the list_issues tool in the ALL_TOOLS array, specifying name, description, input schema, and read-only status.
    {
      name: "list_issues",
      description: "Get issues for a GitLab project",
      inputSchema: createJsonSchema(ListIssuesSchema),
      readOnly: true
    },
  • GitLabApi class method that performs the HTTP request to fetch issues, handles iid filtering client-side, and parses the response.
    async listIssues(
      projectId: string,
      options: {
        iid?: number | string;
        state?: "opened" | "closed" | "all";
        labels?: string;
        milestone?: string;
        scope?: "created_by_me" | "assigned_to_me" | "all";
        author_id?: number;
        assignee_id?: number;
        search?: string;
        created_after?: string;
        created_before?: string;
        updated_after?: string;
        updated_before?: string;
        order_by?: string;
        sort?: "asc" | "desc";
        page?: number;
        per_page?: number;
      } = {}
    ): Promise<GitLabIssuesResponse> {
      // Extract iid for client-side filtering if provided
      const { iid, ...apiOptions } = options;
    
      // Construct the URL with the project ID
      const url = new URL(
        `${this.apiUrl}/projects/${encodeURIComponent(projectId)}/issues`
      );
    
      // Add all query parameters except iid (we'll filter that client-side)
      Object.entries(apiOptions).forEach(([key, value]) => {
        if (value !== undefined) {
          url.searchParams.append(key, value.toString());
        }
      });
    
      const response = await fetch(url.toString(), {
        headers: {
          Authorization: `Bearer ${this.token}`,
        },
      });
    
      if (!response.ok) {
        throw new McpError(
          ErrorCode.InternalError,
          `GitLab API error: ${response.statusText}`
        );
      }
    
      // Parse the response JSON
      const issues = await response.json() as any[];
    
      // If iid is provided, filter the issues by iid
      const filteredIssues = iid !== undefined
        ? issues.filter(issue => issue.iid?.toString() === iid.toString())
        : issues;
    
      // Get the total count - if filtered, use the filtered length
      const totalCount = iid !== undefined ? filteredIssues.length : parseInt(response.headers.get("X-Total") || "0");
    
      // Validate and return the response
      return GitLabIssuesResponseSchema.parse({
        count: totalCount,
        items: filteredIssues,
      });
    }
  • Formats the issues data into a readable summary and structured JSON for the MCP tool response.
    export function formatIssuesResponse(issues: GitLabIssuesResponse) {
      // Create a summary of the issues
      const summary = `Found ${issues.count} issues`;
    
      // Format the issues data
      const formattedIssues = issues.items.map(issue => ({
        id: issue.id,
        iid: issue.iid,
        title: issue.title,
        description: issue.description,
        state: issue.state,
        created_at: issue.created_at,
        updated_at: issue.updated_at,
        closed_at: issue.closed_at,
        labels: issue.labels,
        author: {
          name: issue.author.name,
          username: issue.author.username
        },
        assignees: issue.assignees.map(assignee => ({
          name: assignee.name,
          username: assignee.username
        })),
        web_url: issue.web_url
      }));
    
      // Return the formatted response
      return {
        content: [
          { type: "text", text: summary },
          { type: "text", text: JSON.stringify(formattedIssues, null, 2) }
        ]
      };
    }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/yoda-digital/mcp-gitlab-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server