# OpenCollab MCP
**Find your next open source contribution from your AI chat.**
[](https://pypi.org/project/opencollab-mcp/)
[](https://www.python.org/downloads/)
[](https://github.com/prakhar1605/Opencollab-mcp/actions/workflows/ci.yml)
[](LICENSE)
6 focused tools. Works with Claude Desktop, Cursor, VS Code, or any MCP-compatible client.
[Changelog](CHANGELOG.md) · [Contributing](CONTRIBUTING.md)
---
## What it does
You ask your AI assistant something like:
> *"My GitHub is `@octocat`. Find me a good first issue I can actually pick up — make sure nobody's already working on it."*
OpenCollab gives the AI 6 tools that read the GitHub API. The AI uses them to:
1. **Find** issues matched to your skills.
2. **Evaluate** whether the repo is worth your time.
3. **Verify** the issue isn't already claimed.
4. **Plan** the PR with full context.
That's the whole loop: **find → evaluate → verify → plan**. OpenCollab does not generate text. Your AI client does the thinking; OpenCollab just gives it clean, real-time GitHub data.
> **v0.6.0 — relaunched lean.** Previous versions exposed 22 tools. Most went unused, and big tool lists hurt LLM routing. This release ships the 6 that earn their keep. The full 22-tool version is preserved on the [`v1-full`](https://github.com/prakhar1605/Opencollab-mcp/tree/v1-full) branch.
---
## Quick start
### Step 1 — Get a GitHub token
Go to [github.com/settings/tokens](https://github.com/settings/tokens) → **Generate new token (classic)** → tick `public_repo` → copy the token (it starts with `ghp_`).
### Step 2 — Add it to your AI client
Claude Desktop (recommended)
Open your config file:
- **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
Paste this (replace `your_token_here` with the token from Step 1):
```json
{
"mcpServers": {
"opencollab": {
"command": "uvx",
"args": ["opencollab-mcp"],
"env": {
"GITHUB_TOKEN": "your_token_here"
}
}
}
}
```
Restart Claude Desktop. You're done.
> Requires [`uv`](https://docs.astral.sh/uv/) (`brew install uv` on macOS, `pipx install uv` elsewhere). `uvx` will pull `opencollab-mcp` from PyPI on first launch.
Cursor / VS Code
Same JSON as above, but in your client's MCP config file (`.cursor/mcp.json` for Cursor).
Claude Code
Run this in your terminal (replace `ghp_your_token_here` with the token from Step 1):
```bash
claude mcp add opencollab -e GITHUB_TOKEN=ghp_your_token_here -- uvx opencollab-mcp
```
Check it's connected:
```bash
claude mcp list
```
Or run `/mcp` inside a Claude Code session.
Plain pip (no uv)
```bash
pip install opencollab-mcp
```
Then in your client config, change `command` to the binary that pip put on your PATH:
```json
{
"mcpServers": {
"opencollab": {
"command": "opencollab-mcp",
"env": {
"GITHUB_TOKEN": "your_token_here"
}
}
}
}
```
Note: if you switch Python versions or virtualenvs, the `opencollab-mcp` binary may disappear and you'll need to `pip install` again. `uvx` avoids this.
Docker (for remote / streamable-HTTP setups)
```bash
docker build -t opencollab-mcp .
docker run -e GITHUB_TOKEN=ghp_xxx -p 8000:8000 opencollab-mcp
```
The container runs as a non-root user with `TRANSPORT=streamable-http` on port 8000.
For an SSE client, use `-e TRANSPORT=sse`; both remote transports bind to
`0.0.0.0` and accept `PORT` (default `8000`).
`GET /health` returns `ok`; the image's `HEALTHCHECK` probes it on the configured `PORT`.
**Using Docker Compose**
Create a `.env` file from the example:
```bash
cp .env.example .env
```
Open `.env` and replace the placeholder with your GitHub token. Do not commit `.env`.
Start the service:
```bash
docker compose up --build -d
```
Check the service health:
```bash
curl http://localhost:8000/health
```
To stop the service:
```bash
docker compose down
```
### Step 3 — Try it
Open your AI client and ask:
> *"My GitHub username is ``. Find me a good first issue I can pick up."*
If the AI runs `opencollab_match_me` and comes back with a list, you're set.
---
## What you can ask
These are real things the AI can answer once OpenCollab is connected:
- *"My GitHub is `@octocat` — find me a good first issue."*
- *"Find me a Python good-first-issue."*
- *"How healthy is `pandas-dev/pandas`? Is it worth contributing to?"*
- *"What's the impact tier of contributing to `tensorflow/tensorflow`?"*
- *"Is issue #123 in `facebook/react` still available, or has someone claimed it?"*
- *"Plan a PR for issue #456 in `owner/repo` — pull all the context the AI needs."*
The AI picks which tools to call based on what you ask.
---
## The 6 tools
Discovery — find issues to work on
| Tool | What it does |
|---|---|
| `opencollab_match_me` | Reads your GitHub profile, detects your top language, returns up to 10 matching unassigned issues (adjustable with `limit`, 1–30) — beginner (`good first issue`) or intermediate (`help wanted`) via `difficulty` — all in one call. |
| `opencollab_find_issues` | Up to 15 unassigned issues (adjustable with `limit`, 1–30) created within `max_age_days` (default 90, range 1–365) for a given language, with beginner (`good first issue`) and intermediate (`help wanted`) difficulty filters and sorting via `sort` (`newest` [default], `recently_updated`, or `least_discussed`). Optional `exclude_repos` omits up to 10 `owner/name` repositories (default empty). Each issue includes `updated_days_ago` (days since last activity; `null` if missing or unparseable). |
`opencollab_match_me` scans up to 100 most recently pushed public repositories,
excluding forks from language analysis. If the scan is incomplete, its response
includes `repos_analyzed` (the raw number returned, including forks), `repos_total`
and a `note` explaining the limit. These fields are omitted for a complete scan;
the separate Python fallback note still appears when no language is detected.
Evaluation — score a repo before you invest time
| Tool | What it does |
|---|---|
| `opencollab_repo_health` | 0–100 contributor-friendliness score: activity, PR merge rate, community files, forks. Archived repos get an "Archived — read-only" verdict; `community_profile_available` says whether community-file data could be read. |
| `opencollab_impact_estimator` | Impact tier (LOW → MASSIVE) based on stars + reach, plus a draft resume line. |
Issue intelligence — verify and plan a specific issue
| Tool | What it does |
|---|---|
| `opencollab_check_issue_availability` | Is the issue still open? Assigned? Already has an open or merged closing PR? Uses GraphQL `closedByPullRequestsReferences` when authenticated (falling back to closing-keyword matching across paginated REST timeline pages), separates plain mentions into `mentioned_in_prs`, and reports `linked_prs_checked`, `linked_prs_source`, and `timeline_truncated` when the timeline cap is reached. |
| `opencollab_generate_pr_plan` | Bundles the issue body, comments, CONTRIBUTING.md, PR template preview (`null` when unavailable), and repo layout for the AI to plan a fix. Returns an error for pull request numbers. |
---
## How it works
```
You ask Claude → Claude picks tools → OpenCollab hits GitHub API → JSON back to Claude → Claude answers in plain English
```
A few design choices worth knowing:
- **No AI inference on our end.** OpenCollab is a thin wrapper over the GitHub REST API. Your AI client (Claude / Cursor / etc.) does all the reasoning. Cost to run OpenCollab: $0.
- **Runs locally by default.** Stdio transport — no servers, no telemetry. Your token never leaves your machine.
- **5-minute in-memory cache.** Repeat lookups in the same conversation don't re-hit GitHub. Helps stay under rate limits.
- **Parallel API calls.** The heavy tools (`match_me`, `repo_health`, `generate_pr_plan`) fan out their GitHub requests with `asyncio.gather`, so they're noticeably faster than sequential.
- **Pydantic-validated inputs.** Every tool input is a Pydantic model with `extra="forbid"`. Catches stray fields from LLM-generated tool calls before any logic runs.
---
## Authentication & rate limits
The server uses `GITHUB_TOKEN` when non-empty, otherwise it falls back to
`GH_TOKEN` (also used by the GitHub CLI). Surrounding whitespace is stripped
from either value; when neither provides a token, requests are unauthenticated.
OpenCollab needs a GitHub token for two reasons:
1. **Higher rate limit.** Authenticated requests get 5,000/hour vs 60/hour unauthenticated.
2. **Some endpoints need auth.** A few tools (`/timeline`, etc.) may not work without it.
Scopes needed: just `public_repo`. OpenCollab never writes anything — it's all reads.
---
## Troubleshooting
### Which version am I running?
```bash
opencollab-mcp --version # or: opencollab-mcp -V
```
Include this output when you report a bug. If the flag isn't recognised, you're on an older release; upgrade (see the next item).
### `uvx` keeps running an old version
`uvx` caches packages, so it can keep using a stale copy. Force the newest release with either:
```bash
uvx --refresh opencollab-mcp
uvx opencollab-mcp@latest
```
In an MCP client config, use `"args": ["--refresh", "opencollab-mcp"]` (or `"opencollab-mcp@latest"`).
### Rate-limit errors
Symptom: a tool returns
```
Error: GitHub API rate limit exceeded. Resets in ~N minutes. Set GITHUB_TOKEN for a 5,000 requests/hour limit.
```
Fix: set `GITHUB_TOKEN` (see [Authentication & rate limits](#authentication--rate-limits)). Without a token you get 60 requests/hour; with one, 5,000. If the token is already set, restart your MCP client so it picks up the environment variable.
### Docker container shows "unhealthy"
The health check calls `/health` on `PORT` inside the container. Check that:
1. `PORT` matches the port you publish. If you set `-e PORT=9000`, publish `-p 9000:9000`.
2. `/health` responds:
```bash
curl localhost:8000/health # expected output: ok
```
3. The container is running in HTTP mode (`TRANSPORT=streamable-http`, the image default). In `stdio` mode there is no `/health` endpoint.
### Where are the logs?
Logs go to **stderr** (stdout is reserved for the MCP protocol in stdio mode). For more detail, set `OPENCOLLAB_LOG_LEVEL`:
```bash
OPENCOLLAB_LOG_LEVEL=DEBUG opencollab-mcp
```
Valid levels: `DEBUG`, `INFO` (default), `WARNING`, `ERROR`, `CRITICAL`. In Docker, read them with `docker logs `. Most MCP clients also keep a per-server log; check your client's MCP log viewer.
---
## Develop
```bash
git clone https://github.com/prakhar1605/Opencollab-mcp.git
cd Opencollab-mcp
pip install -e ".[dev]"
export GITHUB_TOKEN="ghp_xxx"
# Run the server (stdio mode, for piping into MCP clients)
python -m opencollab_mcp
# Run the test suite
pytest -v
# Lint
ruff check src tests
# Inspect interactively in the MCP Inspector
npx @modelcontextprotocol/inspector python -m opencollab_mcp
```
### Project layout
```
src/opencollab_mcp/
├── server.py # entry point, transport selection (stdio / HTTP / SSE)
├── github_client.py # cached httpx wrapper, friendly error mapping
├── helpers.py # date math, base64 decode, issue-number parser
├── models.py # Pydantic input models
├── constants.py # scoring thresholds & magic numbers
└── tools/
├── discovery.py # 2 tools — finding issues
├── evaluation.py # 2 tools — scoring a repo
└── issues.py # 2 tools — verifying & planning an issue
tests/ # pytest suite
```
### Contributing
Issues and PRs are welcome. The codebase is small (~1000 lines) and intentionally easy to read. Every scoring threshold lives in `constants.py` so tuning is a one-line change. New tools follow the same pattern: a function in `tools/.py`, a Pydantic input model in `models.py`, and a test in `tests/test_tools.py`.
Please read the [Code of Conduct](CODE_OF_CONDUCT.md) before contributing.
When reporting bugs or submitting issues, please include the version of `opencollab-mcp` you are running (especially when using `uvx` caches):
```bash
opencollab-mcp --version
```
*(or `opencollab-mcp -V`)*
The `main` branch is protected — please open a PR rather than pushing directly. CI runs on Python 3.10, 3.11, 3.12, and 3.13.
---
## Roadmap
Already shipped (v0.6.0):
- 6 focused tools across discovery, evaluation, and issue intelligence
- PyPI release (`pip install opencollab-mcp` / `uvx opencollab-mcp`)
- 5-minute in-memory cache + parallel API calls
- pytest suite on Python 3.10/3.11/3.12/3.13 in CI
- Stdio (local) and streamable-HTTP (remote) transports
- Branch protection + required CI checks on `main`
Merged since v0.6.1 (see the [Changelog](CHANGELOG.md)):
- Migrated to the MCP 2.x server API
- `GET /health` endpoint for the HTTP transports, used by the Docker `HEALTHCHECK`
- Validated tool inputs: GitHub usernames, repo names and issue numbers are checked before any request
Open ideas:
- `first_pr_generator` — chain `match_me` + `check_issue_availability` + `generate_pr_plan` into one prompt
- `track_my_prs` — list your open PRs with staleness nudges
- `skill_gap` — compare your skills to a repo's tech stack and tell you what to learn
If any of these sound interesting, [open an issue](https://github.com/prakhar1605/Opencollab-mcp/issues/new) — that's the fastest path in.
---
## Why only 6 tools?
Earlier versions shipped 22. In practice:
- LLMs route worse with crowded tool lists — they pick generic tools and miss the killer ones.
- Most of the 22 overlapped (5 different "find issues" variants, 3 different "score this repo" variants).
- The 6 that survive form a clean story: **find → evaluate → verify → plan**.
The full 22-tool catalogue still lives on the [`v1-full`](https://github.com/prakhar1605/Opencollab-mcp/tree/v1-full) branch if you want it.
---
## Contributors
New to open source? Start with an open [good first issue](https://github.com/prakhar1605/Opencollab-mcp/issues?q=is%3Aissue%20is%3Aopen%20label%3A%22good%20first%20issue%22).
---
## License
[MIT](LICENSE) — built by [Prakhar Pandey](https://github.com/prakhar1605), IIT Guwahati.
If OpenCollab helps you land your first PR, a ⭐ on the repo would mean a lot.