Metadata-Version: 2.4
Name: contrarian
Version: 0.2.2
Summary: MCP server adding an independent second LLM perspective (Judge B) with full project graph context
Author-email: Anthony Micho <anthony.micho76@gmail.com>
License-Expression: MIT
Project-URL: Repository, https://github.com/anthonymicho/contrarian
Keywords: mcp,llm,code-review,claude,judge
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Quality Assurance
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: mcp
Requires-Dist: openai>=1.0
Requires-Dist: python-dotenv
Requires-Dist: networkx>=3.4
Requires-Dist: graphifyy[leiden]
Requires-Dist: json-repair>=0.6
Provides-Extra: all
Requires-Dist: graphifyy[all]; extra == "all"
Dynamic: license-file

# Contrarian

MCP server that adds a second LLM perspective (Judge B) directly inside Claude Code.

Claude Code is Judge A — it already has full project context. Contrarian adds Judge B, an independent model from a different lab, via a single tool call. Same rubric, different priors, no context switch.

---

## How it works

1. Claude Code invokes `contrarian_review()` — no args for auto-detect, or pass specific files.
2. Contrarian resolves the input: git diff, last commit, or full audit (in that order).
3. Judge B (external model) reviews against `JUDGE.md` in the project root.
4. Findings are returned inline and appended to `REPORT.md` for the dialogue log.

Auto-detect order:
- **diff** — any staged/unstaged changes or untracked files
- **last-commit** — clean tree → reviews the last commit
- **audit** — forced with `audit=true`, or nothing else found

---

## Installation

Requires Python 3.10+. You'll need a free API key from [DeepSeek](https://platform.deepseek.com) (no credit card required).

```bash
pip install contrarian
contrarian setup
```

`contrarian setup` prompts for your API key, then writes the MCP server config to `~/.claude/.claude.json` automatically. Restart Claude Code after running it.

That's it.

---

### Manual config (alternative)

If you prefer to configure manually, add to `~/.claude/.claude.json`:

```json
{
  "mcpServers": {
    "contrarian": {
      "type": "stdio",
      "command": "contrarian",
      "args": [],
      "env": {
        "JUDGE_B_API_KEY": "sk-or-...",
        "JUDGE_B_BASE_URL": "https://openrouter.ai/api/v1"
      }
    }
  }
}
```

Default provider is DeepSeek (`api.deepseek.com`, model `deepseek-chat`). Change `JUDGE_B_BASE_URL` and `JUDGE_B_MODEL` to use any OpenAI-compatible provider (Gemini, Groq, Ollama, OpenRouter, etc.).

Anthropic models are blocked at runtime — Judge B must come from a different lab than Judge A.

---

## Usage

Inside any Claude Code session, the tool is available as `contrarian_review`.

```
contrarian_review()                                    # auto-detect mode
contrarian_review({ path: "src/auth.py" })             # single file, diff
contrarian_review({ path: "src/auth.py", full: true }) # full file
contrarian_review({ paths: ["src/a.py", "src/b.py"] }) # multi-file, reviewed as a unit
contrarian_review({ audit: true })                     # force full repo walk
contrarian_review({ model: "google/gemini-3.1-pro-preview" }) # one-off model override
```

---

## Rubric

Place a `JUDGE.md` at the project root to customize what Judge B looks for. Without it, a built-in fallback rubric applies.

The built-in rubric covers four dimensions:

| Dimension | What to find |
|---|---|
| **Exactitude** | Logic errors, wrong assumptions, incorrect implementation |
| **Missing** | Unhandled cases, absent validation, unconsidered implications |
| **Premises** | Assumptions that could be wrong |
| **Alternatives** | Fundamentally different approaches |

Output is always JSON:

```json
{
  "exactitude": { "verdict": "ok|warn|fail", "findings": [] },
  "missing": [],
  "premises": [],
  "alternatives": []
}
```

---

## Report log

Findings are appended to `REPORT.md` at the project root under `[Judge B]` blocks. Claude Code annotates findings under `[Judge A]` blocks. Judge B reads previous exchanges before each review — closed findings (`addressed`, `won't fix`, `disagree`) are not re-raised.

---

## Phase roadmap

- **Phase 2 (current):** MCP server + project graph context. Auto-detect mode. Python rewrite.
- **Phase 3:** Operational hardening — token budget guard, graph latency, detached HEAD handling.
- **Phase 4:** Agent watchdog — autonomous background review on commit.
