wisdom-mcp
Imports original-language texts from Sefaria into the searchable corpus, including works such as Ecclesiastes, so passages can be retrieved with references.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@wisdom-mcpSearch the Tao Te Ching for passages about anger and quote them with references."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Wisdom MCP
An MCP server for agentic hybrid search over philosophical and spiritual texts, built on Kevin Owocki's Wisdom Context Window. The server only retrieves: your own model searches, reads, quotes and translates. See the design write-up.
Motivation
Ask a model what the Stoics or the Daodejing say about anger and it will often paraphrase, or invent a plausible line with a plausible reference. For texts like these, the exact words and where they come from matter.
Wisdom MCP gives the model tools instead of answers. It searches a curated corpus with keywords and embeddings, then returns the original text with a precise reference. The model does the reasoning and translation, and quotes what it actually read. The corpus can grow without retraining anything, and every quote can be checked against its source.
Related MCP server: sefaria-api-mcp
Setup
pnpm install
cp .env.example .env
pnpm build
pnpm startThe database is created at DATABASE_PATH on first boot, and migrations in migrations/ are applied in order.
Settings come from .env and the environment, which takes precedence, and are validated at startup by the server and the corpus scripts alike. Without MISTRAL_API_KEY, search falls back to keywords only.
Variable | Default | Purpose |
|
|
|
|
| HTTP port, bound to |
|
| Public origin; the only host and origin allowed on |
|
| SQLite file |
|
| Downloaded texts used by the corpus import |
| Mistral API key for keywords and embeddings | |
|
| Embedding model (1,024 dimensions) |
|
| Model that writes search keywords |
|
| Tool calls per client IP per minute on |
|
|
|
Over either rate limit, /mcp answers 429 with a JSON-RPC error and a Retry-After header. Clients are told apart by IP, taken from X-Forwarded-For as set by the reverse proxy in front of the server. Counters are kept in memory, so a restart resets them.
/mcp rejects JSON-RPC batches, request bodies over 16 KB, and a Host or Origin header naming another host than PUBLIC_URL. Requests without Origin, as sent by non-browser clients, pass.
Corpus
pnpm corpus:importThis imports the 18 pilot works from the Wisdom Context Window, with their original-language texts, and its concept graph: 208 concepts, each with a summary, key passages and links to parallel, opposing, related and broader concepts. Downloads are cached in CORPUS_CACHE, so later runs work offline, and each run replaces the works and concepts it imports.
The cached Wisdom Context Window dump is never downloaded again on its own. To see what changed on the site first:
pnpm corpus:diffThis downloads the latest dump, without touching the cached copy, and lists the full texts on the site that are not in PILOT_WORKS yet, then the imported works a re-import would change: a different number of passage blocks, or passages no longer in the block their id points to (edited). Passage ids such as analects:123 are positional, so those works' ids would shift. It reads the database and changes nothing. Then re-import from the latest dump:
pnpm corpus:import --refresh--refresh downloads the dump again and overwrites the cached copy. The original-language texts and the concept graph stay cached.
The corpus badge at the top of this README is static: after an import changes the counts, update it with select count(*) from texts and select count(*) from passages.
Work | Translation | Reference | Original |
Tao Te Ching | James Legge | chapter.para | Chinese Wikisource (王弼本) |
Sayings of Lao Tzŭ | Lionel Giles | chapter | Chinese Wikisource (王弼本) |
Analects | James Legge | book.chapter | Chinese Wikisource |
Great Learning | James Legge | chapter | Chinese Wikisource (章句) |
Doctrine of the Mean | James Legge | chapter | Chinese Wikisource (章句) |
Mencius | James Legge | book.chapter | Chinese Wikisource (集注) |
Chuang Tzŭ | Herbert A. Giles | chapter.para | Chinese Wikisource |
Book of Lieh Tzŭ | Lionel Giles | book.para | Chinese Wikisource |
Yi King (I Ching) | James Legge | hexagram, App. | Chinese Wikisource |
Art of War | Lionel Giles | chapter.para | Chinese Wikisource |
Works of Motse | Yi-Pao Mei | chapter.para | Chinese Wikisource |
Works of Hsüntze | Homer H. Dubs | book.para | Chinese Wikisource |
Dhammapada | F. Max Müller | verse | SuttaCentral |
Bhagavad Gita | Edwin Arnold | chapter.verses | gita/gita dataset, by verse |
Enchiridion | Thomas Wentworth Higginson | section | Perseus |
Meditations | Meric Casaubon | book.section | Perseus, by section |
Sermon on the Mount | King James Version | chapter:verse | Perseus |
Ecclesiastes | King James Version | chapter:verse | Sefaria |
Every quotable passage has a reference and an original. Front matter, translators' notes, indexes and headings are kept but flagged is_apparatus.
The Great Learning, the Doctrine of the Mean and Mencius come from Zhu Xi's 《四書章句集注》, and follow his chapters as Legge does: the Great Learning counts from 0, the text of Confucius, then ten chapters of commentary, and Mencius is book, part and chapter (1A.1). The Wisdom Context Window gives these three with no numbers, each Chinese paragraph followed by Legge's translation of it. So each Chinese paragraph is matched to the chapter whose text it shares the most character pairs with, and the translation after it takes that chapter. The Chinese paragraphs are flagged is_apparatus, and a paragraph that runs over into the next chapter takes a range, such as 14-15.
The three Giles translations have no numbers either, and no Chinese, so they are aligned by hand in data/alignments/<work>.json: in order, the opening words of the block where each unit starts, or … and words within a block, which then takes a range such as 10.6-7. Chuang Tzŭ is a full translation and goes by chapter and Wikisource paragraph (17.12). The Book of Lieh Tzŭ is a selection, by book and paragraph of the Chinese (Giles's Book VII is the Chinese book 8, 說符, so it is 8.x). The Sayings of Lao Tzŭ rearranges sayings by theme, each taking the 王弼本 chapter it comes from, so it shares the Legge Tao Te Ching's original and readings. Giles's notes, page numbers and section titles are flagged is_apparatus.
The Art of War keeps Giles's section numbers (6.22), and each section takes the Wikisource paragraph of its chapter it falls in, or a range of them (6.6-7); his bracketed notes are apparatus. Mei's Motse and Dubs's Hsüntze are scans with footnotes, page heads and margin summaries run into the text, aligned by hand like the Giles translations, by chapter (or book) and Wikisource paragraph: a footnote runs from the first one on a page to the next page head. Dubs translates 19 of the 32 books and the eulogy that ends book 32. Legge's Yi King is also a scan, whose notes are told from the text by their smaller type, which the OCR gives as longer lines. The Text goes by hexagram (15); the appendixes by Legge's numbering: the 彖 and 象 by hexagram (App. I.15, App. II.15), the 繫辭 by section and chapter (App. III.1.5), the 文言 by hexagram and chapter (App. IV.1.2), the 說卦 by chapter (App. V.5), the 序卦 by part (App. VI.2) and the 雜卦 whole (App. VII). The originals are the Wikisource pages of the hexagrams and of the 易傳.
Transcriptions
read_passages gives each original a transcription under it, so a reader who doesn't know the script can say it aloud. It is labelled as a pronunciation aid, never as the source. The import computes it into originals.transcription.
Language | Scheme |
Classical Chinese ( | Hanyu Pinyin with tone marks, using classical readings |
Ancient Greek ( | Romanization with accents and breathings: ē and ō for η and ω, h for the rough breathing, ῳ → ōi |
Biblical Hebrew ( | SBL general-purpose style, read from the points: v, kh, f for spirants, dagesh forte doubled |
Sanskrit ( | IAST |
Pali ( | None, already in Latin script |
Pinyin libraries guess polyphones from modern usage, which is often wrong for classical texts: 不亦說乎 is bù yì yuè hū, not shuō. So every occurrence of a polyphone whose classical reading depends on its sense (說, 樂, 為, 好, 惡, 知, 行, 長, 見, 食…) takes its reading from data/pinyin/<work>.json, keyed by reference and character position. The import fails and lists every occurrence that has no reviewed reading.
pnpm readings:draft [work…]This drafts the Analects, Laozi and Zhuangzi readings files from 《經典釋文》 (論語音義 and 老子音義, 四部叢刊本 on Chinese Wikisource). Each headword is aligned on the text, and each note is resolved to a 廣韻 sound class through ytenx: 「音X」 is X's class, and 「AB反」 is A's initial with B's rhyme. The script then picks the pinyin reading that is the regular Mandarin outcome of that class. A note marked 下同 carries its reading to later occurrences in the same book. An occurrence with no note takes the usual reading (如字), since 釋文 notes only departures from it. For the Analects, each reading is cross-checked against 朱熹《論語集注》. The Great Learning, the Doctrine of the Mean and Mencius take their readings from 集注 alone, since 釋文 has no 音義 for Mencius: each phonetic note (「去聲」, 「音X」, 「AB反」) is placed in the passage it follows and read the same way, and a note it allows two readings for goes to review. The Zhuangzi takes its readings from 莊子音義 (卷二十六 to 二十八 of the same edition). Its 下同 only carries a reading on to the phrase the note names (「下爲是皆同」) or to its headword, since a 下同 there runs through long chapters over other senses of the same character. The Liezi takes its readings from 殷敬順's 釋文, printed inline with 張湛's notes in the 四庫全書 edition: the two editions are aligned character by character, a note opening with a reading is placed on the words before it, and its 下同 stops with its paragraph, since Giles translates only some of them. The I Ching takes its readings from 周易音義 (卷二, 四部叢刊本), which reads 王弼's arrangement, where each line's 象 follows the line: each hexagram's text is set out in that order before the headwords are aligned on it. The Art of War, Mozi and Xunzi have no 音義 in this pipeline: every occurrence takes the usual reading, reviewed by hand for the Art of War and for senses that context settles in Mozi and Xunzi (惡乎 wū, 所惡 wù, 王天下 wàng).
Each entry records its source and the original note, e.g. "note": "音恱注同", and check when 集注 agrees. Entries where the sources disagree, or where a note couldn't be resolved, carry a todo saying why. The import refuses them until they are reviewed.
The script also lists the notes it skips: a note on a character missing from the polyphone list, whose reading differs from pinyin-pro's. Add such a character to POLYPHONES in src/corpus/transcription/pinyin.ts, with its usual reading in RUZI in src/corpus/transcription/shiwen.ts, and run the script again.
To fix or add a reading, edit the entry: set pinyin, remove todo, add "reviewed": "<your name>", and give your reasoning in note. pnpm readings:draft keeps reviewed entries when it runs again.
pnpm corpus:indexThis writes search keywords for each quotable passage, rebuilds the keyword index and embeds the passages, using MISTRAL_API_KEY. Results are cached in CORPUS_CACHE by passage text, so run it again after every import at no extra cost.
Tools
Tool | Input | Returns |
|
| Up to 20 hits (id, author, work, reference, snippet), at most 3 per work |
|
| Each reference unit once: the original to quote, its source, and the translation as an aid |
|
| The exact match (id, work, reference), or the closest candidates |
|
| Concepts (id, name, original term, gloss, tradition, school), optionally filtered |
|
| Summary, key passages with their passage ids, and parallels, tensions and related concepts |
Search is hybrid: an FTS5 keyword index over passage text and keywords, and a vector index over Mistral embeddings, merged with reciprocal rank fusion. When too few passages contain every term, keyword search adds passages that contain any of them, ignoring common English stop words. If the embedding call fails or takes more than 5 seconds, search returns keyword results only and says so. read_passages stops at about 6,000 words. check_quote compares quotes with whitespace and punctuation removed but diacritics kept, through the trigram index on originals and the keyword index on translations. list_concepts matches its filter against a concept's id, name, gloss, tradition, school and domains. get_concept resolves a key passage to a passage id when its work is in the corpus, and lists the others by work as context only, with a 40-word snippet of each. The server sends its quoting rules to the client as MCP instructions.
Endpoints
POST /mcp: MCP over Streamable HTTPGET /health: liveness checkGET /docs: Swagger UI, outside production
Testing from Claude Code
.mcp.json registers the local server with Claude Code as wisdom. Start it with pnpm start, approve it in /mcp, then ask a question:
/wisdom How to improve global cooperation?The wisdom skill first restates the question as the human situation underneath it, then answers with search_passages and read_passages only, quoting the originals with their references and its own translations. It may run one web search to understand an unfamiliar term, never as answer content. Ask follow-up questions in the same window. The whole conversation, with the reframed question, every tool call, the ids read and the number of calls per turn, is written to test/output/<NNNNN>-<mon>-<dd>-<question-slug>.md, numbered from 00001, which is git-ignored.
Evaluation
pnpm evalThis runs search_passages on each situation in test/eval/situations.json and reports Recall@10: the share of the passages judged relevant that appear in the first 10 hits, per situation and on average. It needs a built corpus and MISTRAL_API_KEY, so it is not part of CI. Run it before each launch; the target is 0.7.
The set has 51 situations written as a person would ask them, each with 3 to 6 passages judged relevant by hand, at most 3 per work since search returns at most 3 hits per work. A hit counts only if it is the same passage, not another passage of the same reference.
Date | Recall@10 | Situations |
2026-10-10 | 0.184 | 44 |
2026-10-17 | 0.184 | 51 |
Compatibility
Any MCP client that speaks Streamable HTTP can use the server. Local clients such as Cursor, VS Code, Zed, Gemini CLI or Codex CLI connect to http://localhost:3000/mcp directly. Web apps such as Claude, ChatGPT, Le Chat, Perplexity, Gemini and Grok, and LLM APIs, need a public HTTPS URL. See docs/COMPATIBILITY.md for plans, setup per service, and how to expose the server.
Scripts
Script | What it does |
| Compile to |
| Run the compiled server |
| Import the pilot corpus |
| Compare the corpus with the site |
| Build the search indexes |
| Draft the pinyin readings files |
| Measure search Recall@10 |
| Build, then run the tests |
| ESLint |
| Prettier check |
| TypeScript without emitting |
Privacy
Every tool call is logged to the usage table in the server's SQLite database:
the time and the tool called
the query: the search query, the quote checked, the concept filter or concept id
the passage ids returned or read, and the number of hits
the duration, whether search fell back to keywords only, and the embedding tokens billed by Mistral
No IP address, client name or session id is stored. After 30 days, a job that runs daily replaces each query with its SHA-256 hash and keeps the other fields. The log is used to improve search: to review retrieval quality and how many calls it takes to answer a question.
Credits
Kevin Owocki, for the Wisdom Context Window: the corpus of texts, summaries and concept graph this server searches.
Chinese Wikisource, Perseus Digital Library, SuttaCentral, Sefaria and the gita/gita dataset, for the original-language texts.
陸德明《經典釋文》, 朱熹《四書章句集注》 and 殷敬順's 列子釋文 (四庫全書本), as transcribed on Chinese Wikisource, and ytenx by BYVoid, for the 廣韻 sound classes behind the pinyin readings.
pinyin-pro, for the base pinyin.
sqlite-vec by Alex Garcia, for vector search inside SQLite.
The Model Context Protocol TypeScript SDK.
License
GPL-3.0
Contact
Julien Béranger (GitHub)
Element: @julienbrg:matrix.org
Farcaster: julien-
Telegram: @julienbrg
This server cannot be deployed
Maintenance
Related MCP Connectors
Read-only semantic search over Vedic scripture verses, commentaries, and recorded lectures.
Search your knowledge bases from any AI assistant using hybrid RAG.
Cited, versioned knowledge for agents: retrieve sourced passages and propose owner-approved fixes.
Search 15K rare pre-modern texts translated to English: philosophy, religion, science, literature.
Related MCP Servers
- AlicenseAqualityDmaintenanceSemantic search over 4.6 million text chunks from 20,000+ classical philosophy and humanities works (pre-1928). Covers Aristotle, Plato, Kant, Hegel, Nietzsche and hundreds more. Multilingual: English, German, Latin, French, Italian, Greek, Russian.32MIT
- AlicenseBqualityDmaintenanceEnables AI agents to access and interact with the Sefaria database of Jewish texts, including retrieval, search, and related content.281MIT
- FlicenseNot gradedqualityBmaintenanceEnables semantic retrieval over a structured Quran and classical exegesis library, returning relevant source chunks and verified references for thematic research queries.1-
- AlicenseNot gradedqualityAmaintenanceEnables AI clients to search a personal corpus, read relevant source passages, and answer questions with traceable evidence from imported sessions, notes, and articles.MIT