Skip to main content
Glama
PaulliDev

GitHub Issues MCP Server

by PaulliDev

GitHub Issues MCP Server

A Model Context Protocol (MCP) server in TypeScript that lets Claude, Cursor, or any MCP client list, create, search, and comment on GitHub issues.

This is the companion code for the Snippets Ltd tutorial Building a Custom MCP Server in TypeScript. Read the article for the step-by-step explanation.

What it exposes

Type

Name

What it does

Tool

list_issues

List open, closed, or all issues (pull requests excluded), most recently updated first

Tool

create_issue

Create an issue with a title, body, and labels

Tool

add_comment

Comment on an existing issue

Tool

search_issues

Search issues with GitHub search syntax

Resource

repo://readme

The repository README

Resource

repo://issues/recent

The 10 most recently updated open issues

Related MCP server: github-mcp-server

Prerequisites

Setup

git clone https://github.com/PaulliDev/github-issues-mcp.git
cd github-issues-mcp
npm install
cp .env.example .env   # then fill in GITHUB_TOKEN, GITHUB_OWNER, GITHUB_REPO
npm run build

Run it

Command

What it does

npm run inspect

Opens the MCP Inspector in your browser, connected to the server over stdio

npm start

Runs the stdio server (what desktop clients spawn)

npm run start:http

Runs the Streamable HTTP server on PORT (default 3001), protected by MCP_AUTH_TOKEN

Call the HTTP server

Add MCP_AUTH_TOKEN to .env, run npm run start:http, then from another terminal:

curl -s http://localhost:3001/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H 'Authorization: Bearer <your MCP_AUTH_TOKEN>' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Every MCP message is a POST to /mcp with a JSON-RPC body. Replies arrive as Server-Sent Events (event: message / data: {...}). Without the header you get 401; GET returns 405. The MCP Inspector can also connect: choose Streamable HTTP, URL http://localhost:3001/mcp, and add the Authorization header. To publish online, run it on any Node host behind HTTPS.

Connect to Claude Desktop

Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "github-issues": {
      "command": "node",
      "args": ["/absolute/path/to/github-issues-mcp/dist/index.js"],
      "env": {
        "GITHUB_TOKEN": "github_pat_your_token_here",
        "GITHUB_OWNER": "your-org",
        "GITHUB_REPO": "your-repo"
      }
    }
  }
}

Restart Claude Desktop and ask things like "show me open issues labeled bug".

Project structure

src/
├── index.ts                  # stdio entry point
├── http-server.ts            # Streamable HTTP entry point (auth + rate limiting)
├── server.ts                 # createServer(): registers tools and resources
├── configuration.ts          # loads .env and validates environment variables
├── github-client.ts          # GitHub REST API wrapper
├── types.ts                  # shared and GitHub API types
├── tools/                    # Zod input schemas, one file per tool
└── security/
    ├── sanitize-tool-output.ts
    └── create-authentication-middleware.ts

Security notes

  • Tool results contain text written by anyone who can open an issue. The server filters common prompt-injection phrases, but your client should still treat tool output as untrusted.

  • The HTTP server refuses to start without MCP_AUTH_TOKEN. Use a long random value.

  • Give the GitHub token the fewest permissions possible.

License

MIT

Available Tools

4 tools
add_commentB

Add a comment to an existing issue.

ParametersJSON Schema
NameRequiredDescriptionDefault
bodyYesThe comment body. Supports markdown.
issueNumberYesThe issue number to comment on.

TDQS

B3.4/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. The verb 'Add' indicates a mutating operation, but the description does not disclose permissions, idempotency, side effects, error behavior, or what happens when the issue does not exist. This is a significant gap for a write operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single clear sentence with no filler or redundant content. It is concise and front-loaded, though it leans toward underspecification rather than efficient completeness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple with only two required parameters and full schema coverage, so the core invocation is clear. However, the lack of annotations, output schema, and behavioral details leaves gaps around expected outcomes and failure modes that a fuller description could address.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with both parameters documented in the schema: issueNumber and body. The description itself adds no parameter-level detail, but since the schema covers both parameters, the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource: 'Add a comment to an existing issue.' It clearly distinguishes this tool from sibling tools like create_issue, list_issues, and search_issues, since adding a comment is a distinct action on an existing issue rather than creating, listing, or searching issues.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'existing issue' implies the tool is for commenting on already-created issues, which provides some usage context. However, it does not explicitly state when to choose this tool over alternatives, nor does it mention exclusions or preconditions beyond requiring an existing issue number.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_issueB

Create a new issue in the GitHub repository.

ParametersJSON Schema
NameRequiredDescriptionDefault
bodyYesThe body content of the issue. Supports markdown.
titleYesThe title of the issue to create.
labelsNoLabels to apply to the issue.

TDQS

B3.3/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden of behavioral disclosure, but it only says 'create' without detailing side effects, permissions, idempotency, or response behavior. This is a mutation operation, yet an agent gets no information about what happens after creation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no filler or redundancy. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a low-complexity tool with fully documented parameters, the concise purpose statement is mostly adequate. However, because there are no annotations and no output schema, the lack of any behavioral or return-value context leaves minor gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the input schema already explains title, body, and labels. The description adds no parameter-level detail, so it meets the baseline for fully documented schemas.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description uses a specific verb ('Create') and resource ('issue in the GitHub repository'), making the operation unambiguous. The create action clearly separates it from siblings like list_issues, search_issues, and add_comment.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is given about when to choose this tool over alternatives or about prerequisites such as repository access. The description only restates the operation rather than providing decision context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_issuesA

List issues in the GitHub repository, most recently updated first. Returns issue number, title, state, author, and labels.

ParametersJSON Schema
NameRequiredDescriptionDefault
stateNoFilter issues by state. Defaults to open issues.open

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the behavioral disclosure burden. 'List' signals a non-mutating read operation, and the description adds useful behavioral details: sort order and the specific fields returned. It doesn't mention pagination or access requirements, but nothing suggests hidden side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two focused sentences: the first states the action and ordering, the second lists return fields. Every sentence adds value and there is no redundant detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter read tool with no output schema, the description provides the essential return fields and ordering. It omits pagination details and doesn't address how the repository is scoped, but those are minor and the tool remains callable with the state parameter alone.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema fully documents the only parameter, 'state', including its enum values and default. The description adds no parameter-specific information, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the action ('List'), the resource ('issues in the GitHub repository'), and adds a helpful ordering detail ('most recently updated first'). It doesn't explicitly distinguish itself from search_issues, but the verb and return fields make the basic purpose clear.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no guidance on when to use list_issues rather than search_issues, create_issue, or add_comment. There is no mention of alternatives or conditions, so the agent must infer the appropriate use case from the tool name alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_issuesA

Search for issues in this repository using GitHub search syntax (for example label:bug is:open).

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYesSearch query to find issues in this repository. Supports GitHub search syntax such as label:bug or is:open, but not repo:, org:, or user:.

TDQS

A3.8/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of disclosing behavioral traits. It only restates that it searches, adds an example, and gives a caveat about unsupported qualifiers (already covered in the schema). It does not disclose any side effects, return format, pagination, rate limits, or error behavior. This is a significant gap for a tool with no structured safety hints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence with no filler. It front-loads the action and resource, provides a concrete example, and adds a clarifying constraint. Every word contributes to the tool's usability, making it highly concise and well-structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (one parameter, no output schema, no annotations), the description is largely complete for calling the tool correctly. It explains the purpose and gives syntax guidance, and the schema covers parameter constraints. However, it omits any mention of result limits or what a successful call returns, which could be relevant for an agent expecting a full list. This minor gap keeps it from a 5.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The tool description adds a concrete example of query syntax, but that is largely redundant with the schema's own description (which already mentions label:bug and is:open and explicitly excludes repo:, org:, user:). The description does not meaningfully enrich the parameter semantics beyond what the schema provides, so it stays at baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states a specific verb ('Search') and resource ('issues in this repository'), and includes an example of the search syntax. It distinguishes itself from sibling tools like list_issues (which would list all issues) and create_issue/add_comment (which are actions, not searches). The purpose is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context that this tool searches within the repository, and the example implies it is for finding specific issues rather than listing all. However, it does not explicitly mention when to use this over list_issues or other alternatives, nor does it state exclusions (e.g., 'for all issues, use list_issues'). Thus it earns a 4 rather than a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 4 tool updatesv1.0.0
    • First observedadd_comment
    • First observedcreate_issue
    • First observedlist_issues
    • First observedsearch_issues

TDQS

A3.6/5.0

Scored across 4 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: listing, creating, commenting, and searching. There is no meaningful overlap between list_issues (broad browsing) and search_issues (query-based filtering), and the descriptions make this distinction explicit.

Naming Consistency5/5

All four tool names follow a consistent verb_noun snake_case pattern: list_issues, create_issue, add_comment, search_issues. The naming is predictable and immediately communicates the action and target.

Tool Count3/5

With only 4 tools, the server is quite focused but still covers core issue interaction. The count is on the low end but not unreasonably thin for a single-purpose GitHub issues server, so it earns a borderline score.

Completeness3/5

The server covers listing, creating, commenting, and searching issues, which handles the most common workflows. However, it lacks obvious lifecycle operations like updating, closing, or fetching a single issue, leaving notable gaps that agents cannot work around without external tools.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables natural language interaction with GitHub through an MCP server. Supports reading repos, issues, and PRs, as well as creating and editing issues with user confirmation.
    -
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to interact with GitHub via MCP, managing repositories, issues, PRs, and analyzing repository health through tools like list_repositories, read_issues, create_issue, comment_on_pr, and analyze_repo_health.
    -