chess-coach-mcp
README.md
# Chess Coach Agent — MCP Integration Assignment
An agent that takes a **link to a finished chess game** (lichess.org), fetches the
game through **Playwright MCP**, analyzes it with a local Stockfish through a
**custom Chess Mistake Coach MCP server**, reads/writes the player's training
journal through **Obsidian MCP**, and produces a personalized training plan:
classified mistakes, matching puzzles, and study-resource recommendations.
```
Claude Agent SDK agent
├── playwright MCP (existing #1, stdio via npx) → fetch game PGN from the link
├── obsidian MCP (existing #2, http, plugin) → read/write training journal
├── coach MCP (custom, stdio, this repo) → analyze_game, find_training_puzzles,
│ recommend_study_resources,
│ generate_puzzle_from_position
└── smartsearch MCP (bonus #4, stdio, vendored) → semantic search over the vault's
150-resource library (optional —
see "Bonus" section below)
```
## Prerequisites
- **Python 3.11+**
- **Node.js 18+** (for Playwright MCP: `npx @playwright/mcp`)
- **Claude Code CLI** installed natively (the Claude Agent SDK launches it;
on Windows it must be a `claude.exe`, not the npm `.cmd` shim)
- **Stockfish** binary — download from <https://stockfishchess.org/download/>
- **Obsidian** desktop app with the **Local REST API** community plugin
(`coddingtonbear/obsidian-local-rest-api`, tested with v5.1.0)
- An Anthropic API key (or Claude subscription login) for the Claude Agent SDK
## Installation
```bash
python -m venv .venv
.venv/Scripts/pip install -e ".[dev]" # Windows
npx --yes playwright install chromium # browser for Playwright MCP
```
All commands below use `.venv/Scripts/python.exe` explicitly rather than a bare
`python`/`streamlit`, so they work whether or not the venv is activated in your
shell — a bare `streamlit run ...` will pick up whatever Streamlit is first on
your `PATH`, which is usually **not** this project's venv and is missing
`claude-agent-sdk`, causing `ModuleNotFoundError: No module named 'claude_agent_sdk'`.
## Configuration
Copy `.env.example` to `.env` and fill in:
| Variable | Meaning |
|---|---|
| `ANTHROPIC_API_KEY` | Claude Agent SDK credentials (not needed if `claude` CLI is already logged in) |
| `OBSIDIAN_BASE_URL` | Local REST API endpoint, default `http://127.0.0.1:27123` |
| `OBSIDIAN_API_KEY` | From Obsidian → Settings → Local REST API |
| `STOCKFISH_PATH` | Full path to the Stockfish executable |
**Obsidian setup:** open (or create) a dedicated demo vault, install and enable
the *Local REST API* community plugin, enable its **non-encrypted HTTP server**
(port 27123) in the plugin settings, and copy the API key into `.env`. A ready
demo vault with a `Player Profile.md` and a `TrainingLog/` folder is described in
`docs/demo_script.md`.
**Dataset:** `data/puzzles_subset.csv` (1,249 puzzles filtered from the CC0
Lichess puzzle database) ships in the repo, so the custom server needs **no
network access at runtime**. To regenerate it from the full 6M-row database:
```bash
python scripts/prepare_puzzle_dataset.py
```
## Running — two independent processes
**Custom MCP server standalone** (used during the defence to prove process
separation; the agent also spawns its own instance over stdio):
```bash
.venv/Scripts/python.exe -m chess_coach_mcp.server
```
Scripted standalone proof (handshake, tool discovery, one call per tool, plus an
invalid-input error case):
```bash
.venv/Scripts/python.exe scripts/smoke_test_server.py
```
**Agent — CLI** (recommended for the defence/demo, since MCP connections and tool
calls are visible in the terminal):
```bash
.venv/Scripts/python.exe -m chess_coach_agent.cli --game-url "https://lichess.org/787zsVup" --username aanreitaylor
```
Options: `--username <name>` picks your color from the PGN headers;
`--color white|black` forces it.
**Agent — web UI** (recommended for everyday use):
```bash
.venv/Scripts/python.exe -m streamlit run chess_coach_agent/webapp.py
```
Opens a page at `http://localhost:8501` — paste a game link, optionally set your
username/color, click **Analyze**, and watch live progress (MCP connection status,
each tool call) before the results render below:
- the full prose training-plan report;
- one large step-through board per critical moment (`chess_coach_agent/board_render.py`,
built on `chess.svg`, navigated with ◀ ▶ rather than a row of tiny thumbnails):
first the move you actually played (🔴), then the engine's plan continuing move by
move (🟢) — each mistake also carries a short human interpretation (💡) the agent
writes itself (a `move-notes` block in its response, extracted by the UI — see
`system_prompt.py`) explaining what the plan achieves and what was concretely worse
about the move played, not just a centipawn number;
- if `generate_puzzle_from_position` produced a qualifying puzzle, the same
step-through treatment for its forced winning line;
- if the bonus `smartsearch` connection is up, a short "More to explore" section
from semantic search over the resource library (see below).
Board and puzzle data come straight from the `analyze_game` /
`generate_puzzle_from_position` tool results captured off the message stream —
nothing is re-derived from the prose report. Both entrypoints share the same
session driver (`chess_coach_agent/core.py`); the web UI is purely a display
layer over it, not a separate implementation.
## Bonus: semantic search over the resource library (4th MCP connection)
Beyond the assignment's required existing + custom servers, this project wires up
a **fourth, optional** MCP connection: local semantic search over the 150-entry
study-resource library (`data/study_resources.json`) and the training journal,
via a vendored, locally-patched build of the community `smart-connections-mcp`
server. It's purely supplementary — the agent still uses the required, deterministic
`coach.recommend_study_resources` tool as its primary recommendation path; semantic
search only adds a few "you might also like" results found by meaning rather than
exact theme tags. See `third_party/smart-connections-mcp/PATCH_NOTES.md` for what
was found, patched, and verified (two real bugs in the upstream package), and
`docs/design_rationale.md` for why this is optional rather than one of the graded
required tools.
One-time setup (after Obsidian + the Smart Connections community plugin are
installed and the vault has been opened at least once):
```bash
cd third_party/smart-connections-mcp
npm install
npx tsc
cd ../..
.venv/Scripts/python.exe scripts/build_smartsearch_index.py
```
If this build step hasn't been run, `smartsearch` is simply omitted from the
agent's MCP connections (not shown as "failed") — everything else still works.
## Documentation
- [`docs/tool_contracts.md`](docs/tool_contracts.md) — full Part C contracts for all
4 custom tools + the existing-server tools used
- [`docs/design_rationale.md`](docs/design_rationale.md) — why each server/tool,
trade-offs, limitations
- [`docs/demo_script.md`](docs/demo_script.md) — defence checklist mapped to the
assignment's required demo steps
## Tests
```bash
.venv/Scripts/python.exe -m pytest
```
Covers move classification thresholds, puzzle filtering, and resource ranking
(pure logic; no engine or network needed).
## Security / operational notes
- No secrets in the repo: the Obsidian API key lives only in `.env` (gitignored).
- The custom server uses only local data at runtime (Stockfish + CSV + JSON).
- Playwright is used read-only against public pages; no logins, no form input.
- Rate limits: the agent makes ~1 page load per run against lichess.org; the
dataset script downloads one static file from database.lichess.org.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues