model context protocols
Allow to manage Issues and Project on Github
Allow to manage Issues and Project on Github
A Model Context Protocol (MCP) implementation for managing GitHub projects and issues. This package provides a seamless interface for AI assistants and applications to interact with GitHub repositories, issues, pull requests, and projects.
npm install @monsoft/mcp-github-project-manager
The quickest way to use the GitHub Project Manager is directly with npx:
npx -y @monsoft/mcp-github-project-manager --GITHUB_PERSONAL_TOKEN=your_github_token_here
This starts the MCP server which can then be connected to by MCP clients.
The GitHub Project Manager supports two transport methods:
This is the default transport, ideal for direct CLI integrations and local usage:
# Start with default Stdio transport
npx -y @monsoft/mcp-github-project-manager --GITHUB_PERSONAL_TOKEN=your_github_token_here
For remote setups and web integrations, you can use the SSE transport which starts an HTTP server:
# Start with SSE transport on default port (3010)
npx -y @monsoft/mcp-github-project-manager --GITHUB_PERSONAL_TOKEN=your_github_token_here --RUN_SSE=1
# Start with SSE transport on a custom port
npx -y @monsoft/mcp-github-project-manager --GITHUB_PERSONAL_TOKEN=your_github_token_here --RUN_SSE=1 --PORT=8080
When using SSE transport, the server will be accessible at:
http://localhost:<PORT>/sse
http://localhost:<PORT>/messages
To use this with AI assistants like Claude in Anthropic or Cursor:
# Start the MCP server in your terminal
npx -y @monsoft/mcp-github-project-manager --GITHUB_PERSONAL_TOKEN=your_github_token_here
Then configure your AI assistant to use this MCP server. The exact configuration depends on the client you're using.
To use the GitHub Project Manager in your own code:
import { GitHubProjectManager } from '@monsoft/mcp-github-project-manager';
// The token will be automatically loaded from command line arguments
const manager = new GitHubProjectManager();
// Now you can use the manager to interact with GitHub projects
When running your application, provide the GitHub token as a command-line argument:
node your-app.js --GITHUB_PERSONAL_TOKEN=your_github_token_here
You can also specify the transport type and other options:
# Use SSE transport
node your-app.js --GITHUB_PERSONAL_TOKEN=your_github_token_here --RUN_SSE=1 --PORT=3010
# Use default Stdio transport
node your-app.js --GITHUB_PERSONAL_TOKEN=your_github_token_here
If you need to programmatically start the server with specific transport options:
import {
startGitHubProjectManagerServer,
startGitHubProjectManagerServerSSE,
} from '@monsoft/mcp-github-project-manager';
// Start with Stdio transport
await startGitHubProjectManagerServer('your_github_token_here');
// Or start with SSE transport
await startGitHubProjectManagerServerSSE('your_github_token_here', 3010);
const newIssue = await manager.createIssue({
owner: 'organization-name',
repo: 'repository-name',
title: 'Issue title',
body: 'Detailed description of the issue',
labels: ['bug', 'priority-high'],
assignees: ['username1', 'username2'],
});
const issue = await manager.getIssue({
owner: 'organization-name',
repo: 'repository-name',
issue_number: 123,
});
await manager.updateIssue({
owner: 'organization-name',
repo: 'repository-name',
issue_number: 123,
title: 'Updated title',
body: 'Updated description',
state: 'closed',
});
const issues = await manager.listIssues({
owner: 'organization-name',
repo: 'repository-name',
state: 'open',
labels: ['bug'],
sort: 'created',
direction: 'desc',
});
await manager.addIssueComment({
owner: 'organization-name',
repo: 'repository-name',
issue_number: 123,
body: 'This is a comment',
});
const pr = await manager.createPullRequest({
owner: 'organization-name',
repo: 'repository-name',
title: 'Pull request title',
body: 'Description of changes',
head: 'feature-branch',
base: 'main',
});
const pullRequest = await manager.getPullRequest({
owner: 'organization-name',
repo: 'repository-name',
pull_number: 456,
});
await manager.mergePullRequest({
owner: 'organization-name',
repo: 'repository-name',
pull_number: 456,
merge_method: 'squash',
});
await manager.createPullRequestReview({
owner: 'organization-name',
repo: 'repository-name',
pull_number: 456,
event: 'APPROVE',
body: 'LGTM! Great work.',
});
const project = await manager.createProject({
owner: 'organization-name',
name: 'Project Name',
body: 'Project description',
});
await manager.addProjectItem({
project_id: 12345,
content_id: issue.id,
content_type: 'Issue',
});
const items = await manager.listProjectItems({
project_id: 12345,
});
The package provides custom error classes for handling common error scenarios:
try {
// GitHub operations
} catch (error) {
if (error instanceof MissingGitHubTokenError) {
console.error('GitHub token is missing. Please provide one via command line.');
} else if (error instanceof AuthenticationError) {
console.error('Failed to authenticate with GitHub. Check your token.');
} else if (error instanceof RateLimitError) {
console.error('GitHub API rate limit exceeded.');
} else {
console.error('An unexpected error occurred:', error.message);
}
}
Available error classes:
MissingGitHubTokenError
: Thrown when a GitHub token is not providedAuthenticationError
: Thrown when authentication failsResourceNotFoundError
: Thrown when a requested resource does not existValidationError
: Thrown when input validation failsRateLimitError
: Thrown when GitHub API rate limits are exceededNetworkError
: Thrown when network communication issues occurGitHubApiError
: General error for GitHub API issuesYour GitHub personal access token needs the following permissions:
repo
- Full access to repositoriesproject
- Access to projectsissues
- Access to issuesnpm run build
npm run validate
npm test
npm run lint
MIT
[
{
"description": "Create a new issue in a GitHub repository",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"assignees": {
"description": "GitHub usernames to assign to this issue",
"items": {
"type": "string"
},
"type": "array"
},
"body": {
"description": "Issue body/description",
"type": "string"
},
"labels": {
"description": "Labels to add to this issue",
"items": {
"type": "string"
},
"type": "array"
},
"milestone": {
"description": "Milestone number to associate with this issue",
"type": "number"
},
"owner": {
"description": "Repository owner (username or organization)",
"type": "string"
},
"repo": {
"description": "Repository name",
"type": "string"
},
"title": {
"description": "Issue title",
"type": "string"
}
},
"required": [
"owner",
"repo",
"title"
],
"type": "object"
},
"name": "create_issue"
},
{
"description": "Update an existing issue in a GitHub repository",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"assignees": {
"description": "GitHub usernames to assign",
"items": {
"type": "string"
},
"type": "array"
},
"body": {
"description": "New issue body",
"type": "string"
},
"issue_number": {
"description": "Issue number",
"type": "number"
},
"labels": {
"description": "Labels to set",
"items": {
"type": "string"
},
"type": "array"
},
"milestone": {
"description": "Milestone to set",
"type": [
"number",
"null"
]
},
"owner": {
"description": "Repository owner (username or organization)",
"type": "string"
},
"repo": {
"description": "Repository name",
"type": "string"
},
"state": {
"description": "New issue state",
"enum": [
"open",
"closed"
],
"type": "string"
},
"title": {
"description": "New issue title",
"type": "string"
}
},
"required": [
"owner",
"repo",
"issue_number"
],
"type": "object"
},
"name": "update_issue"
},
{
"description": "List issues in a GitHub repository with filtering options",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"assignee": {
"description": "Filter by assignee",
"type": "string"
},
"creator": {
"description": "Filter by creator",
"type": "string"
},
"direction": {
"description": "Sort direction",
"enum": [
"asc",
"desc"
],
"type": "string"
},
"labels": {
"description": "Filter by labels",
"items": {
"type": "string"
},
"type": "array"
},
"mentioned": {
"description": "Filter by mentioned user",
"type": "string"
},
"milestone": {
"description": "Filter by milestone number or title",
"type": "string"
},
"owner": {
"description": "Repository owner (username or organization)",
"type": "string"
},
"page": {
"description": "Page number",
"type": "number"
},
"per_page": {
"description": "Results per page",
"type": "number"
},
"repo": {
"description": "Repository name",
"type": "string"
},
"since": {
"description": "Filter by updated date (ISO 8601 format)",
"type": "string"
},
"sort": {
"description": "Sort field",
"enum": [
"created",
"updated",
"comments"
],
"type": "string"
},
"state": {
"description": "Issue state",
"enum": [
"open",
"closed",
"all"
],
"type": "string"
}
},
"required": [
"owner",
"repo"
],
"type": "object"
},
"name": "list_issues"
},
{
"description": "Get details of a specific issue in a GitHub repository.",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"issue_number": {
"description": "Issue number",
"type": "number"
},
"owner": {
"description": "Repository owner (username or organization)",
"type": "string"
},
"repo": {
"description": "Repository name",
"type": "string"
}
},
"required": [
"owner",
"repo",
"issue_number"
],
"type": "object"
},
"name": "get_issue"
},
{
"description": "Add a comment to an existing issue",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"body": {
"description": "Comment text",
"type": "string"
},
"issue_number": {
"description": "Issue number",
"type": "number"
},
"owner": {
"description": "Repository owner (username or organization)",
"type": "string"
},
"repo": {
"description": "Repository name",
"type": "string"
}
},
"required": [
"owner",
"repo",
"issue_number",
"body"
],
"type": "object"
},
"name": "add_issue_comment"
},
{
"description": "Create a new GitHub project board",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"body": {
"description": "Project description",
"type": "string"
},
"name": {
"description": "Project name",
"type": "string"
},
"owner": {
"description": "Organization name or username",
"type": "string"
}
},
"required": [
"owner",
"name"
],
"type": "object"
},
"name": "create_project"
},
{
"description": "Add an issue or pull request to a GitHub project",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"content_id": {
"description": "Issue or PR ID",
"type": "number"
},
"content_type": {
"description": "Type of content to add",
"enum": [
"Issue",
"PullRequest"
],
"type": "string"
},
"project_id": {
"description": "Project ID",
"type": "number"
}
},
"required": [
"project_id",
"content_id",
"content_type"
],
"type": "object"
},
"name": "add_project_item"
},
{
"description": "Move an item between columns in a GitHub project",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"column_id": {
"description": "Column ID to move the card to",
"type": "number"
},
"item_id": {
"description": "Card ID to move",
"type": "number"
},
"position": {
"anyOf": [
{
"enum": [
"top",
"bottom"
],
"type": "string"
},
{
"type": "number"
}
],
"description": "Position in the column (top, bottom, or specific position)"
},
"project_id": {
"description": "Project ID",
"type": "number"
}
},
"required": [
"project_id",
"item_id",
"column_id"
],
"type": "object"
},
"name": "update_project_item"
},
{
"description": "List items in a GitHub project",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"column_id": {
"description": "Column ID to filter by",
"type": "number"
},
"project_id": {
"description": "Project ID",
"type": "number"
}
},
"required": [
"project_id"
],
"type": "object"
},
"name": "list_project_items"
},
{
"description": "Create a new pull request in a GitHub repository",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"base": {
"description": "The name of the branch you want the changes pulled into",
"type": "string"
},
"body": {
"description": "Pull request body/description",
"type": "string"
},
"draft": {
"description": "Whether to create the pull request as a draft",
"type": "boolean"
},
"head": {
"description": "The name of the branch where your changes are implemented",
"type": "string"
},
"maintainer_can_modify": {
"description": "Whether maintainers can modify the pull request",
"type": "boolean"
},
"owner": {
"description": "Repository owner (username or organization)",
"type": "string"
},
"repo": {
"description": "Repository name",
"type": "string"
},
"title": {
"description": "Pull request title",
"type": "string"
}
},
"required": [
"owner",
"repo",
"title",
"head",
"base"
],
"type": "object"
},
"name": "create_pull_request"
},
{
"description": "Update an existing pull request in a GitHub repository",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"base": {
"description": "The name of the branch you want the changes pulled into",
"type": "string"
},
"body": {
"description": "New pull request body",
"type": "string"
},
"maintainer_can_modify": {
"description": "Whether maintainers can modify the pull request",
"type": "boolean"
},
"owner": {
"description": "Repository owner (username or organization)",
"type": "string"
},
"pull_number": {
"description": "Pull request number",
"type": "number"
},
"repo": {
"description": "Repository name",
"type": "string"
},
"state": {
"description": "New pull request state",
"enum": [
"open",
"closed"
],
"type": "string"
},
"title": {
"description": "New pull request title",
"type": "string"
}
},
"required": [
"owner",
"repo",
"pull_number"
],
"type": "object"
},
"name": "update_pull_request"
},
{
"description": "List pull requests in a GitHub repository with filtering options",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"base": {
"description": "Filter by base branch",
"type": "string"
},
"direction": {
"description": "Sort direction",
"enum": [
"asc",
"desc"
],
"type": "string"
},
"head": {
"description": "Filter by head branch",
"type": "string"
},
"owner": {
"description": "Repository owner (username or organization)",
"type": "string"
},
"page": {
"description": "Page number",
"type": "number"
},
"per_page": {
"description": "Results per page",
"type": "number"
},
"repo": {
"description": "Repository name",
"type": "string"
},
"sort": {
"description": "Sort field",
"enum": [
"created",
"updated",
"popularity",
"long-running"
],
"type": "string"
},
"state": {
"description": "Pull request state",
"enum": [
"open",
"closed",
"all"
],
"type": "string"
}
},
"required": [
"owner",
"repo"
],
"type": "object"
},
"name": "list_pull_requests"
},
{
"description": "Get details of a specific pull request in a GitHub repository",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"owner": {
"description": "Repository owner (username or organization)",
"type": "string"
},
"pull_number": {
"description": "Pull request number",
"type": "number"
},
"repo": {
"description": "Repository name",
"type": "string"
}
},
"required": [
"owner",
"repo",
"pull_number"
],
"type": "object"
},
"name": "get_pull_request"
},
{
"description": "Merge a pull request",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"commit_message": {
"description": "Extra detail to append to automatic commit message",
"type": "string"
},
"commit_title": {
"description": "Title for the automatic commit message",
"type": "string"
},
"merge_method": {
"description": "Merge method to use",
"enum": [
"merge",
"squash",
"rebase"
],
"type": "string"
},
"owner": {
"description": "Repository owner (username or organization)",
"type": "string"
},
"pull_number": {
"description": "Pull request number",
"type": "number"
},
"repo": {
"description": "Repository name",
"type": "string"
}
},
"required": [
"owner",
"repo",
"pull_number"
],
"type": "object"
},
"name": "merge_pull_request"
},
{
"description": "Check if a pull request has been merged",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"owner": {
"description": "Repository owner (username or organization)",
"type": "string"
},
"pull_number": {
"description": "Pull request number",
"type": "number"
},
"repo": {
"description": "Repository name",
"type": "string"
}
},
"required": [
"owner",
"repo",
"pull_number"
],
"type": "object"
},
"name": "is_pull_request_merged"
},
{
"description": "Create a review for a pull request",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"body": {
"description": "The body text of the review",
"type": "string"
},
"comments": {
"description": "Comments to post as part of the review",
"items": {
"additionalProperties": false,
"properties": {
"body": {
"description": "The text of the comment",
"type": "string"
},
"path": {
"description": "The relative path to the file being commented on",
"type": "string"
},
"position": {
"description": "The position in the diff where the comment should be placed",
"type": "number"
}
},
"required": [
"path",
"position",
"body"
],
"type": "object"
},
"type": "array"
},
"event": {
"description": "The review action to perform",
"enum": [
"APPROVE",
"REQUEST_CHANGES",
"COMMENT"
],
"type": "string"
},
"owner": {
"description": "Repository owner (username or organization)",
"type": "string"
},
"pull_number": {
"description": "Pull request number",
"type": "number"
},
"repo": {
"description": "Repository name",
"type": "string"
}
},
"required": [
"owner",
"repo",
"pull_number"
],
"type": "object"
},
"name": "create_pull_request_review"
},
{
"description": "List reviews for a pull request",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"owner": {
"description": "Repository owner (username or organization)",
"type": "string"
},
"page": {
"description": "Page number",
"type": "number"
},
"per_page": {
"description": "Results per page",
"type": "number"
},
"pull_number": {
"description": "Pull request number",
"type": "number"
},
"repo": {
"description": "Repository name",
"type": "string"
}
},
"required": [
"owner",
"repo",
"pull_number"
],
"type": "object"
},
"name": "list_pull_request_reviews"
},
{
"description": "Create a review comment for a pull request",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"body": {
"description": "The text of the review comment",
"type": "string"
},
"commit_id": {
"description": "The SHA of the commit to comment on",
"type": "string"
},
"in_reply_to": {
"description": "The comment ID to reply to",
"type": "number"
},
"owner": {
"description": "Repository owner (username or organization)",
"type": "string"
},
"path": {
"description": "The relative path to the file being commented on",
"type": "string"
},
"position": {
"description": "The position in the diff where the comment should be placed",
"type": "number"
},
"pull_number": {
"description": "Pull request number",
"type": "number"
},
"repo": {
"description": "Repository name",
"type": "string"
}
},
"required": [
"owner",
"repo",
"pull_number",
"body"
],
"type": "object"
},
"name": "create_pull_request_review_comment"
},
{
"description": "List review comments for a pull request",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"direction": {
"description": "Sort direction",
"enum": [
"asc",
"desc"
],
"type": "string"
},
"owner": {
"description": "Repository owner (username or organization)",
"type": "string"
},
"page": {
"description": "Page number",
"type": "number"
},
"per_page": {
"description": "Results per page",
"type": "number"
},
"pull_number": {
"description": "Pull request number",
"type": "number"
},
"repo": {
"description": "Repository name",
"type": "string"
},
"since": {
"description": "Only comments updated at or after this time are returned",
"type": "string"
},
"sort": {
"description": "Sort field",
"enum": [
"created",
"updated"
],
"type": "string"
}
},
"required": [
"owner",
"repo",
"pull_number"
],
"type": "object"
},
"name": "list_pull_request_review_comments"
},
{
"description": "Request reviewers for a pull request",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"owner": {
"description": "Repository owner (username or organization)",
"type": "string"
},
"pull_number": {
"description": "Pull request number",
"type": "number"
},
"repo": {
"description": "Repository name",
"type": "string"
},
"reviewers": {
"description": "Usernames of people to request a review from",
"items": {
"type": "string"
},
"type": "array"
},
"team_reviewers": {
"description": "Names of teams to request a review from",
"items": {
"type": "string"
},
"type": "array"
}
},
"required": [
"owner",
"repo",
"pull_number"
],
"type": "object"
},
"name": "request_reviewers"
},
{
"description": "Remove requested reviewers from a pull request",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"owner": {
"description": "Repository owner (username or organization)",
"type": "string"
},
"pull_number": {
"description": "Pull request number",
"type": "number"
},
"repo": {
"description": "Repository name",
"type": "string"
},
"reviewers": {
"description": "Usernames of people to remove from the review request",
"items": {
"type": "string"
},
"type": "array"
},
"team_reviewers": {
"description": "Names of teams to remove from the review request",
"items": {
"type": "string"
},
"type": "array"
}
},
"required": [
"owner",
"repo",
"pull_number",
"reviewers"
],
"type": "object"
},
"name": "remove_requested_reviewers"
},
{
"description": "Update a pull request branch with the latest upstream changes",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"expected_head_sha": {
"description": "The expected SHA of the pull request head",
"type": "string"
},
"owner": {
"description": "Repository owner (username or organization)",
"type": "string"
},
"pull_number": {
"description": "Pull request number",
"type": "number"
},
"repo": {
"description": "Repository name",
"type": "string"
}
},
"required": [
"owner",
"repo",
"pull_number"
],
"type": "object"
},
"name": "update_pull_request_branch"
}
]