Skip to main content
Glama
issues.router.ts8.66 kB
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { z } from 'zod'; import Issues from "#features/issues/issues.service"; export function registerIssueTools(server: McpServer, issuesInstance: Issues) { server.registerTool( 'get_issue', { description: 'Gets the contents of an issue within a repository', inputSchema: { owner: z.string().describe('Repository owner (string, required)'), repo: z.string().describe('Repository name (string, required)'), issueNumber: z.number().describe('Issue number (number, required)'), } }, async (args, req: any) => { try { let info = await issuesInstance.getIssues(args, req.requestInfo.headers.github_token); return { content: [{ type: 'text', text: JSON.stringify(info, null, 2) }] }; } catch (error: any) { return { content: [{ type: 'text', text: `Error : ${error.message}` }], isError: true }; } } ); server.registerTool( 'get_issue_comments', { description: 'Get comments for a GitHub issue', inputSchema: { owner: z.string().describe('Repository owner (string, required)'), repo: z.string().describe('Repository name (string, required)'), issueNumber: z.number().describe('Issue number (number, required)'), }, }, async (args, req: any) => { try { let info = await issuesInstance.getComments(args, req.requestInfo.headers.github_token); return { content: [{ type: 'text', text: JSON.stringify(info, null, 2) }] }; } catch (error: any) { return { content: [{ type: 'text', text: `Error : ${error.message}` }], isError: true }; } } ); server.registerTool( 'create_issue', { description: 'Create a new issue in a GitHub repository', inputSchema: { owner: z.string().describe('Repository owner (string, required)'), repo: z.string().describe('Repository name (string, required)'), title: z.string().describe('Issue title (string, required)'), body: z.string().optional().describe('Issue body (string, optional)'), assignees: z.array(z.string()).optional().describe('Usernames to assign to this issue (string[], optional)'), labels: z.array(z.string()).optional().describe('Labels to apply to this issue (string[], optional)'), milestone: z.number().optional().describe('ID of the milestone to associate this issue with (number, optional)'), }, }, async (args, req: any) => { try { let info = await issuesInstance.createIssue(args, req.requestInfo.headers.github_token); return { content: [{ type: 'text', text: JSON.stringify(info, null, 2) }] }; } catch (error: any) { return { content: [{ type: 'text', text: `Error : ${error.message}` }], isError: true }; } } ); server.registerTool( 'add_issue_comment', { description: 'Add a comment to an issue', inputSchema: { owner: z.string().describe('Repository owner (string, required)'), repo: z.string().describe('Repository name (string, required)'), issueNumber: z.number().describe('Issue number (number, required)'), comment: z.string().describe('Comment text (string, required)'), }, }, async (args, req: any) => { try { let info = await issuesInstance.addComment(args, req.requestInfo.headers.github_token); return { content: [{ type: 'text', text: JSON.stringify(info, null, 2) }] }; } catch (error: any) { return { content: [{ type: 'text', text: `Error : ${error.message}` }], isError: true }; } } ); server.registerTool( 'list_issues', { description: 'List and filter repository issues', inputSchema: { owner: z.string().describe('Repository owner (string, required)'), repo: z.string().describe('Repository name (string, required)'), state: z.enum(['open', 'closed', 'all']).optional().describe("Filter by state ('open', 'closed', 'all') (string, optional)"), labels: z.array(z.string()).optional().describe('Labels to filter by (string[], optional)'), sort: z.enum(['created', 'updated', 'comments']).optional().describe("Sort by ('created', 'updated', 'comments') (string, optional)"), direction: z.enum(['asc', 'desc']).optional().describe("Sort direction ('asc', 'desc') (string, optional)"), since: z.string().optional().describe('Filter by date (ISO 8601 timestamp) (string, optional)'), page: z.number().optional().describe('Page number (number, optional)'), per_page: z.number().optional().describe('Results per page (number, optional)'), }, }, async (args, req: any) => { try { let info = await issuesInstance.listIssues(args, req.requestInfo.headers.github_token); return { content: [{ type: 'text', text: JSON.stringify(info, null, 2) }] }; } catch (error: any) { return { content: [{ type: 'text', text: `Error : ${error.message}` }], isError: true }; } } ); server.registerTool( 'update_issue', { description: 'Update an issue in a GitHub repository', inputSchema: { owner: z.string().describe('Repository owner (string, required)'), repo: z.string().describe('Repository name (string, required)'), issueNumber: z.number().describe('Issue number (number, required)'), title: z.string().optional().describe('New issue title (string, optional)'), body: z.string().optional().describe('New issue body (string, optional)'), assignees: z.array(z.string()).optional().describe('Usernames to assign to this issue (string[], optional)'), state: z.enum(['open', 'closed']).optional().describe("New issue state ('open', 'closed') (string, optional)"), milestone: z.number().optional().describe('New milestone ID (number, optional)'), labels: z.array(z.string()).optional().describe('New labels (string[], optional)'), }, }, async (args, req: any) => { try { let info = await issuesInstance.updateIssue(args, req.requestInfo.headers.github_token); return { content: [{ type: 'text', text: JSON.stringify(info, null, 2) }] }; } catch (error: any) { return { content: [{ type: 'text', text: `Error : ${error.message}` }], isError: true }; } } ); server.registerTool( 'search_issues', { description: 'Search for issues and pull requests', inputSchema: { owner: z.string().describe('Repository owner (string, required)'), repo: z.string().describe('Repository name (string, required)'), q: z.string().describe('Search query (string, required)'), sort: z.enum(['created', 'updated', 'comments']).optional().describe("Sort by ('created', 'updated', 'comments') (string, optional)"), order: z.enum(['asc', 'desc']).optional().describe("Sort order ('asc', 'desc') (string, optional)"), page: z.number().optional().describe('Page number (number, optional)'), per_page: z.number().optional().describe('Results per page (number, optional)'), fields: z.array(z.string()).optional().describe('Fields to return (string[], optional)'), }, }, async (args, req: any) => { try { let info = await issuesInstance.searchIssues(args, req.requestInfo.headers.github_token); return { content: [{ type: 'text', text: JSON.stringify(info, null, 2) }] }; } catch (error: any) { return { content: [{ type: 'text', text: `Error : ${error.message}` }], isError: true }; } } ); }

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/JesusMaster/github-see-mcp-server'

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