Skip to main content

srs-mcp

Agent-agnostic MCP server for spaced-repetition learning — no Anki GUI, no Xvfb, no AnkiConnect. Bring your own agent; this brings the card box + the scheduler.

It wraps FSRS (the Free Spaced Repetition Scheduler, the same algorithm modern Anki uses) around a tiny SQLite store, so an agent can author cards, see what's due, and record recall — entirely headless.

Why not headless Anki?

Driving the Anki desktop app headless means Qt + a virtual framebuffer (Xvfb) + the AnkiConnect add-on — brittle and version-coupled. The anki PyPI package can drive a real .anki2 collection GUI-less if you need interop with your phone's Anki. But if you just want spaced repetition behind an API, you don't need Anki at all: FSRS is a library, and this server is ~200 lines around it.

Tools

  • add_card(front, back) -> {card_id, due} — author + schedule a card. Keep back short — a word or a phrase; a card you can't grade in seconds is a note, not a flashcard
  • due_cards(q=None, limit=20) -> [{card_id, front, back, deck, due}] — what's due now, optionally narrowed to a topic (q="horace")
  • grade_card(card_id, rating) -> {card_id, rating, next_due, reps} — record recall (again/hard/good/easy, or 1-4)
  • edit_card(card_id, front=None, back=None) — edit content in place; schedule is preserved (fix typos / shorten a long answer instead of duplicating)
  • suspend_card(card_id) / unsuspend_card(card_id) — shelve a card (kept with its history, removed from the due queue) / restore it
  • list_cards(q=None, limit=50) — overview regardless of due date
  • delete_card(card_id) — remove one (reset / cleanup)
  • stats(deck=None) -> {total, due_now, suspended, reviews, decks}

Finding cards: search, not decks

Cards are found by searching their text — due_cards(q="horace") — rather than by filing them into decks up front. Nothing writes the deck field any more; put the topic in the card itself ("Horace, Odes 1.11: …") and it stays findable.

Decks were a single-valued, free-text, exact-match label with no per-deck scheduling attached, so they bought nothing a search doesn't, and cost accuracy: on the deck this was measured against, agents had invented ten names for Horace across five separator conventions, so the best possible deck="Horace" returned 20 of 97 Horace cards while q="horac" returns 89 — including ones misfiled under Talks. The column and the deck= filter on due_cards/list_cards/stats remain for cards labelled by older versions. See plans/002-decks.md.

The review loop: due_cards → quiz the user with front → check against back → grade_card. FSRS computes the next due date from the rating.

Run

uv sync
# HTTP (default; for Railway / remote agents)
PORT=8000 uv run srs-mcp
# or stdio (local agent)
MCP_TRANSPORT=stdio uv run srs-mcp

Storage

Two backends, chosen at startup:

  • Postgres (shared deck) — set SRS_DATABASE_URL (or DATABASE_URL) to a Postgres connection string (e.g. a Neon DB). Every deployment that points at the same URL reads/writes one shared deck, so you can add and review cards from anywhere (local, Railway, etc.). FSRS card ids are large, so the cards.card_id column is BIGINT on Postgres. Requires the psycopg dependency (already declared).
  • SQLite (fallback) — when no *DATABASE_URL is set, cards live in a SQLite file at SRS_DB (default ./srs.db). Single-host / offline. In a SQLite-on-Railway setup, mount a volume at /data and keep SRS_DB=/data/srs.db so the box survives redeploys.

The schema is identical (table cards) and auto-created on first use.

Metadata

Release files for srs-mcp 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for srs-mcp 0.3.0
File Size Uploaded Provenance
srs_mcp-0.3.0.tar.gz 96.7 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for srs-mcp 0.3.0
File Interpreter ABI Platform
srs_mcp-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 108.3 kB

Release files / srs_mcp-0.3.0.tar.gz

Download URL srs_mcp-0.3.0.tar.gz
Size 96.7 kB
Tags Source
SHA-256 checksum
How to use checksums
3a892628dd53e9c5ddf15470710766e494f1ae3cf6c1c232828a7b967bf28d5e
BLAKE2b-256 checksum
How to use checksums
129cd4946a380eeb2ccf6d89f5137c3f84efe39d166ff38b5c185366f34e06df
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.8.17

Release files / srs_mcp-0.3.0-py3-none-any.whl

Download URL srs_mcp-0.3.0-py3-none-any.whl
Size 11.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ac47c680ca4fe5eb37a535b23bd7bc141fd3a028dc895b589833ed190a829108
BLAKE2b-256 checksum
How to use checksums
1f7eafe27f2a0defc7a1784a290a6479bb792503621ee88488249af693bb3bfb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.8.17

Security for srs-mcp 0.3.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page