list-issues
Retrieve GitHub issues from a repository with filters for state, sorting, and pagination to manage project tracking and collaboration.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| owner | Yes | Repository owner (user or organization) | |
| repo | Yes | Repository name | |
| state | No | Issue state filter | open |
| sort | No | Sort criteria | created |
| direction | No | Sort direction | desc |
| page | No | Page number | |
| per_page | No | Items per page |
Implementation Reference
- server/index.ts:1401-1495 (registration)Registers the MCP tool 'list-issues' with Zod input schema and handler that calls the IssuesAPI.listIssues function, formats the response, and returns it in MCP format."list-issues", { owner: z.string().describe(i18n.t('issues', 'param_owner')), repo: z.string().describe(i18n.t('issues', 'param_repo')), state: z.enum(['open', 'closed', 'all']).default('open').describe(i18n.t('issues', 'param_state')), sort: z.enum(['created', 'updated', 'comments']).default('created').describe(i18n.t('issues', 'param_sort')), direction: z.enum(['asc', 'desc']).default('desc').describe(i18n.t('issues', 'param_direction')), page: z.number().default(1).describe(i18n.t('common', 'param_page')), per_page: z.number().default(30).describe(i18n.t('common', 'param_per_page')) }, async ({ owner, repo, state, sort, direction, page, per_page }) => { try { // Parameter validation if (!owner || typeof owner !== 'string' || owner.trim() === '') { return { content: [ { type: "text", text: i18n.t('common', 'error_required', { field: i18n.t('issues', 'param_owner') }) } ], isError: true }; } if (!repo || typeof repo !== 'string' || repo.trim() === '') { return { content: [ { type: "text", text: i18n.t('common', 'error_required', { field: i18n.t('issues', 'param_repo') }) } ], isError: true }; } const issues = await context.issues.listIssues(context.client, { owner, repo, state, sort, direction, page, per_page }); // No issues found if (!issues || issues.length === 0) { return { content: [ { type: "text", text: i18n.t('issues', 'issue_not_found', { owner, repo, state }) } ] }; } // Format issues info for better readability const formattedIssues = issues.map(issue => ({ number: issue.number, title: issue.title, state: issue.state, user: issue.user.login, created_at: issue.created_at, updated_at: issue.updated_at, body: issue.body ? (issue.body.length > 100 ? issue.body.substring(0, 100) + '...' : issue.body) : '', comments: issue.comments, labels: issue.labels.map((label: any) => label.name), assignees: issue.assignees?.map((assignee: any) => assignee.login) || [] })); return { content: [ { type: "text", text: i18n.t('issues', 'issue_list_title', { owner, repo, count: issues.length }) + `\n\n${JSON.stringify(formattedIssues, null, 2)}` } ] }; } catch (error: any) { console.error(i18n.t('common', 'error_generic', { message: error.message })); return { content: [ { type: "text", text: i18n.t('common', 'error_generic', { message: error.message }) } ], isError: true }; } } );
- api/issues/issues.ts:19-35 (handler)Core handler function that executes the GitHub API request to list issues for a given repository, constructing the query parameters dynamically.export async function listIssues( client: GitHubClient, params: ListIssuesParams ): Promise<Issue[]> { const { owner, repo, ...rest } = params; const queryParams = new URLSearchParams(); // Add additional parameters Object.entries(rest).forEach(([key, value]) => { if (value !== undefined) { queryParams.append(key, String(value)); } }); const queryString = queryParams.toString() ? `?${queryParams.toString()}` : ''; return client.get<Issue[]>(`/repos/${owner}/${repo}/issues${queryString}`); }
- api/issues/types.ts:6-15 (schema)TypeScript interface defining the input parameters for the listIssues function, matching the Zod schema used in tool registration.export interface ListIssuesParams { owner: string; repo: string; state?: 'open' | 'closed' | 'all'; sort?: 'created' | 'updated' | 'comments'; direction?: 'asc' | 'desc'; since?: string; page?: number; per_page?: number; }