PR Viewer MCP Server
README.md
# Dev MCP Server
MCP server for local development workflows. Tools for branching and diff review,
designed to be called by AI coding assistants.
## Setup
```bash
uv sync --group dev
```
## Tools
| Tool | Description |
|---|---|
| `health_check` | Confirms the server is reachable. |
| `open_branch` | Checks the working tree is clean, then creates a new branch. |
| `open_review` | Launches a diff visualizer and blocks until the user accepts or rejects. |
### `open_branch`
| Parameter | Default | Description |
|---|---|---|
| `repo_path` | — | Absolute path to a git repo. |
| `branch_name` | — | Name for the new branch. |
| `base_ref` | `main` | Ref to branch from. |
Returns `"Created branch '<name>' from <base_ref>"` on success, or an error
string describing why it failed (dirty tree, branch already exists, bad ref).
### `open_review`
| Parameter | Default | Description |
|---|---|---|
| `repo_path` | — | Absolute path to a git repo. |
| `base_ref` | `main` | The base git ref (e.g. `main`, `origin/main`). |
| `head_ref` | `HEAD` | The head ref to diff against base (branch name, commit SHA, etc.). |
Blocks until the user finishes reviewing. Returns `"accepted"` or `"rejected"`.
## Wiring in a visualizer
Create a shell script that receives the repo context via env vars, launches the
visualizer, captures the user's decision, and signals the result back to the
server via the provided IPC path:
```bash
#!/usr/bin/env bash
# Env vars provided by the server:
# REPO_PATH – absolute path to the git repo
# BASE_REF – base ref (e.g. main)
# HEAD_REF – head ref (e.g. feature/add-greet)
# RESULT_PATH – IPC path the script writes "accepted" or "rejected" to
# launch your visualizer, capture the decision, then signal the result:
echo "accepted" > "$RESULT_PATH"
```
The default visualizer (`scripts/launch-octorus.sh`) opens octorus in a new
terminal window and prompts accept/reject after the user quits.
## Connecting to AI coding assistants
### Claude Code
Add to `~/.claude/mcp.json` (global) or `.mcp.json` at a project root:
```json
{
"mcpServers": {
"devflow": {
"command": "uv",
"args": ["run", "--directory", "/path/to/pr-viewer", "devflow-mcp"]
}
}
}
```
### OpenCode
```bash
opencode mcp add pr-viewer
```
Follow the prompts: choose **stdio**, set command to `uv`, args to
`run --directory /path/to/pr-viewer devflow-mcp`. This writes to
`~/.config/opencode/opencode.jsonc`.
### Codex
```bash
codex mcp add pr-viewer -- uv run --directory /path/to/pr-viewer devflow-mcp
```
This writes to `~/.codex/config.toml`.
### Example prompts
```
Create a branch called feature/add-login in /path/to/repo from main.
```
```
Open a review of feature/add-greet in /path/to/repo against main.
If it's accepted, merge it with `gh pr merge --merge`.
If it's rejected, post a comment explaining what needs to change.
```
## Manual end-to-end test with a toy repo
### 1. Create the toy repo
```bash
./scripts/setup-toy-repo.sh
```
Creates `./toy-repo/` with a `main` branch and a `feature/add-greet` branch.
To remove it when done:
```bash
./scripts/teardown-toy-repo.sh
```
### 2. Start the MCP inspector
```bash
uv run mcp dev src/devflow_mcp/server.py
```
Open the inspector URL printed in the terminal (default: `http://localhost:5173`).
### 3. Test open_branch
In the MCP inspector, select **open_branch** and fill in:
```json
{
"repo_path": "<absolute-path-to-project>/toy-repo",
"branch_name": "test-branch"
}
```
### 4. Test open_review
Select **open_review** and fill in:
```json
{
"repo_path": "<absolute-path-to-project>/toy-repo",
"base_ref": "main",
"head_ref": "feature/add-greet"
}
```
The tool blocks — the inspector shows a spinner until the review is complete.
A terminal window opens automatically; answer the accept/reject prompt when you
quit octorus.
## Programmatic use
```python
import asyncio
from mcp.client.stdio import stdio_client, StdioServerParameters
from mcp.client.session import ClientSession
async def main() -> None:
server = StdioServerParameters(
command="uv",
args=["run", "--directory", "/path/to/pr-viewer", "devflow-mcp"],
)
async with stdio_client(server) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
await session.call_tool("open_branch", {
"repo_path": "/path/to/repo",
"branch_name": "feature/my-feature",
})
result = await session.call_tool("open_review", {
"repo_path": "/path/to/repo",
"base_ref": "main",
"head_ref": "feature/my-feature",
})
print(result.content[0].text) # "accepted" or "rejected"
asyncio.run(main())
```
## Tests
```bash
uv run pytest
```
TDQS
A3.6/5.0
Scored across 2 tools
Disambiguation5/5
The two tools have completely distinct purposes: one checks server health, the other initiates a review workflow. There is no overlap or ambiguity.
Naming Consistency4/5
Both names use snake_case, but 'health_check' is a noun phrase while 'open_review' is a verb phrase, creating a minor inconsistency in grammatical pattern.
Tool Count2/5
Only two tools for a 'PR Viewer' server is very thin. The scope appears limited, and typical MCP servers offer more operations for meaningful interaction.
Completeness1/5
The server lacks essential tools for a PR viewer, such as listing PRs, viewing details, or commenting. Only a health check and a single review tool are provided, leaving major gaps.
Maintenance
ActivityInactive
ResponsivenessNo issues