@three-ws/tutor-mcp
v0.1.0
Published
three.ws Pay-As-You-Learn tutor ledger from any AI agent — read a learning session's itemized running tab and close it for an attested invoice. Free, no key, no signer; answering questions is the paid action handled elsewhere.
Downloads
118
Maintainers
Readme
A Model Context Protocol server that exposes the three.ws Pay-As-You-Learn tutor ledger over stdio. Read a tutoring session's itemized tab — one line item per answered question, with per-item cost and a running total — and close the session to seal an attested invoice.
The tutor bills per answered question; this server's tools are free. Viewing the running tab and closing the session never charge the learner — a learner must never pay to see what they owe or to end the session. Sessions are addressed by an opaque sessionId, so no API key and no signer are required — point THREE_WS_BASE at a deployment and go.
Install
npm install @three-ws/tutor-mcpOr run with npx (no install):
npx @three-ws/tutor-mcpQuick start
Claude Code, one line:
claude mcp add tutor -- npx -y @three-ws/tutor-mcpClaude Desktop / Cursor (claude_desktop_config.json or mcp.json):
{
"mcpServers": {
"tutor": {
"command": "npx",
"args": ["-y", "@three-ws/tutor-mcp"]
}
}
}Inspect the surface with the MCP Inspector:
npx -y @modelcontextprotocol/inspector npx @three-ws/tutor-mcpTools
| Tool | Type | What it does |
| --------------- | ----- | ---------------------------------------------------------------------------------------------------------------------------- |
| load_session | read | Read a session's itemized running tab by sessionId — line items (question, level, tokens, cost), status, and running total. |
| close_session | write | Finalize a session and return its attested invoice — seals the ledger with a SHA-256 attestation and locks further billing. |
Both tools are free and move no funds: the per-question answers are the paid action (handled elsewhere). load_session reads live data — the tab grows as questions are billed, so it is not idempotent. close_session mutates state (open → closed) but is itself idempotent: re-closing returns the same itemized total.
Input parameters
load_session — sessionId (required, ≤100 chars).
close_session — sessionId (required, ≤100 chars).
Example
// load_session
> { "sessionId": "learn-abc123" }
{
"ok": true,
"sessionId": "learn-abc123",
"status": "open",
"createdAt": "2026-06-24T03:40:00.000Z",
"questionCount": 2,
"lineItems": [
{ "n": 1, "question": "What is a Solana PDA?", "level": "intro", "outputTokens": 180, "costAtomics": 10000, "costUsd": "0.010000", "at": "2026-06-24T03:41:00.000Z" },
{ "n": 2, "question": "How do CPIs work?", "level": "intro", "outputTokens": 220, "costAtomics": 10000, "costUsd": "0.010000", "at": "2026-06-24T03:42:00.000Z" }
],
"totalAtomics": 20000,
"totalUsd": "0.020000"
}// close_session
> { "sessionId": "learn-abc123" }
{
"ok": true,
"sessionId": "learn-abc123",
"createdAt": "2026-06-24T03:40:00.000Z",
"closedAt": "2026-06-24T03:45:00.000Z",
"questionCount": 2,
"lineItems": [ /* same itemized line items */ ],
"totalAtomics": 20000,
"totalUsd": "0.020000",
"attestation": "sha256:…"
}A sessionId with no stored history returns an empty open session (questionCount: 0) rather than an error — an honest "nothing billed yet", not a failure.
Requirements
- Node.js >= 20.
- Network access to
https://three.ws(or your ownTHREE_WS_BASE).
Environment variables
| Variable | Required | Default |
| --------------------- | -------- | ------------------ |
| THREE_WS_BASE | no | https://three.ws |
| THREE_WS_TIMEOUT_MS | no | 20000 |
Links
- Homepage: https://three.ws
- Changelog: https://three.ws/changelog
- Issues: https://github.com/nirholas/three.ws/issues
- License: Apache-2.0 — see LICENSE
