Skip to content

The eklavya CLI

For the parts of Eklavya that make sense outside a Claude Code session. npx eklavya install already puts it on your machine; to have it on your PATH permanently use npm install -g eklavya, or run any subcommand without installing via npx eklavya <command>. The package ships this one command; the MCP server is eklavya serve, not a separate executable.

CommandWhat it does
eklavya serveRuns the MCP server on stdio. This is what Claude Code starts for you — you would only run it by hand to point another MCP client at Eklavya.
eklavya installInstalls Eklavya into Claude Code: checks Node, installs the runtime and its SQLite driver, registers and enables the plugin, installs the chat skill at ~/.claude/skills/eklavya/, and creates the database. Safe to re-run — that is how you upgrade, including for a marketplace install, where it pulls the plugin’s git clone forward.
eklavya uninstall [--purge]Removes the plugin, the runtime and the chat skill, and deregisters it from Claude Code. Your learning history is kept unless you pass --purge.
eklavya config getPrints the effective configuration as JSON, plus the paths of the global and repo files it came from.
eklavya config set <key> <value>Changes one setting. Add --repo to write .eklavya.json at the repository root instead of your global config. Add --topic <topic> when setting focus learn.
eklavya doctorChecks that everything is wired up: the runtime, the SQLite driver, the plugin’s registration with Claude Code, the chat skill, then the database, counts, journal mode, this project’s level and runway, and the effective mode, focus and cadence. It also applies your concept packs — the only command that does so unconditionally — and names any that failed to load. Exits non-zero if a check fails, and names the command that repairs it; a broken pack is reported but does not fail the run, because eklavya install cannot repair one.
eklavya dashboard [--port <n>] [--no-open]Serves your learning history as a local web page and opens it in your browser. --no-open serves it and prints the URL instead. See The dashboard.
eklavya statuslinePrints your dials as one line for a status bar, or nothing at all. See below.
eklavya db-pathPrints the database location. Useful in scripts.
eklavya export-rules [--out <file>]Writes the tutor pedagogy out as a Markdown rules file, for editors that read one. Claude Code loads the pedagogy in pieces, on demand; a rules file is a single always-applied document, so every piece is inlined into it. With no --out it prints to stdout. Nothing in the Claude Code flow needs it.

eklavya statusline

Your four dials, in Claude Code’s status bar, so the settings that shape a question are on screen when it arrives:

~/eklavya · main · Opus 5 · [EKLAVYA ambient · concept · interleaved · easy]

Add it to ~/.claude/settings.json:

~/.claude/settings.json
{
"statusLine": {
"type": "command",
"command": "eklavya statusline"
}
}

Already have a status line? Call eklavya statusline from your own script and append the output — it prints one line and exits 0, and prints nothing when it has nothing to say.

It stays silent when mode is off or quiet is true, so a bar you have stopped reading is a bar Eklavya is not writing to. enforced mode is printed in amber, because that is the one dial value with a consequence attached: your commits are gated. Pass --no-color, or set NO_COLOR, for plain text.

The bar never shows the tier of the question in front of you. A status bar refreshes when Claude Code decides to, not when a question appears, so a tier there would sometimes name the previous question’s difficulty. The level is there instead, and it is the part that explains the pitch — easy means tiers 1–2. For the exact tier of any past answer, see the dashboard.

What doctor looks like

Terminal window
$ eklavya doctor
home: /Users/you/.eklavya
runtime: /Users/you/.eklavya/runtime
driver: better-sqlite3 loads on Node 22.14.0
plugin: /Users/you/.claude/plugins/marketplaces/eklavya registered, enabled
skill: /Users/you/.claude/skills/eklavya
database: /Users/you/.eklavya/knowledge.db
concepts: 87
attempts: 41
mastered: 12
journal: wal
level: easy (23/100 passing answers in /Users/you/code/api)
mode: ambient
focus: concept
cadence: interleaved (one question mid-task, min 4m apart)

This is the first thing to run when something feels wrong.

The first four lines are the install itself. They matter because Eklavya fails quietly by design — every hook exits successfully whatever happens, so it can never break a session you are in the middle of. The cost of that guarantee is that a broken install looks exactly like a quiet one: Eklavya simply stops asking. These four checks are the only place that says which it is.

When one fails, doctor says so and names the fix:

Terminal window
$ eklavya doctor
home: /Users/you/.eklavya
runtime: /Users/you/.eklavya/runtime
driver: FAILED will not load on Node 24.0.0 Error: dlopen: symbol not found
plugin: /Users/you/.claude/plugins/marketplaces/eklavya registered, enabled
skill: /Users/you/.claude/skills/eklavya
...
Something is broken. Run: eklavya install

eklavya install is the repair for all four. It is idempotent — re-running it reinstalls the runtime, re-copies the plugin and rewrites the registration, leaving your learning history untouched. doctor never repairs anything itself; it reports, and you decide.

CheckWhat it means when it fails
runtimeThe compiled server is missing from ~/.eklavya/runtime. Usually an install that was interrupted.
driverThe SQLite driver will not load — almost always a Node upgrade that left the prebuilt binary on the wrong ABI.
pluginThe plugin is gone from Claude Code’s registry, or is registered but switched off in settings.json.
skillThe chat skill is missing from ~/.claude/skills/eklavya. If the name is taken by a skill of your own, doctor says so and leaves it alone — move yours first.