A free-text field takes any philosophical prompt — a term, a phrase, a full question — and returns a sequenced reading list through twentieth-century continental philosophy. The model is constrained to cite specific chapters, sections, page ranges, or aphorisms rather than whole books, and each reading is tagged Introductory, Intermediate, or Advanced.
The constraint is enforced at two levels. A Gemini responseSchema requires the
output to be JSON matching a fixed shape: a topic, a short overview, and an
ordered list of modules, each containing readings with author, work,
specificLocation, rationale, and a difficulty field restricted to a three-value
enum. Schema conformance is enforced by the API rather than validated after the
fact. The “no whole books” rule is carried by the prompt together with the
granularity requirement on specificLocation.
Citations are grounded through a small MCP layer exposing one live tool,
query_academic_repository, which queries the OpenAlex scholarly index over HTTP
and returns up to three real works with title, author, year, DOI, and citation
count. The model must then build its answer from those results rather than from
recall. Every tool call and response is logged and rendered in an on-screen
protocol viewer, so the exchange is inspectable.
In development both AI paths run client-side against a VITE_-prefixed key; in
production they proxy through Netlify Functions holding a server-side key, with
the dev branch dead-code-eliminated from the production bundle. Both functions
carry edge-enforced rate limits — 10 requests per 60 seconds for generation, 5 for
MCP analysis, the latter tighter because each analysis fans out into several model
calls. Generation logic is shared by the serverless function and the dev fallback,
so prompt and schema live in one place. There is no database; every request is
stateless.