GitHub Projects MCP Server

import { Octokit } from "@octokit/core"; import { paginateGraphQL } from "@octokit/plugin-paginate-graphql"; import { restEndpointMethods } from "@octokit/plugin-rest-endpoint-methods"; // Create custom Octokit with plugins const CustomOctokit = Octokit.plugin(restEndpointMethods, paginateGraphQL); /** * GitHub client using Octokit for interacting with GitHub APIs */ export class GitHubClient { private octokit: InstanceType<typeof CustomOctokit>; /** * Create a new GitHub client */ constructor() { const token = process.env.GITHUB_TOKEN; if (!token) { throw new Error("GITHUB_TOKEN environment variable is required"); } // Initialize Octokit instance this.octokit = new CustomOctokit({ auth: token, }); } /** * Make a GraphQL request to the GitHub API */ async graphql< TData, TVariables extends Record<string, unknown> = Record<string, unknown>, >(query: string, variables: TVariables): Promise<TData> { try { return this.octokit.graphql<TData>(query, variables); } catch (error) { console.error("GraphQL error:", error); throw error; } } /** * Make a paginated GraphQL request with automatic handling of pagination */ async paginateGraphql<T extends object>( query: string, variables: Record<string, unknown> = {}, pageInfo: { pageSize?: number } = {}, ): Promise<T> { try { return await this.octokit.graphql.paginate<T>(query, { ...variables, pageSize: pageInfo.pageSize || 20, }); } catch (error) { console.error("Paginated GraphQL error:", error); throw error; } } /** * Make a REST request to the GitHub API */ async rest<T>( method: string, path: string, parameters: Record<string, unknown> = {}, ): Promise<T> { try { const response = await this.octokit.request( `${method.toUpperCase()} ${path}`, parameters, ); return response.data as T; } catch (error) { console.error("REST error:", error); throw error; } } }