Lean Github Mcp
About
The lean GitHub MCP server for Claude — 26x smaller responses, 19 tools, zero Docker required.
Details
- Author
- noushad999
- Downloads
- 202
- Categories
- Developer Tools, Automation
Jump to
Setting up with Highlight
This MCP is not yet compatible with Highlight’s one-click setup. However, you can still use it with Highlight by following these steps:
- Download and install Highlight from highlightai.com/download
- Navigate to the plugins tab and select "Add Custom Plugin"
-
Configure the plugin with the settings below
Plugin Name
Lean Github McpCommand (node, npx, python, etc.)Please refer to the README for specific instructions on how to obtain API keys or other required environment variables.
- Enable "Start Automatically" if you want the plugin to start when Highlight launches
From the repository
{
"mcpServers": {
"github-mcp-server": {
"command": "node",
"args": [
"/path/to/github-mcp-server/dist/index.js"
],
"env": {
"GITHUB_TOKEN": "your_github_token_here"
}
}
}
}
Claude Desktop / Cursor
Paste into your MCP client config file to install this server.
{
"mcpServers": {
"lean github mcp": {
"github-mcp-server": {
"command": "node",
"args": [
"/path/to/github-mcp-server/dist/index.js"
],
"env": {
"GITHUB_TOKEN": "your_github_token_here"
}
}
}
}
}
McpServers
{
"github-mcp-server": {
"command": "node",
"args": [
"/path/to/github-mcp-server/dist/index.js"
],
"env": {
"GITHUB_TOKEN": "your_github_token_here"
}
}
}
Lean GitHub MCP
Control GitHub entirely through Claude — in plain English.
Create PRs, manage issues, trigger workflows, cut releases, review diffs — without touching a browser.
26x smaller responses than the official GitHub MCP — your Claude context window goes further.
</div>
---
What is this?
This is a Model Context Protocol (MCP) server that connects Claude directly to the GitHub API. Once installed, you can manage your entire GitHub workflow through natural conversation — no GUI, no copy-pasting URLs, no context switching.
You type this in Claude:
Merge PR #47 with squash, delete the branch, then create a release v2.1.0 with those changes
Claude does all of it. Three API calls. Done.
---
Why this instead of the official GitHub MCP?
| | This Server | Official GitHub MCP |
|---|---|---|
| Setup | npm install + token | Docker required |
| Response size | ~320 avg tokens | 2000+ tokens (raw API) |
| Token efficiency | Null stripping, compactify | Raw JSON passthrough |
| Caching | 120s in-memory cache | No cache |
| Tools | 19 tools | ~30 tools |
| Default branch | Auto-detected | Hard-coded main |
| Error messages | Status codes included | Generic messages |
| License | MIT — use anywhere | MIT |
Bottom line: This server was built to be lean. Every response is stripped of nulls, truncated intelligently, and cached where it makes sense. Your Claude context window is treated as a precious resource.
---
60-Second Setup
Option 1 — Run with npx (no install needed):
GITHUB_TOKEN=ghp_your_token npx @noushad999/lean-github-mcp
Option 2 — Install globally from npm:
npm install -g @noushad999/lean-github-mcp
lean-github-mcp
Option 3 — Docker _(coming soon)_:
docker run -e GITHUB_TOKEN=ghp_your_token ghcr.io/noushad999/lean-github-mcp
Option 4 — Clone from source:
git clone https://github.com/noushad999/lean-github-mcp.git
cd lean-github-mcp
npm install && npm run build
echo "GITHUB_TOKEN=ghp_your_token" > .env
Claude Desktop — edit %APPDATA%\Claude\claude_desktop_config.json (Windows) or ~/Library/Application Support/Claude/claude_desktop_config.json (Mac):
Using npx (easiest — no install needed):
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@noushad999/lean-github-mcp"],
"env": {
"GITHUB_TOKEN": "ghp_your_token_here"
}
}
}
}
Using local build:
{
"mcpServers": {
"github": {
"command": "node",
"args": ["C:/absolute/path/to/lean-github-mcp/dist/index.js"],
"env": {
"GITHUB_TOKEN": "ghp_your_token_here"
}
}
}
}
Claude Code (CLI):
claude mcp add github -- node /absolute/path/to/lean-github-mcp/dist/index.js
Restart Claude. You're done.
---
Token Permissions Required
Go to github.com/settings/tokens?type=beta → Fine-grained token:
| Permission | Level | Used by |
|---|---|---|
| Contents | Read & Write | get_file, create_branch, delete_branch |
| Issues | Read & Write | list_issues, create_issue, assign_issue, add_comment |
| Pull requests | Read & Write | list_prs, create_pr, merge_pr, get_pr_diff |
| Actions | Read & Write | list_workflows, trigger_workflow |
| Metadata | Read | list_repos, get_repo |
---
Available Tools
Repositories
list_repos
List repositories for any user or organization.
"Show me all of vercel's public repos sorted by recent activity"
| Param | Type | Required | Default |
|---|---|---|---|
| owner | string | yes | — |
| type | owner \| member | no | owner |
---
get_repo
Get detailed stats for a specific repository.
"Tell me about facebook/react — stars, forks, language, open issues"
| Param | Type | Required |
|---|---|---|
| owner | string | yes |
| repo | string | yes |
---
Issues
list_issues
List issues with labels and assignees.
"Show all open bugs in my repo"
| Param | Type | Required | Default |
|---|---|---|---|
| owner | string | yes | — |
| repo | string | yes | — |
| state | open \| closed \| all | no | open |
---
create_issue
Create a new issue with labels.
"Create an issue titled 'Login crashes on Safari' with labels bug and priority"
| Param | Type | Required |
|---|---|---|
| owner | string | yes |
| repo | string | yes |
| title | string | yes |
| body | string | no |
| labels | string[] | no |
---
assign_issue
Add or remove assignees on an issue or PR.
"Assign issue #42 to alice and bob"
| Param | Type | Required | Default |
|---|---|---|---|
| owner | string | yes | — |
| repo | string | yes | — |
| issue_number | number | yes | — |
| assignees | string[] | yes | — |
| action | add \| remove | no | add |
---
Pull Requests
list_prs
List pull requests by state.
"What PRs are currently open in vercel/next.js?"
| Param | Type | Required | Default |
|---|---|---|---|
| owner | string | yes | — |
| repo | string | yes | — |
| state | open \| closed \| all | no | open |
---
create_pr
Create a pull request. Automatically detects the repo's default branch if base is omitted.
"Create a PR from feat/dark-mode to main titled 'Add dark mode support'"
| Param | Type | Required | Default |
|---|---|---|---|
| owner | string | yes | — |
| repo | string | yes | — |
| title | string | yes | — |
| body | string | no | — |
| head | string | yes | — |
| base | string | no | repo default |
---
get_pr_diff
Get the unified diff of a pull request — up to 200 lines.
"Show me the diff for PR #88"
| Param | Type | Required |
|---|---|---|
| owner | string | yes |
| repo | string | yes |
| pull_number | number | yes |
---
merge_pr
Merge with your chosen strategy.
"Squash-merge PR #47 with title 'feat: dark mode'"
| Param | Type | Required | Default |
|---|---|---|---|
| owner | string | yes | — |
| repo | string | yes | — |
| pull_number | number | yes | — |
| method | merge \| squash \| rebase | no | merge |
| commit_title | string | no | — |
---
Branches
create_branch
Create a branch from any base. Auto-detects default branch.
"Create branch fix/header-overflow from main"
| Param | Type | Required | Default |
|---|---|---|---|
| owner | string | yes | — |
| repo | string | yes | — |
| branch | string | yes | — |
| base | string | no | repo default |
---
delete_branch
Delete a branch — typically after merging.
"Delete the feat/dark-mode branch, it's been merged"
| Param | Type | Required |
|---|---|---|
| owner | string | yes |
| repo | string | yes |
| branch | string | yes |
---
Commits & Files
list_commits
View recent commit history with authors and timestamps.
"Show the last 5 commits on the main branch"
| Param | Type | Required | Default |
|---|---|---|---|
| owner | string | yes | — |
| repo | string | yes | — |
| branch | string | no | repo default |
| per_page | 1–10 | no | 10 |
---
get_file
Read file content from any branch. Files over 100 lines are truncated.
"Show me the contents of src/auth.ts on the dev branch"
| Param | Type | Required | Default |
|---|---|---|---|
| owner | string | yes | — |
| repo | string | yes | — |
| path | string | yes | — |
| branch | string | no | repo default |
---
search_code
Search code across GitHub.
"Find all TypeScript files using useAuth hook"
| Param | Type | Required | Default |
|---|---|---|---|
| query | string | yes | — |
| per_page | 1–10 | no | 10 |
> GitHub's code search API requires authentication and has a rate limit of ~10 requests/minute. Results are cached for 120s.
---
Comments
add_comment
Comment on any issue or pull request.
"Add a comment to PR #55 saying the deployment is ready for testing"
| Param | Type | Required |
|---|---|---|
| owner | string | yes |
| repo | string | yes |
| issue_number | number | yes |
| body | string | yes |
---
Releases
get_release
Get the latest release or look up a specific tag.
"What's the latest release of vercel/next.js?"
| Param | Type | Required | Default |
|---|---|---|---|
| owner | string | yes | — |
| repo | string | yes | — |
| tag | string | no | latest |
---
create_release
Publish a new release with release notes.
"Create release v2.1.0 on the main branch with the changelog I'll paste"
| Param | Type | Required | Default |
|---|---|---|---|
| owner | string | yes | — |
| repo | string | yes | — |
| tag_name | string | yes | — |
| name | string | no | tag name |
| body | string | no | — |
| draft | boolean | no | false |
| prerelease | boolean | no | false |
| target_commitish | string | no | repo default |
---
GitHub Actions
list_workflows
List all workflows in a repository.
"What GitHub Actions workflows does this repo have?"
| Param | Type | Required |
|---|---|---|
| owner | string | yes |
| repo | string | yes |
---
trigger_workflow
Trigger a workflow dispatch event with optional inputs.
"Trigger the deploy.yml workflow on the staging branch"
| Param | Type | Required | Default |
|---|---|---|---|
| owner | string | yes | — |
| repo | string | yes | — |
| workflow_id | string \| number | yes | — |
| ref | string | no | repo default |
| inputs | object | no | {} |
---
How It Works
You (natural language)
│
▼
Claude AI
│ MCP Protocol (stdio)
▼
┌──────────────────────────────────┐
│ lean-github-mcp │
│ │
│ ┌─────────────────────────┐ │
│ │ 19 Tool Handlers │ │
│ └────────┬────────────────┘ │
│ │ │
│ ┌────────▼─────┐ ┌──────────┐ │
│ │ Token Guard │ │ Cache │ │
│ │ 4000 char │ │ 120s │ │
│ │ null strip │ │ 200 max │ │
│ └────────┬─────┘ └────┬─────┘ │
│ └──────┬───────┘ │
│ ▼ │
│ ┌──────────────────┐ │
│ │ GitHub Client │ │
│ │ Axios + Auth │ │
│ │ Status codes │ │
│ └──────────────────┘ │
└──────────────┬───────────────────┘
│ HTTPS
▼
api.github.com
Token Efficiency — Why It Matters
Every response the MCP server sends consumes your Claude context window. Bloated responses mean Claude forgets earlier parts of your conversation faster. This server aggressively minimizes response size:
Raw GitHub API response for a single repository:
{
"id": 1296269,
"node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5",
"name": "Hello-World",
"full_name": "octocat/Hello-World",
"private": false,
"owner": {
"login": "octocat",
"id": 1,
"node_id": "MDQ6VXNlcjE=",
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
"gravatar_id": "",
"url": "https://api.github.com/users/octocat",
"html_url": "https://github.com/octocat",
"followers_url": "...",
... 20 more owner fields
},
"html_url": "https://github.com/octocat/Hello-World",
"description": "This your first repo!",
... 80+ more fields, mostly null
}
~2,400 tokens
This server's response:
{
"name": "Hello-World",
"full_name": "octocat/Hello-World",
"description": "This your first repo!",
"stars": 2045,
"forks": 1731,
"language": "JavaScript",
"open_issues": 12,
"updated_at": "2024-01-15T10:30:00Z",
"html_url": "https://github.com/octocat/Hello-World"
}
~90 tokens — 26x smaller
---
Real-World Example Conversations
Full PR workflow:
You: Show me open PRs in my-org/my-repo
Claude: Found 3 open PRs:
#88 — "Add OAuth2 support" by sarah_dev
#91 — "Fix memory leak in worker" by john_k
#94 — "Upgrade to Node 22" by bot
You: Show me the diff for #91
Claude: [shows unified diff of the memory leak fix]
You: Looks good. Merge it with squash, then delete the branch
Claude: Done — squash merged PR #91 (sha: a3f9c21), deleted branch fix/memory-leak
You: Now create a release v3.2.1 from main with changelog: "Fixed memory leak in background workers"
Claude: Release v3.2.1 published — https://github.com/my-org/my-repo/releases/tag/v3.2.1
Four separate GitHub operations. One conversation.
---
Automated triage:
You: List open issues in my-org/api-server, assign the ones labeled "bug" to me
Claude: Found 4 open issues. 2 have the "bug" label (#34, #41).
Assigned #34 and #41 to you.
---
Testing
npm run build
npx tsx tests/simulate-10-users.ts
Expected output:
╔══════════════════════════════════════════════════════════╗
║ GitHub MCP Server - 10 User Deployment Test ║
║ 19 Tools · Full Coverage Simulation ║
╚══════════════════════════════════════════════════════════╝
...
║ Total Tests: 49 ║
║ Passed: 49 ║
║ Failed: 0 ║
║ Pass Rate: 100.0 % ║
║ Null Fields Found: 0 ║
║ Avg Response: 319 tokens ║
╚══════════════════════════════════════════╝
🎉 ALL TESTS PASSED! Ready for production.
You can also inspect live with the MCP Inspector:
npx @modelcontextprotocol/inspector node dist/index.js
---
Project Structure
lean-github-mcp/
├── src/
│ ├── index.ts # MCP server entry, tool registration
│ ├── github-client.ts # Axios client + getDefaultBranch helper
│ ├── middleware/
│ │ └── tokenGuard.ts # Response trimmer: null strip, compactify, 4000 char limit
│ ├── utils/
│ │ └── cache.ts # 120s TTL in-memory cache, max 200 entries
│ └── tools/ # 19 tool handlers (one file each)
│ ├── list_repos.ts
│ ├── get_repo.ts
│ ├── list_issues.ts
│ ├── create_issue.ts
│ ├── assign_issue.ts
│ ├── list_prs.ts
│ ├── create_pr.ts
│ ├── get_pr_diff.ts
│ ├── merge_pr.ts
│ ├── create_branch.ts
│ ├── delete_branch.ts
│ ├── list_commits.ts
│ ├── get_file.ts
│ ├── search_code.ts
│ ├── add_comment.ts
│ ├── get_release.ts
│ ├── create_release.ts
│ ├── list_workflows.ts
│ └── trigger_workflow.ts
├── tests/
│ └── simulate-10-users.ts # Full simulation test, 49 assertions
├── dist/ # Compiled JS (after npm run build)
├── package.json
├── tsconfig.json
└── .env.example
---
Troubleshooting
GITHUB_TOKEN not set
cat .env # make sure GITHUB_TOKEN=ghp_... is there
GitHub API (403): Rate limited or insufficient permissions
- Fine-grained tokens need explicit repository access — check the permissions table above
- Code search has a stricter limit (~10 req/min) — wait 60s and retry
GitHub API (404): Resource not found
- Double-check the owner and repo spelling
- Private repos need your token to have access to them
GitHub API (422): Unprocessable
- Usually means a PR already exists for that branch, or a branch name is invalid
Command not found: node in Claude Desktop
- Use the full path: C:\Program Files\nodejs\node.exe (Windows) or run which node on Mac/Linux
---
Contributing
Contributions are welcome — see CONTRIBUTING.md for a step-by-step guide to adding new tools, code conventions, and the PR checklist.
---
Roadmap
- [ ] list_workflow_runs — view CI status for a branch
- [ ] get_commit — detailed single commit with files changed
- [ ] compare_branches — diff between two branches
- [ ] update_file — commit a file change directly
- [ ] add_label / remove_label — label management
Open an issue if you want something added.
---
License
MIT — do whatever you want with it.
---
<div align="center">
Built for developers who'd rather talk to Claude than click through GitHub.
Report a bug · Request a feature
</div>
Sign in to leave a review
Use Google, GitHub, or an email account so ratings stay tied to real people.
No reviews posted yet.


