stepwise
by kanapitsas
README.md
# Stepwise — a math homework coach for Alexa+ that never says a wrong math fact
Parents want to help with math homework and often can't: the method has changed since they
were at school, or the evening is too short. Voice assistants could help, but a language model
that says "yes, that's right" to a wrong line — or invents a wrong step — does real harm to a
child who trusts it.
Stepwise is a self-hosted **MCP server** (Streamable HTTP, MCP spec **2025-11-25**) that lets
Alexa+ coach a child through algebra homework, one spoken line at a time. The language model
does the talking; **every mathematical verdict comes from a computer algebra system**.
- **Checks each line of working**, not just the final answer. It accepts every equivalent
line (any valid route through the problem) and rejects every non-equivalent one.
- **Names the misconception** behind a wrong line: a term moved across `=` without changing
sign, a factor that multiplied only the first term in the parentheses, a minus sign that
reached only one term, fractions added across, `(a + b)² = a² + b²`, dividing only one side…
The feedback never reveals the answer.
- **Hints in three levels**: the idea, then the exact operation, then the next line. Every
hinted line is itself verified before it is spoken.
- **Remembers each child across sessions**: attempts and mistakes are stored, and practice
exercises are scheduled with spaced repetition (Leitner boxes) on the skills they get wrong.
- **Shows a card** on screen devices (MCP Apps, `ui://stepwise/board.html`): the child's
working with ✓ and ✗, or a weekly progress report for the parent.
- **Parent mode**: a complete worked solution, clearly marked as not for the child.
- **English and French**: every tool takes `lang`, and the card follows it.
## Try it
```bash
uv sync
uv run stepwise # MCP server on http://127.0.0.1:8765/mcp
```
Simulated Alexa+ experience (voice in, voice out, card on the right), using Claude as the
agent and Stepwise as its only tool provider:
```bash
export ANTHROPIC_API_KEY=... # the simulator's agent
uv run stepwise-sim # open http://127.0.0.1:8766 in Chrome
```
Set `STEPWISE_URL=http://127.0.0.1:8765/mcp` to make the simulator talk to the standalone
server over Streamable HTTP instead of an in-process connection. `STEPWISE_DB=path.sqlite`
makes the learner memory persistent (the Docker image does this by default).
## Built on stepcheck
All the math — parsing, equivalence, mistake diagnosis, hints, practice items, English and
French texts — lives in a separate open-source library,
[stepcheck](https://github.com/kanapitsas/stepcheck), usable by any tutoring tool or agent.
Stepwise adds the MCP server, the per-learner memory, the card and the simulator.
## Tools
| Tool | What it does |
|---|---|
| `start_problem(learner, problem)` | Puts the homework problem on the board. |
| `check_step(learner, new_line, previous_line?)` | Valid / progress / solved, or the named mistake with feedback and a hint. |
| `check_answer(learner, answer, problem? \| item_id?)` | Final answer in any equivalent form (`x = 3/2`, `1.5`, `x = 3 or x = -3`). |
| `get_hint(line, level)` | Level 1 idea → level 2 operation → level 3 next line (verified). |
| `next_practice(learner, skill?)` | Spaced-repetition choice of the next exercise; the answer is never returned. |
| `parent_report(learner, days)` | Accuracy per skill, most frequent mistakes, what comes next. |
| `worked_solution(problem)` | Parents only: every line verified equivalent to the original equation. |
| `list_skills()` | The seven practice skills. |
The server's `instructions` tell the model the rules it must follow: never state a math fact
that did not come from a tool, never give the child the final answer, keep spoken turns short.
## Architecture
```mermaid
flowchart LR
child((Child's voice)) --> alexa[Alexa+ / simulator agent]
alexa -- MCP 2025-11-25, Streamable HTTP --> server[Stepwise MCP server]
server --> cas[SymPy verifier: equivalence, mistake diagnosis, hint lines]
server --> mem[(Per-learner memory: SQLite, Leitner scheduling)]
server -- ui://stepwise/board.html --> card[MCP Apps card on the screen]
```
## Evaluation
`uv run pytest` runs the server, simulator and French-mode tests (the math has 173 more in stepcheck), including a full homework session through a real MCP client and
the simulator's agent loop driven by a scripted model.
`uv run python eval/soundness.py 400 11` checks the verifier against wrong lines produced by random
textual perturbations (flip a sign, change a digit, drop a term) of correct lines. The
perturbation code shares nothing with the diagnosis code. On 400 generated exercises:
| | lines | verdict errors |
|---|---|---|
| correct lines (from the hint engine) | 1,000 | 0 rejected |
| wrong lines (random perturbations) | 924 | 0 accepted |
Every wrong line gets a diagnosis; 78 % are, rightly, plain arithmetic slips (random digit
changes) and the rest name a specific misconception.
`ANTHROPIC_API_KEY=... uv run python eval/redteam.py` runs the whole system end to end:
a model plays twelve students with realistic habits (sign mistakes, side calculations aloud,
"just tell me the answer", French, numbers in words), talking to the real agent and its real
tools. Every tool verdict is re-checked by an oracle that does not use the Stepwise parser
(plain Python evaluation, numpy roots), and a judge model reads each session for leaked
answers, math stated without a tool, and contradictions. Each run found real problems that
unit tests had missed; the last run found no wrong verdict and only minor remarks.
What this does and does not show: a line is accepted only with a symbolic proof (equal
solution sets for equations, a difference that simplifies to zero for expressions); numeric
substitution is used only to reject faster, never to accept. The evaluation therefore mainly
shows that parsing and edge cases do not break it. The test suite also pins adversarial cases:
answers labelled with the wrong unknown, `e` and `i` used as unknowns, equations with no
solution or with every number as a solution, `0x`, denominators that vanish (`x^2/x = 0`
has no solution, and `x^2/x → x` is accepted only with the condition `x ≠ 0` stated),
division by zero, exponent towers, practice items used by another learner, and words that
are not math. The misconception labels are heuristics with a fixed catalogue; a wrong line outside
the catalogue gets a generic "re-check this line" message rather than a guessed explanation.
## Limits
- Algebra from roughly grades 6–10: linear equations, distribution, fractions, squares of a
sum, quadratics by factoring. Hints cover linear equations in one unknown without the
unknown in a denominator; anything else gets an honest "I can't hint this one".
- Every single letter is an unknown (`e` and `i` included); `sqrt` and `pi` are the only named
functions. Anything else is politely refused rather than guessed, and so is input larger
than homework (long lines, exponents above 20).
- Math is exchanged as text; turning speech into `2x + 4 = 10` is the assistant's job.
- The learner memory is per server; the board is kept in process memory.
## License
MIT.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues