TypeScript MCP server that exposes 5 GitHub tools over stateless Streamable HTTP.
No sessions / no mcp-session-id — each POST is independent (good for gateways and multi-instance deploy).
The GitHub access-token header is required only for tools/call.
initialize, tools/list, and other discovery methods work without a token.
| Tool | Description |
|---|---|
get_me |
Authenticated user for the token |
get_repository |
Repository metadata (owner, repo) |
get_file_contents |
File or directory contents (owner, repo, path, optional ref) |
list_issues |
List issues (PRs filtered out) |
create_issue |
Create an issue (title, optional body, labels, assignees) |
- Node.js 18+
- A GitHub personal access token (classic or fine-grained) with the scopes your tools need
- Read tools:
repo(or public-only fine-grained read) create_issue: issues write on the target repo
- Read tools:
npm install
npm run build
npm startDev (no build step):
npm run devdocker build -t github-mcp .
docker run --rm -p 3000:3000 github-mcpMCP endpoint: http://localhost:3000/mcp.
Server listens on http://localhost:3000/mcp (override with PORT).
| MCP method | access-token required? |
|---|---|
initialize, tools/list, ping, notifications |
No |
tools/call |
Yes |
On tool calls, send a GitHub personal access token:
access-token: ghp_your_token_hereAlternatively:
Authorization: Bearer ghp_your_token_hereMissing token on tools/call → 401 JSON-RPC error.
Point any Streamable HTTP MCP client at:
http://localhost:3000/mcp
Send the GitHub token on tool-call requests (many clients set it for all requests to the server):
{
"mcpServers": {
"github": {
"url": "http://localhost:3000/mcp",
"headers": {
"access-token": "ghp_your_token_here"
}
}
}
}(Exact client config shape depends on the client.)
curl http://localhost:3000/healthsrc/
index.ts # Express + stateless Streamable HTTP (POST only), access-token middleware
server.ts # McpServer factory
tools.ts # 5 tool registrations
github.ts # GitHub REST client
context.ts # AsyncLocalStorage for per-request token
MIT