Skip to main content
Glama
README.md
# The Teacher

Run learning as a **verified loop**: interview to build a detailed **Target** (your goal as
observable claims), derive a **Path** to close the gap, learn through **teach → lab → test →
gate** per claim, get **cold-examined** by an adversarial verifier, and **raise the Target** once
you match it. A generic engine; ships with a guitar-learning example.

It's a small **MCP server + Claude Code skill**. The coaching agent teaches; a separate
**fresh-context examiner subagent** grades — so the teacher never certifies itself.

## Quickstart
```bash
python3 -m venv .venv && .venv/bin/pip install "mcp[cli]" pytest
.venv/bin/pytest            # all green
THE_TEACHER_STORE=./store.local.json .venv/bin/python server.py
```
See **Install** below to add it to Claude Code.

## Install as a plugin (one step) — recommended
The repo is its own plugin marketplace, so Claude Code can install the server **and** the skill
together. Requires [`uv`](https://docs.astral.sh/uv/) on your PATH (it pulls the `mcp` dependency
on the fly — no venv to manage).
```
/plugin marketplace add outlast85/the-teacher
/plugin install the-teacher@the-teacher
```
The coaching skill is then available as `/the-teacher:teacher`.

## Install manually
If you'd rather wire it up by hand (or don't use `uv`):
```bash
git clone https://github.com/outlast85/the-teacher.git
cd the-teacher
python3 -m venv .venv && .venv/bin/pip install "mcp[cli]"

# 1) register the MCP server (per-user; the `--` separator is required)
claude mcp add --transport stdio the-teacher -- "$PWD/.venv/bin/python" "$PWD/server.py"

# 2) install the coaching skill
mkdir -p ~/.claude/skills/teacher && cp skills/teacher/SKILL.md ~/.claude/skills/teacher/SKILL.md
```
There is no global MCP list — registration is **per-user and local**. Confirm with
`claude mcp list`.

## How it works
1. **First run** — the coach calls `status()`, and if no Target is set it **interviews you
   first**: it probes your real goal, decomposes it into 2–6 claims with observable
   `pass_criteria`, tags each claim `needs_lab` (runnable/software claims require lab evidence to
   pass), dispatches a fresh-context subagent to review the drafted Target for specificity, then
   calls `set_target`. **A detailed Target is required before any teaching begins.**
2. **Teach → lab → test → gate per claim** — for each module the coach teaches the concept,
   runs a lab if `needs_lab=true` (recording evidence with `record_progress`), asks you to
   explain the claim cold, dispatches a fresh-context examiner subagent to grade blind, and calls
   `record_verdict`. A `needs_lab` claim with no logged lab evidence is coerced to non-pass by
   the server even if the examiner says passed. The claim stays in `derive_path` until it
   genuinely passes the gate.
3. **Raise the Target** — when `status().matched` is true, the coach congratulates you and
   offers a harder Target, restarting the loop.

## Verifier-independence (the design point)
The examiner is deliberately adversarial (default-to-not-ready, high field standard). What makes
the verdict *independent* of the teacher is **context isolation** — and that's the only mechanism:

- **The verifier is a fresh-context examiner subagent.** The coach asks the learner to explain the
  module cold, then dispatches a SEPARATE subagent (same model, **clean context**) whose prompt
  contains ONLY the claim, the pass criteria, the learner's explanation, and any lab evidence —
  never the coaching conversation. Because that examiner never saw the context it would otherwise
  be anchored on, the grade is genuinely decorrelated: real **maker/checker**, not Reflection. The
  coach records it via `record_verdict(..., verdict_source="fresh-context")`. This works for
  **any** subject, needs **zero config**, no second model, and no external service.
- **Discouraged — `same-context`:** inline grading in the same coaching conversation. If ever
  used, it's recorded as `verdict_source="same-context"` and `status()` raises an
  `only_same_context` warning when a match is backed solely by it. This is the weak-verifier
  case; avoid it.

`matched` in `status` counts `fresh-context` verdicts. The server itself never calls any model —
all grading is done by the subagent inside your own client.

Resource URIs use the `theteacher://` scheme (e.g. `theteacher://target`,
`theteacher://path`, `theteacher://progress`).

## Privacy
Your Target/Path/progress live in a local JSON store (`~/.the-teacher/store.json` by default,
overridden by `THE_TEACHER_STORE`) that is **gitignored**. The repo ships only the generic
example. No personal data is ever committed.

TDQS

A3.5/5.0

Scored across 6 tools

Disambiguation5/5

Each tool has a distinct purpose: derive_path generates learning paths, load_target loads targets, record_progress logs attempts, record_verdict records exam verdicts, set_target stores goals, and status reports coverage. No overlap.

Naming Consistency4/5

Most tools follow verb_noun pattern (derive_path, load_target, record_progress, record_verdict, set_target). 'status' is a single noun but is a common exception.

Tool Count5/5

Six tools is well-scoped for the domain of managing learning targets and progress. Neither too few nor too many.

Completeness5/5

The tool set covers the full workflow: setting targets, loading them, deriving paths for uncovered claims, recording progress and verdicts, and reporting status. No obvious gaps.

Maintenance

ActivityInactive
ResponsivenessNo issues