pylon_list_issues
Retrieve a compact list of support issues within a 30-day time range. Get key details quickly and use the issue ID to fetch full information.
Instructions
List issues within a time range (max 30 days). Returns compact table. Use pylon_get_issue for details.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| start_time | Yes | Start time in RFC3339 format (e.g., 2024-01-01T00:00:00Z) | |
| end_time | Yes | End time in RFC3339 format (e.g., 2024-01-31T00:00:00Z) | |
| limit | No | Number of issues to return (1-100, default 25) | |
| cursor | No | Pagination cursor for next page |
Implementation Reference
- src/index.ts:574-612 (registration)Registration of the pylon_list_issues MCP tool with Zod schema for inputs (start_time, end_time, optional limit/cursor) and handler that calls client.listIssues, transforms results via toIssueMinimal, and formats as a markdown table.
server.tool( 'pylon_list_issues', 'List issues within a time range (max 30 days). Returns compact table. Use pylon_get_issue for details.', { start_time: z .string() .describe('Start time in RFC3339 format (e.g., 2024-01-01T00:00:00Z)'), end_time: z .string() .describe('End time in RFC3339 format (e.g., 2024-01-31T00:00:00Z)'), limit: z .number() .min(1) .max(100) .optional() .describe(`Number of issues to return (1-100, default ${DEFAULT_ISSUE_LIMIT})`), cursor: z.string().optional().describe('Pagination cursor for next page'), }, async ({ start_time, end_time, limit, cursor }) => { const result = await client.listIssues(start_time, end_time, { limit: limit ?? DEFAULT_ISSUE_LIMIT, cursor, }); // Transform to minimal format to reduce context size const issues = (result.data || []).map((raw) => toIssueMinimal(raw as unknown as Record<string, unknown>), ); const table = formatIssuesAsTable(issues); const pagination = result.pagination?.has_next_page ? `\n\nMore results available. Use cursor: "${result.pagination.cursor}"` : ''; return { content: [{ type: 'text', text: table + pagination }], }; }, ); - src/index.ts:592-611 (handler)Handler function for pylon_list_issues: calls client.listIssues with time range and pagination, maps raw data to minimal issue format using toIssueMinimal, and returns a formatted markdown table with optional pagination cursor.
async ({ start_time, end_time, limit, cursor }) => { const result = await client.listIssues(start_time, end_time, { limit: limit ?? DEFAULT_ISSUE_LIMIT, cursor, }); // Transform to minimal format to reduce context size const issues = (result.data || []).map((raw) => toIssueMinimal(raw as unknown as Record<string, unknown>), ); const table = formatIssuesAsTable(issues); const pagination = result.pagination?.has_next_page ? `\n\nMore results available. Use cursor: "${result.pagination.cursor}"` : ''; return { content: [{ type: 'text', text: table + pagination }], }; }, - src/index.ts:54-73 (helper)Helper function that formats an array of IssueMinimal objects into a compact markdown table with columns: #, Title, State, Created, Link.
function formatIssuesAsTable(issues: IssueMinimal[]): string { if (issues.length === 0) { return 'No issues found.'; } const headers = ['#', 'Title', 'State', 'Created', 'Link']; const rows = issues.map((issue) => [ escapeCell(String(issue.number ?? '')), escapeCell(truncate(issue.title, MAX_TITLE_LENGTH)), escapeCell(issue.state), escapeCell(issue.created_at?.split('T')[0] || '-'), issue.link || '-', ]); const headerRow = `| ${headers.join(' | ')} |`; const separatorRow = `|${headers.map(() => '---').join('|')}|`; const dataRows = rows.map((row) => `| ${row.join(' | ')} |`).join('\n'); return `${headerRow}\n${separatorRow}\n${dataRows}`; } - src/schemas.ts:224-236 (helper)Transforms raw API issue response to a minimal IssueMinimal object containing only essential fields (id, number, title, state, link, created_at, assignee_id, account_id, tags) to reduce context size.
export function toIssueMinimal(raw: Record<string, unknown>): IssueMinimal { return { id: raw['id'] as string, number: raw['number'] as number | undefined, title: raw['title'] as string, state: raw['state'] as string, link: raw['link'] as string | undefined, created_at: raw['created_at'] as string | undefined, assignee_id: extractAssigneeId(raw), account_id: extractAccountId(raw), tags: raw['tags'] as string[] | null | undefined, }; } - src/pylon-client.ts:428-443 (helper)PylonClient.listIssues method: validates the time range (max 30 days), builds query params with start_time, end_time, limit, and cursor, then makes a GET request to /issues endpoint.
async listIssues( startTime: string, endTime: string, params?: PaginationParams, ): Promise<PaginatedResponse<Issue>> { validateTimeRange(startTime, endTime); const searchParams = new URLSearchParams(); searchParams.set('start_time', startTime); searchParams.set('end_time', endTime); if (params?.limit) searchParams.set('limit', params.limit.toString()); if (params?.cursor) searchParams.set('cursor', params.cursor); return this.request<PaginatedResponse<Issue>>( 'GET', `/issues?${searchParams.toString()}`, ); }