Skip to main content
Glama

Recall

A memory engine for your LeetCode practice. Paste the Problem Log summary from your Claude tutoring session; Recall parses it, derives a review grade from how the solve actually went, schedules spaced-repetition reviews with FSRS, and mirrors due dates onto your calendar.

Run it

npm install
npm run db:migrate     # create/update the schema from drizzle/
npm run seed:lists     # one-time: seed the problem list and make it active
npm run dev            # http://localhost:3000

Skip seed:lists and there is no active list, so the recommender has nothing to draw from and "what should I solve next" stays empty.

These follow your .env, not the filename above. drizzle.config.ts loads dotenv, so if TURSO_DATABASE_URL is set (see Deploy) then db:migrate, db:push and import:sheet target the deployed database, not data/recall.db. Unset the TURSO_* vars for a purely local run.

npm run import:sheet is a one-time historical import from the original Google Sheet; it is not part of a normal setup.

Related MCP server: recall

Tests

npm test               # parser, identity ladder, FSRS scheduler, timezone

No test runner — each suite is a plain tsx script that exits non-zero on failure. The two DB-backed suites seed a scratch SQLite file in os.tmpdir() and never touch a real database. All four run in CI (.github/workflows/ci.yml) alongside lint, typecheck, drizzle-kit check and a production build.

The suites exist because each one covers something that fails silently rather than loudly:

Suite

Guards against

test:parser

a misread log writing the wrong FSRS grade

test:identity

the lcSlug → slug → number → bare-slug ladder drifting apart

test:fsrs

the scheduler quietly returning the wrong next date

test:tz

day-boundary math shifting when TZ is preset by the host

One thing test:fsrs documents rather than enforces: maximum_interval: 365 is a soft cap. LongTermScheduler.next_interval clamps each grade and then enforces again < hard < good < easy, so a fully saturated card settles at 365/366/367/368 days rather than 365. Harmless, but surprising if unexplained.

Daily loop

  1. Solve a problem with your Claude tutor (the tutor Skill ends the session with a Problem Log summary).

  2. Log → paste → Parse → confirm → Save. (~15 seconds)

  3. Each morning, Today shows what's due. Each review is a 2-minute approach recall: name the pattern, state the invariant, give the complexity — then reveal and grade yourself honestly.

The Problem Log template

Anything close to this parses perfectly (free-form text also works, best-effort; set ANTHROPIC_API_KEY to parse messy summaries with Claude):

## Problem Log — 49. Group Anagrams
URL / Difficulty / Patterns: https://leetcode.com/problems/group-anagrams/ · Medium · arrays-hashing
Solved: with 2 hints     Recall speed: slow
Confidence: before 2/5 → after 3/5     Time: approach 12 min · code 20 min
Fundamentals missing: definition of anagram
Issues: wrong pattern; code was messy
Brute force: compare every pair — O(n²k) / O(1)
Optimal: bucket by sorted-string key — O(nk log k) / O(nk)
Key insight: all anagrams share one canonical form
Tips: char-count tuple avoids the sort
Revise: yes — pattern recognition still weak
Suggested grade: hard — needed hints for the invariant

Grades: again (couldn't do it) · hard (hints/slow/low confidence) · good (solo with friction) · easy (instant + optimal). The tutor's suggested grade wins; otherwise Recall derives it from the signals.

Calendar

Subscribe once in Google Calendar: Other calendars → From URLhttp://<host>:3000/api/calendar/dev.ics (set CALENDAR_TOKEN to change the secret). Overdue reviews appear on today. Note: Google only refreshes subscribed feeds every 12–24h, which is fine for multi-day intervals; Apple Calendar refreshes faster. While the app only runs on localhost the feed can't be reached by Google's servers — use the in-app Today queue as primary (it is anyway), or deploy first.

MCP — let the tutoring chat log problems itself

Recall is also an MCP server at /api/mcp. Tools: get_next_action (call it first — it returns the day's plan), add_problem, get_due_reviews, log_review, get_stats, get_weekly_report_data, save_coach_report. With the dev server running, connect Claude Code:

claude mcp add --transport http recall http://localhost:3000/api/mcp --header "Authorization: Bearer dev"

(Replace dev if you set MCP_TOKEN.) Then at the end of a tutoring session, say "log it" — Claude calls add_problem directly, zero copy-paste. For claude.ai custom connectors the endpoint must be publicly reachable, i.e. after deployment.

The tutor prompt in docs/tutor-prompt.md is written to use these tools when available and fall back to the paste template otherwise.

Insights

/insights — activity heatmap, felt-vs-actual calibration (fed by the review player's pre-reveal confidence slider), confidence trend, per-pattern mastery, and grade distribution. Sparse until you've logged a few weeks of reviews.

Environment (.env)

Variable

Default

Purpose

DATABASE_PATH

data/recall.db

SQLite location

CALENDAR_TOKEN

dev — see below

Secret in the ICS feed URL

MCP_TOKEN

dev — see below

Bearer token for the MCP endpoint

ANTHROPIC_API_KEY

Enables AI parsing of free-form summaries

PARSE_MODEL

Haiku 4.5

Model for AI parsing

RECALL_USER_ID

shreet

Row owner (multi-user later)

APP_TIMEZONE

America/Los_Angeles

Timezone all day math uses (streaks, "due today")

APP_URL

Vercel URL, else localhost

Base URL the MCP tools put in their replies

The dev fallback for CALENDAR_TOKEN and MCP_TOKEN is local-only. It is revoked the moment APP_PASSWORD is set or NODE_ENV=production, because those two routes are exempt from the login gate and a shared default would leave them open. On a gated instance, set both explicitly or the ICS feed and the MCP endpoint return "Not found" / 401. See src/lib/secrets.ts.

Set APP_TIMEZONE, not TZ, to change the app's day boundary — TZ is overwritten at startup (src/db/index.ts) because the deploy platform presets it to UTC.

Deploy (Vercel + Turso)

The app runs on local SQLite with zero setup; setting TURSO_DATABASE_URL switches it to Turso (hosted libSQL — same schema, same queries). Deployed instances should also set APP_PASSWORD, which activates the login gate on every page and API (the MCP endpoint and ICS feed keep their own tokens).

One-time, interactive (browser OAuth — only steps a human can do):

turso auth signup
npx vercel login

Then, from recall/:

  1. sqlite3 data/recall.db "PRAGMA wal_checkpoint(TRUNCATE);" then turso db create recall --from-file data/recall.db — creates the cloud DB with all existing data.

  2. turso db show recall --url and turso db tokens create recall → the two TURSO_* values.

  3. npx vercel link, add env vars (TURSO_DATABASE_URL, TURSO_AUTH_TOKEN, APP_PASSWORD, CALENDAR_TOKEN, MCP_TOKEN, optionally ANTHROPIC_API_KEY), then npx vercel --prod.

After deploy:

  • Calendar: Google Calendar → Other calendars → From URL → https://<app>.vercel.app/api/calendar/<CALENDAR_TOKEN>.ics (now reachable by Google's servers, so it actually syncs).

  • MCP from claude.ai: Settings → Connectors → Add custom connector → https://<app>.vercel.app/api/mcp with header Authorization: Bearer <MCP_TOKEN>.

  • Note: local SQLite and Turso are now separate databases. Treat the deployed app as the source of truth; for cloud-backed local dev, put the TURSO_* values in .env.

Architecture notes

  • Next.js 16 App Router · Tailwind v4 + shadcn/ui (Base UI) · Drizzle over Turso (libSQL) in deployment, better-sqlite3 locally · ts-fsrs (FSRS-6, long-term mode, retention 0.9, max interval 365d, first interval floored at 2 days).

  • Every user-owned table carries user_id, so multi-user is a migration rather than a rewrite. The three that don't are not user-scoped: list_items (owned by its list), problem_concepts (a join table), and problems_catalog (a shared cache of public LeetCode metadata).

  • A re-solve of an existing problem logs a review against the existing record — never a duplicate row. Identity resolves lcSlug → slug → number → exact bare slug, in one place (findProblem in src/lib/data.ts).

  • Schema changes go through migration files: edit src/db/schema.ts, then npm run db:generate to emit reviewable SQL into drizzle/, then npm run db:migrate to apply it. drizzle/0000_baseline.sql is a baseline — it describes the schema as it already existed when migrations were adopted, and is recorded as applied, so it never re-runs against a live database.

  • npm run db:push still exists but is for throwaway/scratch databases only. Against a database with real rows, push resolves a column rename or a new NOT NULL column without a default by recreating the table, with no SQL to review and nothing to roll back to. Use db:generate + db:migrate.

  • Roadmap: concept-level scheduling (the concepts / problem_concepts tables are declared and waiting for it); sibling-problem substitution on mature cards.

A
license - permissive license
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • F
    license
    A
    quality
    D
    maintenance
    An MCP server that provides tools to interact with the LeetCode API, enabling problem fetching, code template generation, and solution execution/submission.
    7
    1
  • A
    license
    A
    quality
    C
    maintenance
    A zero-dependency MCP server for cross-session memory recall in Claude Code. Provides lexical search, listing, and retrieval of past session memories to avoid re-explaining context.
    3
    11
    MIT
  • A
    license
    -
    quality
    B
    maintenance
    A production-ready MCP server for GitHub and competitive programming (Codeforces) that enables AI assistants to fetch user profiles, repository stats, contest history, and personalized problem recommendations.
    MIT

View all related MCP servers

Related MCP Connectors

  • An MCP server that gives your AI access to the source code and docs of all public github repos

  • MCP server for AI dialogue using various LLM models via AceDataCloud

  • Search your AI chat history (ChatGPT, Claude, Codex) from any MCP client. Remote, private, read-only

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ShreeBohara/recall-leetcode'

If you have feedback or need assistance with the MCP directory API, please join our Discord server