Octoswitch
by ApiCartOps
README.md
<p align="center"><img src="https://raw.githubusercontent.com/ApiCartOps/github-multi-mcp/main/assets/logo.svg" width="96" alt="Octoswitch logo"></p>
<h1 align="center">Octoswitch</h1>
<p align="center"><b>One MCP server, every GitHub account.</b><br>Routes each call to the right token, for any AI agent.</p>
<p align="center"><img alt="license" src="https://img.shields.io/badge/license-MIT-2dd4bf"> <img alt="node" src="https://img.shields.io/badge/node-%3E%3D20-2dd4bf"> <img alt="MCP" src="https://img.shields.io/badge/MCP-stdio-2dd4bf"></p>
An MCP server and CLI for GitHub that manages **multiple accounts** (personal, work, orgs) and routes each call to the right token. It speaks plain MCP over stdio, so it works with any MCP-capable agent: Claude Code and Desktop, Cursor, GitHub Copilot (VS Code), Windsurf, Cline, Gemini CLI, Codex CLI, opencode, Continue, Hermes Agent, Zed and others.
Not affiliated with or endorsed by GitHub.
## Why
Most GitHub MCP setups use one token. This keeps several named accounts and picks one per call:
1. an explicit `account` argument (name or GitHub login), else
2. the account whose login matches the repo owner (`ApiCartOps/demo` uses the `ApiCartOps` account), else
3. the default account.
## Setup
```bash
git clone https://github.com/ApiCartOps/github-multi-mcp.git octoswitch
cd octoswitch
npm install
npm link # puts the `octoswitch` command on your PATH
octoswitch add personal --default
octoswitch add work
octoswitch list
```
```text
NAME LOGIN
* personal alice (default)
work acme-corp
```
Without `npm link`, run `node src/cli.js` in place of `octoswitch`.
`add` asks for the token at a hidden prompt (or reads it from an env var with `--token-env=VAR`), checks it against GitHub and stores the login. Tokens are never passed on the command line, never printed, and never returned by any tool. They are stored in `~/.octoswitch/accounts.json` (file mode 600).
Use a fine-grained or classic personal access token per account. For org repos the token must be allowed by the org.
## Connect it to your agent
```bash
octoswitch agents # what is supported, and what looks installed
octoswitch install cursor # or: claude-code, vscode, codex, gemini-cli, ... or: all
octoswitch install cursor --dry-run
octoswitch config hermes # print the snippet instead of editing anything
```
`install` merges one entry into the agent's user-level MCP config and leaves everything else in the file alone. It refuses to touch a file it cannot parse (for example JSON with comments) and prints the snippet instead. `uninstall <agent>` removes it. Restart the agent afterwards.
| Agent | Id | What `install` does |
|---|---|---|
| Claude Code | `claude-code` | `mcpServers` in `~/.claude.json`, plus the skill and slash commands below |
| Claude Desktop | `claude-desktop` | `mcpServers` in `claude_desktop_config.json` |
| Cursor | `cursor` | `mcpServers` in `~/.cursor/mcp.json` |
| VS Code / GitHub Copilot | `vscode` | `servers` in the user `mcp.json` |
| Windsurf | `windsurf` | `~/.codeium/windsurf/mcp_config.json` |
| Cline | `cline` | `cline_mcp_settings.json` |
| Gemini CLI | `gemini-cli` | `mcpServers` in `~/.gemini/settings.json` |
| opencode | `opencode` | `mcp` in `~/.config/opencode/opencode.json` |
| Codex CLI | `codex` | `[mcp_servers.octoswitch]` in `~/.codex/config.toml` |
| Continue | `continue` | `~/.continue/mcpServers/octoswitch.yaml` |
| Hermes Agent | `hermes` | prints a YAML snippet for `~/.hermes/config.yaml` |
| Zed | `zed` | prints a snippet for `settings.json` |
| anything else | `generic` | prints the standard `mcpServers` JSON |
Config locations differ between versions of these tools, so check the printed path if an agent does not pick it up. Use `--npx` to register `npx -y octoswitch mcp` instead of a path to this checkout (once published), and `--name=NAME` to use a different server name.
### Project instructions
```bash
octoswitch init # AGENTS.md, plus any of CLAUDE.md / GEMINI.md / copilot / cursor rule that already exist
octoswitch init --all # write all five
```
This adds a short, marked block telling the agent to use the `gh_*` tools and to confirm the account before any write. Re-running updates the block in place. `AGENTS.md` is read by Codex, Cursor, Copilot, Windsurf, opencode, Zed and others; the other files cover Claude Code (`CLAUDE.md`), Gemini CLI (`GEMINI.md`), GitHub Copilot (`.github/copilot-instructions.md`) and Cursor (`.cursor/rules/octoswitch.mdc`).
## What it exposes
**Tools** (all agents):
| Read | Write (act on a real account; agents are told to confirm first) |
|---|---|
| `gh_list_accounts`, `gh_whoami`, `gh_list_repos`, `gh_get_repo`, `gh_list_issues`, `gh_get_issue`, `gh_list_prs`, `gh_get_pr`, `gh_search_issues`, `gh_get_file` | `gh_create_repo` (private by default), `gh_create_issue`, `gh_comment_issue`, `gh_create_pr` |
**Server instructions**: the same guidance as above is sent in the MCP `initialize` response, so clients that surface it need no extra setup.
**Prompts** (commands, for clients that support MCP prompts): `gh_accounts`, `gh_triage`, `gh_review_pr`, `gh_new_issue`. They take one optional argument such as `owner/repo` or `owner/repo 42`.
**Resource**: `octoswitch://accounts` (names and logins only).
**Claude Code extras** (installed by `install claude-code`): the `octoswitch` skill in `~/.claude/skills/` and the slash commands `/gh-accounts`, `/gh-triage`, `/gh-review-pr`, `/gh-new-issue` in `~/.claude/commands/`. The sources live in [`content/`](content), including a standard `SKILL.md` you can copy into any agent that supports Agent Skills.
## CLI reference
| Command | Description |
|---|---|
| `add <name> [--token-env=VAR] [--default]` | Add or replace an account |
| `list [--json]` | Show accounts (no tokens) |
| `default <name>` | Set the default account |
| `remove <name>` | Remove an account |
| `agents` | List supported agents |
| `install <agent\|all> [--name=N] [--npx] [--dry-run]` | Register the server with an agent |
| `uninstall <agent>` | Remove it |
| `config <agent>` | Print the snippet |
| `init [--dir=.] [--only=a,b] [--all]` | Write project instruction files |
| `mcp` | Run as an MCP server over stdio |
## Test
```bash
npm test
```
Runs against a fake GitHub API with temporary config and home folders; no real accounts or agent configs are touched.
## License
MIT
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues