Skip to main content
Glama
julienbrg

wisdom-mcp

by julienbrg

Corpus CI NestJS TypeScript pnpm Node.js License: GPL v3

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 start

The 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

NODE_ENV

development

production turns off Swagger UI at /docs

PORT

3000

HTTP port, bound to 127.0.0.1

PUBLIC_URL

http://localhost:3000

Public origin; the only host and origin allowed on /mcp

DATABASE_PATH

./data/app.db

SQLite file

CORPUS_CACHE

./data/cache

Downloaded texts used by the corpus import

MISTRAL_API_KEY

Mistral API key for keywords and embeddings

EMBEDDING_MODEL

mistral-embed

Embedding model (1,024 dimensions)

KEYWORDS_MODEL

ministral-8b-latest

Model that writes search keywords

RATE_LIMIT_PER_MINUTE

30

Tool calls per client IP per minute on /mcp

SEARCH_LIMIT_PER_DAY

200

search_passages calls per client IP per day

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:import

This 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:diff

This 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 (lzh)

Hanyu Pinyin with tone marks, using classical readings

Ancient Greek (grc)

Romanization with accents and breathings: ē and ō for η and ω, h for the rough breathing, ῳ → ōi

Biblical Hebrew (hbo)

SBL general-purpose style, read from the points: v, kh, f for spirants, dagesh forte doubled

Sanskrit (san)

IAST

Pali (pli)

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:index

This 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

search_passages

query

Up to 20 hits (id, author, work, reference, snippet), at most 3 per work

read_passages

ids (max 10)

Each reference unit once: the original to quote, its source, and the translation as an aid

check_quote

quote, work?

The exact match (id, work, reference), or the closest candidates

list_concepts

filter?

Concepts (id, name, original term, gloss, tradition, school), optionally filtered

get_concept

id

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 HTTP

  • GET /health: liveness check

  • GET /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 eval

This 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

pnpm build

Compile to dist/

pnpm start

Run the compiled server

pnpm corpus:import

Import the pilot corpus

pnpm corpus:diff

Compare the corpus with the site

pnpm corpus:index

Build the search indexes

pnpm readings:draft

Draft the pinyin readings files

pnpm eval

Measure search Recall@10

pnpm test

Build, then run the tests

pnpm lint

ESLint

pnpm format:check

Prettier check

pnpm typecheck

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

License

GPL-3.0

Contact

Julien Béranger (GitHub)

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Semantic 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.
    3
    2
    MIT
  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables semantic retrieval over a structured Quran and classical exegesis library, returning relevant source chunks and verified references for thematic research queries.
    1
    -