Skip to main content
Glama

GHAS MCP server (GitHub Advanced Security)

index.ts5.04 kB
#!/usr/bin/env node import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; import { z } from 'zod'; import { zodToJsonSchema } from 'zod-to-json-schema'; import { listCodeScanningAlerts, listSecretScanningAlerts, listDependabotAlerts } from "./operations/security.js"; import { GitHubValidationError, GitHubResourceNotFoundError, GitHubAuthenticationError, GitHubPermissionError, GitHubRateLimitError, GitHubConflictError, isGitHubError, GitHubError, } from './common/errors.js'; import { VERSION } from "./common/version.js"; const server = new Server({ name: "github-mcp-server", version: VERSION, }, { capabilities: { tools: {}, }, }); function formatGitHubError(error: GitHubError) { let message = `GitHub API Error: ${error.message}`; if (error instanceof GitHubValidationError) { message = `Validation Error: ${error.message}`; if (error.response) { message += `\nDetails: ${JSON.stringify(error.response)}`; } } else if (error instanceof GitHubResourceNotFoundError) { message = `Not Found: ${error.message}`; } else if (error instanceof GitHubAuthenticationError) { message = `Authentication Failed: ${error.message}`; } else if (error instanceof GitHubPermissionError) { message = `Permission Denied: ${error.message}`; } else if (error instanceof GitHubRateLimitError) { message = `Rate Limit Exceeded: ${error.message}\nResets at: ${error.resetAt.toISOString()}`; } else if (error instanceof GitHubConflictError) { message = `Conflict: ${error.message}`; } return message; } server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: "list_code_scanning_alerts", description: "List the current GitHub Advanced Security code scanning alerts for a repository", inputSchema: zodToJsonSchema(z.object({ owner: z.string(), repo: z.string(), })), }, { name: "list_secret_scanning_alerts", description: "List the current GitHub Advanced Security secret scanning alerts for a repository", inputSchema: zodToJsonSchema(z.object({ owner: z.string(), repo: z.string(), })), }, { name: "list_dependabot_alerts", description: "List the current GitHub Dependabot alerts for a repository", inputSchema: zodToJsonSchema(z.object({ owner: z.string(), repo: z.string(), })), }, ], }; }); server.setRequestHandler(CallToolRequestSchema, async (request) => { try { if (!request.params.arguments) { throw new Error("Arguments are required"); } switch (request.params.name) { case "list_code_scanning_alerts": { const args = z.object({ owner: z.string(), repo: z.string() }).parse(request.params.arguments); const alerts = await listCodeScanningAlerts(args.owner, args.repo); return { content: [{ type: "text", text: JSON.stringify(alerts, null, 2) }], }; } case "list_secret_scanning_alerts": { const args = z.object({ owner: z.string(), repo: z.string() }).parse(request.params.arguments); const alerts = await listSecretScanningAlerts(args.owner, args.repo); return { content: [{ type: "text", text: JSON.stringify(alerts, null, 2) }], }; } case "list_dependabot_alerts": { const args = z.object({ owner: z.string(), repo: z.string() }).parse(request.params.arguments); const alerts = await listDependabotAlerts(args.owner, args.repo); return { content: [{ type: "text", text: JSON.stringify(alerts, null, 2) }], }; } default: throw new Error(`Unknown tool: ${request.params.name}`); } } catch (error) { if (error instanceof z.ZodError) { throw new Error(`Invalid input: ${JSON.stringify(error.errors)}`); } if (isGitHubError(error)) { throw new Error(formatGitHubError(error)); } throw error; } }); async function runServer() { const transport = new StdioServerTransport(); await server.connect(transport); console.error("GitHub MCP Server running on stdio"); } runServer().catch((error) => { console.error("Fatal error in main():", error); process.exit(1); });

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/rajbos/ghas-mcp-server'

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