Search, compare, and track italki lessons — from the terminal, with LLM support via MCP.
italki has no official API. Every endpoint, filter, and enum value in this tool was reverse-engineered from the public web API and verified by testing real requests.
This project is unofficial and not affiliated with, endorsed by, or sponsored by italki HK Limited or Lingbe, S.L. It was built for educational and personal-use purposes.
italki's Terms of Service (effective 11 Dec 2025, https://www.italki.com/tos) restrict activities that this tool performs. Section 12.2 prohibits, among other things:
- 12.2.3 — using robots, spiders, or automated means to access, retrieve, scrape, or index the Platform
- 12.2.4 — reverse engineering any portion of the Platform
- 12.2.6 — recording, processing, or mining information about other Members
- 12.2.7 — accessing the Platform by means other than the public interfaces provided
By using this tool you accept that you may be violating italki's Terms of Service and that enforcement (including account suspension or termination) is at italki's sole discretion. Use at your own risk. Recommended posture:
- Personal, low-volume, authenticated use of your own account data is the lowest-risk path.
- Do not bulk-scrape the teacher directory or run high-rate automated requests.
- Do not expose the MCP server to other users — that crosses from personal use into a third-party service.
This project does not redistribute italki Content. All data is fetched live from italki's API at runtime and used locally by the user running the tool.
Open to collaboration: if you work at italki and want to discuss integrating any of this functionality officially, formalizing an API, or taking this project down in exchange for an official path, please open an issue or reach out.
Not published — personal-use tool. Run locally with Bun:
git clone <repo-url> && cd italki-cli
bun install
bun run index.ts --helpbun run index.ts --help # list all commands
bun run index.ts <command> --help # flags for a specific commandOutput modes: human-readable with colors by default (disable with NO_COLOR=1). Add --json for translated JSON output (dollars, tag names, minutes — for scripts/pipe consumers).
italki mcp starts a stdio MCP server for AI tools (Claude Desktop, Cursor):
~/.config/claude/claude_desktop_config.json:
{
"mcpServers": {
"italki": { "command": "bun", "args": ["run", "/path/to/italki-cli/index.ts", "mcp"] }
}
}| Tool | Description | Auth? |
|---|---|---|
search_teachers |
Search by language with filters + client-side sort | No |
get_teacher |
Full teacher profile (bio, courses, pricing, stats, education) | No |
get_schedule |
Availability calendar (default 28 days, days param adjustable) |
No |
get_reviews |
Paginated student reviews | No |
compare_teachers |
Fetch 2+ teacher profiles in parallel | No |
get_balance |
Credit balance (ITC) | Yes |
get_whoami |
Profile + learning languages + analytics | Yes |
get_lessons |
Lesson history with client-side filters | Yes |
book_lesson |
Book a lesson (dry_run to preview) | Yes |
reschedule_lesson |
View slots or reschedule a lesson | Yes |
cancel_lesson |
Cancel a lesson | Yes |
confirm_lesson |
Confirm a completed lesson (status 7 → F) | Yes |
get_session_history |
Status change timeline for a session | Yes |
All tools return translated JSON by default (domain objects: dollars, tag names, minutes). Pass text: true for compact human-readable text.
4-layer separation, lint-enforced (bun run verify):
schemas/ zod contracts — API truth, no src/ imports
services/ fetch + zod validate — no UI, no transforms, no commands
transforms/ raw API → domain objects (cents→$, codes→names, units→min)
presenters/ domain objects → ANSI text — no services, no commands
commands/ citty CLI — wires services + transforms + presenters
mcp/ MCP server — same wiring, JSON default, text=true opt-in
Rule: services/ and transforms/ never import up. This makes MCP, REST, or any future interface addable without touching services or transforms. Violations are build errors, not suggestions.
CLI: args → service.fetch → zod.parse → transform.translate → presenter.format → stdout
CLI --json: args → service.fetch → zod.parse → transform.translate → JSON(domain) → stdout
MCP default: call → service.fetch → zod.parse → transform.translate → JSON(domain) → text content
MCP text=true: call → service.fetch → zod.parse → transform.translate → presenter.format → text content
CLI defaults to presenter text. MCP defaults to translated JSON (agents need all fields to reason, not a curated subset).
See AGENTS.md for the full operating contract.
| Tool | Why |
|---|---|
| Bun | Dev runtime — fast, native TypeScript |
| TypeScript | Type safety, strict mode |
| Zod | Runtime validation of API responses. 50+ nested fields need a schema, not hand-written interfaces. |
| Citty | CLI arg parsing + auto --help. ~3KB, works on Bun + Node. |
| Oxlint | 5 custom lint rules enforce architecture separation. Keys, not prompts. |
- AGENTS.md — architecture contract and engineering rules
- ROADMAP.md — phase plan and target commands
- KNOWN_GAPS.md — verification status and known limitations
- docs/api-reference.md — all verified API endpoints, headers, and enum values
- rappi-cli — architectural pattern
- mludv/italki_teachers — v2 teachers endpoint discovery
- bigl34/claude-code-plugin-italki — auth + booking research