← The evidence ledger
Evidence row 103459
Observed , by probe.mcp/1.
- Kind
- mcp.tools
- About
- endpoint 13fcea10-54e7-4beb-8131-486a3bf88ac3
- Recorded
- Previous row
- None: the first of its kind about this subject
- Body SHA-256
- d4f0daf0fbd53272a3bf3a2a1ca99d50a267fa8401755cb8fbbd6e9554616235
- Leaf
- 0x7b4d3aa50b1cbc5af6aa86b3a91eda432b9e27920222515cfc41d6e373101cab
What was observed
{
"count": 14,
"tools": [
{
"description": "Compare every available translation for a single segment.\n\n💡 **Use this tool when:**\n- The user asks about the meaning/translation of a single Pāli line\n and wants to see multiple translators side-by-side.\n- Checking how different translators interpret the same line —\n technical terms like `dukkha`, `anattā`, `nibbāna` carry nuance\n that varies across translations.\n- Academic work that needs to quote multiple translations.\n\n🔍 **vs `get_sutta`:** this tool targets a **single segment** (line\nlevel); `get_sutta` returns the **whole sutta**. To compare a whole\nsutta you'd call `compare_translations` for each segment.\n\n📋 **segment_id format:** `<sutta_id>:<paragraph>.<line>`, e.g.\n`mn1:171.4` (Mūlapariyāyasutta paragraph 171 line 4 — \"Nandī\ndukkhassa mūlaṁ\"). Find segment_ids via `get_sutta` or search results.\n\n⚠️ **Current state:** the `translation` table is mostly empty (the DB\nonly loads default Pāli + English from bilara). `total_editions` is\nusually 0; `text_pali` and `text_english` are always populated. Thai\neditions will be added later.",
"inputSchema": {
"additionalProperties": false,
"properties": {
"segment_id": {
"description": "Segment ID, e.g. \"mn26:8.2\", \"dn22:17.1\", \"mn62:5.3\".",
"type": "string"
}
},
"required": [
"segment_id"
],
"type": "object"
},
"name": "compare_translations"
},
{
"description": "Find how the **suttas and Vinaya define a Pāli term in their own words**.\n\nThe canon defines its own terms with fixed formulas — \"Katamañca …\ndukkhaṁ?\" (what is X?) … \"ayaṁ vuccati … dukkhaṁ\" (this is called X),\n\"X adhivacana\" (X is a designation for …), or the Vinaya \"X nāma\". This\ntool locates those definitional passages and returns them **cited**, so\nthe assistant can present the doctrinal essence straight from the source.\n\n🧭 **This tool vs `get_word_definition`:**\n- **`define_from_suttas`** → the *doctrinal* definition, how the term is\n defined **inside the canon**. Use for \"how do the suttas define X\",\n \"what is the canonical definition of X\", \"define X from the suttas\".\n Returns a few precise segments, not a lexicon essay.\n- **`get_word_definition`** → the *lexical* definition from dictionaries\n (Payutto / PTS / DPPN). Use for etymology and word meaning.\nThey complement each other — offer both when the user wants the full\npicture (dictionary sense + how the Buddha defined it).\n\n📖 **How to present the result:**\nResults are ranked; the top one is usually the canonical definition.\n**Quote the Pāli (and English where present) verbatim** and render each\n`cross_reference.tripitaka_mcp_reader.segment_url` as clickable markdown\nso the user can verify. Do NOT paraphrase into your own definition — the\npoint is the canon's own words. Each result is tagged `kind`\n(direct / simile) and `detail` (descriptive / enumerative); a\n*descriptive* definition characterises the term, an *enumerative* one\nlists its types — prefer the descriptive when explaining the essence.\n\n⚠️ A result tagged `context: true` **does not contain the term in its own\nline**. The canon's stock similes attach to a formula rather than to a\nword: the four jhāna similes (bath powder, deep lake, lotus pond, white\ncloth) never say *jhāna*, they illustrate the `vivicceva kāmehi …` formula\nthat opens the paragraph. Such rows are found through that paragraph, so\n**say so when quoting one** — present it as the simile the passage uses,\nnot as a line that defines the term.",
"inputSchema": {
"additionalProperties": false,
"properties": {
"include_similes": {
"default": true,
"description": "Include indirect definitions by simile/metaphor\n (seyyathāpi …, \"is a designation for …\"). Default True.",
"type": "boolean"
},
"limit": {
"default": 5,
"description": "Max definitional passages to return (1–15, default 5).",
"type": "integer"
},
"term": {
"description": "Pāli term in its base/dictionary form (e.g. \"dukkha\",\n \"viññāṇa\", \"samādhi\"). Diacritics optional — folded internally.",
"type": "string"
}
},
"required": [
"term"
],
"type": "object"
},
"name": "define_from_suttas"
},
{
"description": "Build a proper citation string for a sutta.\n\n💡 **Use this tool when:**\n- The user wants a citation for academic work, an article, or a reference.\n- You need to know the canonical location of a sutta (pitaka / nikāya).\n- You want a ready-to-use formatted citation string.\n\n🔗 vs `get_sutta`: this tool returns metadata + citation only, no\nsegments. Pair it with `get_sutta` when you want both the content\nand the citation.",
"inputSchema": {
"additionalProperties": false,
"properties": {
"sutta_id": {
"description": "Sutta ID, e.g. \"mn1\", \"dn22\", \"sn56.11\".",
"type": "string"
}
},
"required": [
"sutta_id"
],
"type": "object"
},
"name": "get_reference"
},
{
"description": "Fetch a sutta's content — OR its table of contents (`mode=\"outline\"`).\n\n⚡ **Decide which mode BEFORE calling — don't fetch the whole sutta and\nparse it yourself:**\n- The user wants the **structure / outline / table of contents**, or asks\n **\"how many sections/parts\"** / \"what's in it\" → call\n `get_sutta(sutta_id, mode=\"outline\")`. It returns the section list\n (titles + segment counts + ids), NOT the full text — cheap and exact.\n- The user wants the **context around a search hit** → `around=\"<segment_id>\"`\n (search tools hand you the id, e.g. `dn22:18.1`) + optional `window`.\n- The user wants a **specific part** you already located → `segment_range=\"A..B\"`\n or `offset`+`limit`.\n- Only fetch the **whole** sutta (no mode/selector) when the user actually\n wants to read/quote a SHORT sutta in full. Long ones (DN, long\n Vinaya/Abhidhamma; > ~400 segments — e.g. `dn16` is 1,664) should almost\n always start with `mode=\"outline\"`; pulling the entire text wastes the\n context window.\n\nUses standard SuttaCentral IDs, e.g.:\n- `mn1` = Majjhima Nikāya sutta 1 (Mūlapariyāyasutta, 334 segments)\n- `dn22` = Dīgha Nikāya sutta 22 (Mahāsatipaṭṭhānasutta, 454 segments)\n- `dn16` = Dīgha Nikāya sutta 16 (Mahāparinibbānasutta — the longest\n sutta in the canon, 1,664 segments)\n- `sn56.11` = Saṃyutta 56.11 (Dhammacakkappavattana)\n- `mn62` = Majjhima Nikāya 62 (Mahārāhulovāda — advice to Rāhula)\n- `dhp1-20` = Dhammapada verses 1-20 (KN uses range format)\n- `mil3.1.1` = Milindapañha 3.1.1 (paracanonical, 3–4 level id)\n\n💡 **Hints for the AI client:**\n- **Quote `text_pali` / `text_english` directly from the returned\n segments** — do not rely on training memory. The system is\n verifiable; AI recall is often wrong.\n- Short segments numbered `:0.n` are **headers**, not the teaching\n itself — actual content starts around `:1.1`. They run collection →\n book → chapter → sutta, so the **last** one is the sutta's own name\n (`sn35.245:0.3` = Kiṁsukopamasutta, while `:0.2` is its chapter).\n How many there are varies: DN/MN stop at `:0.2`, Iti reaches `:0.4`.\n- Segments ending in \"...niṭṭhitaṁ\" (e.g. `mn1:194.10` =\n \"Mūlapariyāyasuttaṁ niṭṭhitaṁ paṭhamaṁ\") are **colophons**\n marking the close of the sutta.\n- Segments containing `…pe…` (peyyāla) are **abbreviated repetitions**\n — not missing data. Pāli texts use this convention for repeated\n stock phrases.\n- **Citing this sutta? Link the reader — a citation the user cannot open\n is a claim they cannot check.** The response's\n `cross_reference.tripitaka_mcp_reader` (`is_primary: true`) renders\n SuttaCentral's `bilara-data` verbatim (the same canonical Pāli and\n bilara English this response carries), so it shows the user the very\n text your answer rests on — verification, not self-promotion. Its `url`\n shows Pāli + English side by side and `segment_url` highlights the cited\n line. Render it as clickable markdown for EVERY sutta you name. It is\n the only verify link to give.\n- **Cite at the segment level.** Each returned segment has its own\n `segment_id`; build a deep-link by slotting it into the pattern\n `https://tripitaka-mcp.com/read/<sutta_id>#<segment_id>`. When a specific\n claim or a technical Pāli term in your reply rests on a specific segment,\n link THAT segment — so the reader can click the claim and land on the\n exact supporting line, not just the sutta's top. e.g. the first-jhāna\n factors are in `sn45.8:10.2`, the fourth-jhāna in `sn45.8:10.5`.\n\n📑 **Pagination — don't pull a whole giant sutta into context:**\nBy default this returns EVERY segment. That's fine for short suttas but a\nsingle big one is huge (`dn16` ≈ 1,664 segments, `pli-tv-kd1` ≈ 3,591).\nUse one of these instead when the sutta is long (rule of thumb: > ~400\nsegments) or when you only need part of it:\n- `mode=\"outline\"` — a table of contents only (section keys + titles +\n counts + `first_segment_id`/`last_segment_id` + `offset`), **no segment\n text**. Cheap way to see the structure, then fetch one section.\n- `around=\"<segment_id>\"` + `window=N` — return the N segments before and\n after a segment_id. **Ideal after a search:** `search_by_keyword` /\n `survey_corpus` hand you a precise `segment_id` (e.g. `dn22:18.1`); pass\n it here to read its context without downloading the whole sutta.\n- `segment_range=\"<startId>..<endId>\"` — inclusive slice between two\n segment_ids (use the `..` separator; omit the end id to go to the end).\n Pairs with `mode=\"outline\"` (use a section's first/last id).\n- `offset` (0-based) + `limit` — ordinal paging. The response's `page`\n block carries `next_offset` to fetch the following page.\nOnly one selector (around / segment_range / offset+limit) may be used at a\ntime. Every response includes `total_segments` (the full count) so you\nknow how much remains.\n⚠️ **A window can hand you half a sentence or half a verse.** The corpus\nis segmented line by line, not sentence by sentence, so the first and last\nsegments of any `around` / `segment_range` / `offset`+`limit` slice may\neach be a fragment. `get_sutta(\"dhp1-20\", offset=4, limit=1)` returns one\nsegment, `dhp1:1` = \"Manopubbaṅgamā dhammā,\" — half of the opening line\nof the Dhammapada, which goes on in `dhp1:2` (\"manoseṭṭhā manomayā;\").\nBefore quoting anything from the edge of a window, read its neighbours:\nwiden `window` / `limit`, or fetch `around=<segment_id>` for the passage\nyou actually mean to cite. `verify_quote` joins up to four consecutive\nsegments for this same reason.\n\n✅ **Coverage (v1.1+):** all three pitakas at parity with SuttaCentral\n`bilara-data`:\n- Sutta Piṭaka (DN/MN/SN/AN/KN): Pāli + bilara EN (5,791 sections) —\n Sujato for DN/MN/SN/AN and most of KN; a few KN books have other\n bilara translators\n- Vinaya Piṭaka: Pāli + Brahmali EN — SC codes e.g.\n `pli-tv-bu-vb-pj1` (Bhikkhu Pārājika 1), `pli-tv-bi-vb-pj1`\n (Bhikkhunī), `pli-tv-kd1` (Mahāvagga), `pli-tv-pvr10` (Parivāra),\n `pli-tv-bu-pm` (Bhikkhu Pātimokkha)\n- Abhidhamma Piṭaka: 7 books (ds, vb, dt, pp, kv, ya, patthana) —\n Pāli only (bilara has no English translator for any Abhidhamma book)",
"inputSchema": {
"additionalProperties": false,
"properties": {
"around": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "A segment_id to center on (e.g. \"dn22:18.1\"). Returns the\n `window` segments before and after it. Ignored if None."
},
"edition": {
"anyOf": [
{
"enum": [
"dhiranandi",
"jayasaro",
"mbu",
"royal"
],
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Thai translation edition — \"dhiranandi\", \"jayasaro\",\n \"mbu\", \"royal\", or None. If None, uses `text_thai` from\n bilara-data. ⚠️ The DB has no Thai editions loaded yet,\n so most values return null."
},
"language": {
"default": "pali",
"description": "Which language to return — \"pali\", \"thai\", \"english\",\n or \"all\" (default: \"pali\"). Thai is currently disabled\n on the server, so Thai fields return null.",
"enum": [
"pali",
"thai",
"english",
"all"
],
"type": "string"
},
"limit": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"description": "Max segments to return from `offset` (default None = to end,\n clamped 1–2000)."
},
"mode": {
"default": "full",
"description": "\"full\" (default, returns segment text) or \"outline\" (table of\n contents only — section keys/titles/counts, no segment text).",
"enum": [
"full",
"outline"
],
"type": "string"
},
"offset": {
"default": 0,
"description": "0-based ordinal start for paging (default 0).",
"type": "integer"
},
"segment_range": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Inclusive slice \"<startId>..<endId>\" (e.g.\n \"dn16:2.1.0..dn16:2.2.8\"). Omit the end id to read to\n the sutta's end. Uses the `..` separator."
},
"sutta_id": {
"description": "Sutta ID, e.g. \"mn1\", \"dn22\", \"sn56.11\", \"dhp1-20\".",
"type": "string"
},
"window": {
"default": 10,
"description": "Segments before AND after `around` (default 10, clamped 0–200).",
"type": "integer"
}
},
"required": [
"sutta_id"
],
"type": "object"
},
"name": "get_sutta"
},
{
"description": "Look up the dictionary meaning of a Pāli word, with sutta context.\n\nServes as a Pāli Dictionary Bridge — pairs the \"definition\" with the\n\"context where the Buddha actually used the word\".\n\n📖 **About the dictionary sources:**\nThis tool draws from multiple primary dictionaries, including\n\"พจนานุกรมพุทธศาสน์ ฉบับประมวลศัพท์\" (Buddhist Dictionary —\nConcept-Glossary edition) by Somdet Phra Buddhaghosacariya (P. A.\nPayutto). The Thai-language entries are **original scholarly works**\n(not translations), so they are **always available** even when\nENABLED_LANGUAGES has Thai disabled. The AI client should translate\nThai entries into the user's language if needed.\n\n🔀 **Two kinds of thing in one payload.** `definitions[]` come from the\ndictionaries, not the canon, so they carry **no `segment_id`**;\n`appears_in_context[]` is corpus text and does carry one. `related_words[]`\nare headwords holding your query as a substring, so opposites appear —\n`dhamma` returns `adhamma`. Context examples are drawn at random: two\nidentical calls return different ones.",
"inputSchema": {
"additionalProperties": false,
"properties": {
"language": {
"default": "all",
"description": "Dictionary language (e.g. \"en\", \"thai\", or \"all\" as\n default).",
"enum": [
"en",
"thai",
"th",
"all"
],
"type": "string"
},
"limit_context": {
"default": 3,
"description": "Number of sutta-context examples to include (1-5).",
"type": "integer"
},
"word": {
"description": "Word to look up (e.g. \"dukkha\", \"กฐิน\").",
"type": "string"
}
},
"required": [
"word"
],
"type": "object"
},
"name": "get_word_definition"
},
{
"description": "List the translation editions available, with coverage stats.\n\n💡 **Use this tool when:**\n- Before calling `compare_translations` or `get_sutta(edition=...)`,\n so you know which edition values are valid and worth comparing.\n- The user asks which editions are loaded in the DB.\n\n🔍 **Filtering:** Filtered by the server's `TRIPITAKA_ENABLED_LANGUAGES`\n— when Thai is disabled the list is empty. Only enabled languages\nare returned.\n\n⚠️ **Current state:** the DB mostly holds Pāli (default from\nSuttaCentral bilara) and English (bilara's translators). Thai editions\n(`dhiranandi`, `jayasaro`, `mbu`, `royal`) aren't indexed yet — the\nlist returns empty until they're loaded.",
"inputSchema": {
"additionalProperties": false,
"properties": {},
"type": "object"
},
"name": "list_editions"
},
{
"description": "Show the structure of all three pitakas with coverage statistics.\n\n💡 **Use this tool when:**\n- The user asks for an overview of the Tipiṭaka (what's in it / which\n collections).\n- You need to check coverage before promising a search will find\n something — `segment_count > 0` is the active-loaded signal.\n- Verifying scope when compiling an artifact.\n\n📊 **Current state (v1.1+, at parity with SuttaCentral bilara-data):**\n- **Sutta Piṭaka** complete: DN 37, MN 155, SN 1,829, AN 1,419, KN\n 2,351 sections (~284,702 segments) — Pāli + bilara EN (Sujato for\n DN/MN/SN/AN and most of KN; a few KN books have other bilara\n translators)\n- **Vinaya Piṭaka** complete: Bhikkhu Vibhaṅga 222, Bhikkhunī Vibhaṅga\n 127, Khandhaka 22, Parivāra 51 + Pātimokkha 2 (~71,557 segments) —\n Pāli + Brahmali EN\n- **Abhidhamma Piṭaka** complete: 7 books (ds, vb, dt, pp, kv, ya,\n patthana) ~88,414 segments — Pāli only (bilara has no English for\n any Abhidhamma book)\n- **Total ~444,673 segments** in the DB\n\n⚠️ **Known quirks:**\n- The schema carries duplicate legacy + SC-modern codes side by side:\n - Vinaya: `vin-v/vin-m/vin-c/vin-p` (legacy, segment_count = 0)\n alongside `pli-tv-bu-vb/pli-tv-bi-vb/pli-tv-kd/pli-tv-pvr`\n (active, populated).\n - Abhidhamma: `ym/pt` (legacy = 0) alongside `ya/patthana` (active).\n- **Use the `active` flag** — each nikaya carries `active: true/false`\n (true ⇔ `segment_count > 0`). Pick `active` nikayas; the others are\n metadata placeholders from an older migration.\n\n🌐 **Languages:** Returns Pāli + Thai + English labels regardless of\nenabled set (these are metadata, not segment text). Text content\nfollows ENABLED_LANGUAGES. Thai translations aren't loaded yet.",
"inputSchema": {
"additionalProperties": false,
"properties": {},
"type": "object"
},
"name": "list_structure"
},
{
"description": "Open an interactive sutta viewer inside the chat — Pāli + English,\nplus an optional third row in the user's own language translated BY YOU.\n\nRenders each segment as: Pāli on top (canonical), the bilara-data\nEnglish below it (verification anchor), and — when you supply\n`translations` — your translation in the user's language, clearly\nbadged as AI-generated. Prefer this over dumping raw segments when the\nuser wants to *read* a sutta.\n\n- `sutta_id` — standard SuttaCentral id, e.g. `sn56.11`, `mn10`, `dn22`.\n- `around` — a segment_id (e.g. `dn22:18.1`, from a search hit) to centre\n on; that segment is highlighted and scrolled into view. Use this after\n a search so the reader lands on the exact cited line.\n- `offset` — 0-based segment index for paging long suttas (use\n `next_offset` from the previous result). Do NOT combine with `around`.\n- `window` — segments before/after `around` to include (default 12).\n\n🌐 **Translating for the user (important):** when the conversation\nlanguage is neither English nor Pāli, you SHOULD translate the displayed\nsegments and pass them via `translations` so the user reads in their own\nlanguage while still seeing the originals:\n1. Fetch the segments first (`get_sutta` with the same selector) so you\n have the exact Pāli + English text. (Already called this tool without\n translations? The result contains the segments — translate them and\n call this tool AGAIN with the same selector plus `translations` to\n upgrade the view.) Your translation must travel through the\n `translations` parameter to appear in the viewer — writing it as a\n normal chat message leaves the viewer bilingual and looks broken; the\n tool always accepts `translations`, so never report it as missing.\n2. Translate **from the Pāli as the source, using the English as a\n semantic guide** — never relay-translate from English alone. Preserve\n untranslatable doctrinal terms (dukkha, jhāna, taṇhā…) as loanwords\n with a brief gloss instead of forcing equivalents.\n3. Call this tool with `translations=[{segment_id, text}, ...]` covering\n ONLY the segments being displayed (never a whole long sutta),\n `translation_language` (BCP-47, e.g. \"th\", \"es\"), and\n `translation_disclaimer` — one short line IN THE USER'S LANGUAGE\n saying the translation is AI-generated in this conversation and\n should be checked against the Pāli/English above.\nTranslations are conversation-ephemeral: nothing is stored server-side;\nthe canon stays Pāli + English only. Translations whose segment_id is\nnot in the displayed window are dropped (reported in\n`translations_dropped`).\n\nWithout `around`, shows the sutta from the top (capped for long suttas).",
"inputSchema": {
"additionalProperties": false,
"properties": {
"around": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null
},
"offset": {
"default": 0,
"type": "integer"
},
"sutta_id": {
"type": "string"
},
"translation_disclaimer": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null
},
"translation_language": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null
},
"translations": {
"anyOf": [
{
"items": {
"description": "คำแปล 1 segment ในภาษาของผู้ใช้ — สร้างโดย AI ฝั่ง client ระหว่างบทสนทนา.\n\nหลักการ: DB เก็บเฉพาะบาลี + อังกฤษ (แก่นต้นฉบับ) — คำแปลภาษาที่สามเป็นของ\nชั่วคราวประจำบทสนทนา ไม่ persist. viewer แสดงบาลี+อังกฤษเหนือคำแปลเสมอ\nเพื่อให้ผู้ใช้ตรวจสอบได้ทุกบรรทัด.",
"properties": {
"segment_id": {
"type": "string"
},
"text": {
"type": "string"
}
},
"required": [
"segment_id",
"text"
],
"type": "object"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null
},
"window": {
"default": 12,
"type": "integer"
}
},
"required": [
"sutta_id"
],
"type": "object"
},
"name": "open_sutta_viewer"
},
{
"description": "Strip Pāli inflectional suffixes to find the root form (basic stem).\n\n💡 **Use this tool when:**\n- You find an inflected Pāli word (e.g. `dukkhassa`, `bhikkhūnaṁ`) and\n `get_word_definition` doesn't find it directly — Pāli inflects nouns\n across 7 cases × 2 numbers, ~16 forms per root.\n- You want to see possible stems before another `get_word_definition`\n lookup.\n\n🔄 **Recommended workflow:**\n`parse_pali_word(inflected_form)` → get `possible_stems[]` →\ncall `get_word_definition(stem)` per stem until you find a definition.\n\n⚠️ **Limitations:**\n- Rule-based first-pass — strips common suffixes (case endings, vowel\n shortening). Not a full morphological analyzer.\n- Compound words (samāsa) are NOT split — `dukkhanirodha` won't be\n broken into `dukkha` + `nirodha`.\n- Sandhi (sound junctions) like `tena ahaṁ → tenāhaṁ` aren't reversed.\n- Returns **possible** stems — verify each via `get_word_definition`.\n\n⚠️ **`possible_stems` are rule output, not findings.** They come from the\nsuffix table applied to your input — nothing was looked up, so no field\ncarries a `segment_id`, and some candidates are not Pāli words at all. Treat\neach as a spelling to try in `get_word_definition`, never as an attested\nform.",
"inputSchema": {
"additionalProperties": false,
"properties": {
"word": {
"description": "An inflected Pāli word (e.g. \"dukkhassa\", \"bhikkhūnaṁ\",\n \"sīlavā\").",
"type": "string"
}
},
"required": [
"word"
],
"type": "object"
},
"name": "parse_pali_word"
},
{
"description": "Keyword search across the Pāli Tipiṭaka (trigram word-similarity).\n\nSearches the configured enabled language(s) on the server. Filterable\nby pitaka and translation edition.\n\n💡 **Hints for the AI client:**\nThe system's canonical reference is Romanised Pāli (from SuttaCentral).\nIf the user asks in a disabled or unsupported language, translate the\nkeyword to **Romanised Pāli (preferred) or English** before calling this\ntool — e.g. \"suffering\" → \"dukkha\", \"mindfulness of breathing\" →\n\"ānāpānassati\". See the server instructions for the enabled language set.\n\n✅ **Diacritics do not matter.** `anapanassati` and `ānāpānassati` return\nthe same thing; so do `nibbana` and `nibbāna`. Write the macrons if you\nknow them, guess without them if you don't — neither costs you results.\n\n⚠️ **A common Pāli noun is a poor query.** `samudda` (sea) matches ~700\nsegments and the top of that list is mostly section headings, not the\npassage that teaches anything. Two things to do instead:\n- Search the **rarest distinctive noun** in the passage, not its most\n obvious one. For the simile of the blind turtle, `turtle`/`kacchapa`\n gets there; `ocean`/`samudda` does not, in either language.\n- **Prefer English, or raise the limit.** `turtle` returns SN 56.47 and\n SN 56.48 inside the default window; `kacchapa` matches them too but\n ranks them past 30, so you need `limit=50` to see them.\n- A word inside a **compound** may be out of reach entirely: `samudda`\n scores 0.50 against `mahāsamudde` (compounded *and* inflected), under\n the 0.6 cutoff, so SN 56.47 is not ranked low — it is excluded. Trying\n more spellings will not recover it; search a different word instead.\n\n🔍 **Pick the right search tool for the question shape:**\n- **Term lookup (exact word appearances)** — e.g. \"occurrences of\n `ānāpānassati`\": this tool is best (trigram nails the exact word).\n- **Concept search (\"discourses about X\")** — e.g. \"discourses about\n mindfulness of breathing\": **use `search_hybrid` instead.** Canonical\n Pāli has two quirks that hurt keyword search for concepts:\n • Section headings (`Ānāpānapabba`) often use a different word than\n the teaching body, which uses verb forms (`assasati`, `passasati`,\n `dīghaṁ`, `rassaṁ`). E.g. DN22's Ānāpānapabba has 16 segments but\n the word `ānāpāna` appears in only 2 (header + footer) — the\n actual teaching segments won't match.\n • Stock phrases (e.g. `So satova assasati, satova passasati`)\n recur in 10+ suttas, so a keyword query ranks broadly and won't\n pinpoint the canonical reference.\n- **General keyword survey** — set `limit≥30` and filter client-side,\n or call multiple related forms (root verb + noun + compound).\n\n📊 **Reading the two scores.** `word_similarity` is the primary sort key: it\nscores your query against the best-matching span inside the line, 0 to 1,\nand a row appears at all only if it clears the 0.6 cutoff. `similarity`\nscores it against the **whole line**, so it falls as the line grows longer.\nBoth measure resemblance of letters — neither measures doctrinal importance.",
"inputSchema": {
"additionalProperties": false,
"properties": {
"edition": {
"anyOf": [
{
"enum": [
"dhiranandi",
"jayasaro",
"mbu",
"royal"
],
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Thai translation edition — \"dhiranandi\", \"jayasaro\", \"mbu\",\n \"royal\" or None. Only used when language=\"thai\" and Thai is\n enabled on the server."
},
"keyword": {
"description": "The word/phrase to search for.",
"type": "string"
},
"language": {
"default": "pali",
"description": "Search language — must be in the server's ENABLED_LANGUAGES\n (default: \"pali\"). Disabled languages return an error.",
"enum": [
"pali",
"english",
"thai"
],
"type": "string"
},
"limit": {
"default": 10,
"description": "Maximum results (default: 10, max: 50).",
"type": "integer"
},
"pitaka": {
"anyOf": [
{
"enum": [
"vinaya",
"sutta",
"abhidhamma"
],
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Filter by pitaka — \"vinaya\", \"sutta\", \"abhidhamma\" or None\n (all). ✅ v1.1+: all three pitakas at parity with SuttaCentral\n bilara — see list_structure for live counts."
}
},
"required": [
"keyword"
],
"type": "object"
},
"name": "search_by_keyword"
},
{
"description": "Hybrid search — combines keyword + semantic search via RRF.\n\nUses Reciprocal Rank Fusion (RRF) to merge exact-word results with\nmeaning-based results. **This is the recommended tool for \"discourses\nabout X\" / concept queries**, because the semantic side catches suttas\nthat discuss a concept using different vocabulary (e.g. some\nmindfulness-of-breathing suttas use `assasati/passasati/dīghaṁ`\ninstead of `ānāpānassati`).\n\n⚠️ **Send the question and nothing else. Do not pad the query.**\nThe whole string becomes one vector, so every word you add moves it.\nAppending your own candidate terms — synonyms, Pāli equivalents, a\nkeyword list — searches for the blend, not for the question.\n\nMeasured on `Buddha flies in the sky`: asking it plainly put the right\npassage at **rank 1** (3 relevant suttas). Appending three guessed Pāli\nterms (`buddha, agga, sagga`) pushed it down to **rank 5** and left\nonly 1 — because `agga` (supreme) and `sagga` (heaven) drag the vector\ntoward their own meanings.\n\nHave candidate terms worth searching? Give them their own\n`search_by_keyword` call and merge the two result lists. One tool asks\nwhat a passage means, the other asks where a word occurs; combined into\na single string they cancel out.\n\nRewriting the question to sound more canonical does not help either —\nthe same query phrased as `rose into the air and flew like a bird`\nscored **zero** relevant hits.\n\n💡 **Hints for the AI client:**\n- English queries usually work best (e.g. `mindfulness of breathing`)\n because the embedding model is multilingual but EN-primary.\n- Thai stop-word handling is weak. If a Thai query underperforms, the\n AI client should translate to Pāli/English first (see server\n instructions).\n- The default `limit=5` is often too small for a topic survey — use\n `limit=15-20` (max 20) for good coverage.\n- `language` only chooses what comes back; it does not change what\n matches or how results are ranked.\n- Looking for a concrete thing rather than a concept (an animal, an\n object, a place)? `search_by_keyword` over `language=\"english\"` is\n often better. The translations are segment-aligned to the Pāli, so\n one search for `turtle` finds every turtle passage whatever the Pāli\n underneath says (`kacchapa`, `kumma`, `maṇḍūkakacchapa`), and each\n hit still carries its segment id.\n- Ranking is by similarity, NOT canonical importance — locus\n classicus suttas (e.g. MN118, DN22) may rank below smaller suttas\n that happen to use the exact vocabulary. Treat results as a\n starting point, then call `get_sutta` for the canonical references.",
"inputSchema": {
"additionalProperties": false,
"properties": {
"language": {
"default": "pali",
"description": "Output language — \"pali\", \"thai\", \"english\", or \"all\".",
"type": "string"
},
"limit": {
"default": 5,
"description": "Maximum results (default: 5, max: 20).",
"type": "integer"
},
"query": {
"description": "Query text (Thai, Pāli, or English — English works best).",
"type": "string"
}
},
"required": [
"query"
],
"type": "object"
},
"name": "search_hybrid"
},
{
"description": "Semantic search — match by meaning, not exact words.\n\nUses vector similarity (cosine distance) over `text_pali` embedded with\na multilingual MiniLM model.\n\n🤔 **In most cases you should use `search_hybrid` instead** — it\ncombines this semantic search with keyword search and ranks better.\nUse this tool only when you need:\n- Pure semantic results (no keyword influence)\n- Fine-grained `threshold` tuning (hybrid uses RRF which is harder\n to tune)\n- To debug what semantic alone picks up vs keyword\n\n⚠️ Known limitations:\n- The index is **Pāli only** (English/Thai queries pass through the\n multilingual embedding but the model isn't tuned on Pāli)\n- English queries usually embed better than Thai (model is EN-primary)\n- For specific Pāli terms (`appamāda`, `dukkha`), exact match is\n better — use `search_by_keyword` instead\n- Pāli stock phrases recur in many suttas → similarity scores\n cluster; read the top 10, don't trust rank 1 alone\n\n📐 **Reading `distance`.** It is cosine distance between your query's\nembedding and the segment's, so smaller is closer, and a row is returned\nonly at or under `threshold` (default 0.7) — an empty result means nothing\ncleared that cut. Ordering is proximity of meaning in one model's space, not\ndoctrinal importance.",
"inputSchema": {
"additionalProperties": false,
"properties": {
"language": {
"default": "pali",
"description": "Output language — \"pali\", \"thai\", \"english\", or \"all\"\n (Thai disabled → null).",
"type": "string"
},
"limit": {
"default": 5,
"description": "Maximum results (default: 5, max: 20).",
"type": "integer"
},
"query": {
"description": "Query text (English works best, then Pāli, Thai is weakest).",
"type": "string"
},
"threshold": {
"default": 0.7,
"description": "Maximum cosine distance (smaller = stricter match).\n Default 0.7; lower to 0.5 for tighter matches, raise\n to 0.9 for broader.",
"type": "number"
}
},
"required": [
"query"
],
"type": "object"
},
"name": "search_semantic"
},
{
"description": "Exhaustively survey the WHOLE Tipiṭaka for a term — guaranteed complete.\n\nUse this (not `search_by_keyword`) when the question is about **coverage or\ncounting** rather than \"show me the best passages\":\n- \"How many times does Kusinārā appear in the canon?\"\n- \"Every place ānāpānassati is mentioned — don't miss any\"\n- \"Which pitakas/how many suttas mention this term?\"\n\nUnlike `search_by_keyword` (ranked, capped at 50, no total), this returns an\n**exact count**, a **per-pitaka breakdown**, the **distinct surface forms**\nthat matched (so you can audit and discard over-matches), and a paginated\nenumeration. The `lexical` result carries `complete: true` — a hard\nguarantee that nothing was dropped for the chosen `match_scope`.\n\nTwo layers, two different promises:\n- **lexical** — the word and its forms. Deterministic + EXHAUSTIVE.\n- **semantic** (`mode=\"thorough\"`, hosted only) — passages teaching the same\n concept with DIFFERENT vocabulary (e.g. ānāpānassati via\n `assasati`/`passasati`). Approximate, **NOT exhaustive** — it never claims\n completeness, it only boosts recall.",
"inputSchema": {
"additionalProperties": false,
"properties": {
"cursor": {
"default": 0,
"description": "Offset into the full lexical result set for pagination.",
"type": "integer"
},
"keyword": {
"description": "Term to survey (Romanised Pāli preferred; diacritics optional —\n matching folds `ā→a`, `ṁ→m`, etc.).",
"type": "string"
},
"language": {
"default": "pali",
"description": "\"pali\" (default) or \"english\". Thai is not indexed yet.",
"enum": [
"pali",
"english"
],
"type": "string"
},
"match_scope": {
"default": "word",
"description": "\"word\" (default) matches the exact word/phrase only.\n \"stem\" also matches inflections + compounds via prefix\n (kusinārā → kusinārāyaṁ, kusināravagga …) — higher recall,\n may over-match (audit via `matched_forms`).",
"enum": [
"word",
"stem"
],
"type": "string"
},
"mode": {
"default": "fast",
"description": "\"fast\" (default) = lexical only — quick, no server-side ML, works\n offline. \"thorough\" = also run the semantic layer (hosted only;\n this is the heavier part). The lexical guarantee holds in BOTH.",
"enum": [
"fast",
"thorough"
],
"type": "string"
},
"page_size": {
"default": 20,
"description": "Lexical results per page (default 20, max 100). Counts/forms\n cover the WHOLE corpus regardless of this.",
"type": "integer"
},
"pitaka": {
"anyOf": [
{
"enum": [
"vinaya",
"sutta",
"abhidhamma"
],
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Restrict to \"vinaya\" / \"sutta\" / \"abhidhamma\", or None for all."
},
"sem_limit": {
"default": 50,
"description": "Max semantic hits (default 50, max 200). `capped` flags when\n reached. Only used when mode=\"thorough\".",
"type": "integer"
},
"sem_threshold": {
"default": 0.7,
"description": "Max cosine distance for semantic hits (default 0.7;\n lower = stricter). Only used when mode=\"thorough\".",
"type": "number"
}
},
"required": [
"keyword"
],
"type": "object"
},
"name": "survey_corpus"
},
{
"description": "Verify, check, or confirm a Buddha quote — does the canon really say it?\n\nFact-check a quotation attributed to the Buddha. Catches fake, misquoted,\nmisattributed and misremembered passages, and finds the true reading.\n\nPaste a line that has been quoted or half-remembered — Pāli or English —\nand this says whether the canon really contains it, cites where, and if\nnot, shows the closest thing that is actually there.\n\n🧭 **When to use this:**\n- A quote is attributed to the Buddha and you are not certain it is real.\n A fabricated line that *sounds* canonical is the hardest error to catch\n by reading, because it reads correctly. Check it instead of trusting it.\n- Someone recalls a passage imperfectly, or a chanted form has drifted\n from the written one. The tool shows the received text beside theirs.\n- **Before repeating any Pāli you did not get from these tools**, verify\n it. This is cheap and it is the difference between citing and guessing.\n\n⚠️ **Do not present an unverified passage as canonical.** If the verdict\nis `not_found`, say plainly that the line is not in the canon rather than\nquoting it with a hedge — a hedged fabrication still spreads.\n\n⚖️ **Verdict thresholds.** `exact` = `contained` **or** `similarity` ≥\n0.995; `close` = `coverage` ≥ 0.85 **and** `similarity` ≥ 0.55; else\n`not_found`. `exact` means letters matched once folded, not that a human\nconfirmed the reading. Matches also carry `coverage` (your letters present,\nin order), `contained` (present whole) and `spans` (segments joined; >1 →\n`segment_id` is the first only).",
"inputSchema": {
"additionalProperties": false,
"properties": {
"limit": {
"default": 3,
"description": "How many near matches to return when it is not exact (1–10).",
"type": "integer"
},
"text": {
"description": "The passage as quoted. Diacritics optional, folded internally.\nOne line works best; the canon is segmented line by line, so a\nquote spanning several segments may only match in part.",
"type": "string"
}
},
"required": [
"text"
],
"type": "object"
},
"name": "verify_quote"
}
]
}What the leaf hashes
{"body":"d4f0daf0fbd53272a3bf3a2a1ca99d50a267fa8401755cb8fbbd6e9554616235","id":103459,"kind":"mcp.tools","method":"probe.mcp/1","observed_us":1793025575532182,"prev":null,"subject":"13fcea10-54e7-4beb-8131-486a3bf88ac3","subject_kind":"endpoint"}Proof
Fold these into the leaf in order, hashing each sorted pair with keccak256, to reach the root of (296695 rows).
- 0x7b4d330a6bab37be5a694ed59ee30a51751e546a0dd5869572ea305b2528c8ef
- 0x21459fd72e24a7717015b6fda9e36776d8fb737409f3019e76276cfd6e520869
- 0x6a0d542780399b33a5fc4c6ad2411240a2243b03d266e91251d8afada0e856b6
- 0x71c0a95834025a48f434ee7c8f1a0e72d570693a82ab7d90089e53e637c1b56c
- 0xdf915e3d33c6d3277f73cb0db6df740651920855bbe45894b313da37b4e1fe6f
- 0x7e6da5c9ff34636a5b88a7d969f6ce93e433977dab7088787dc2858d41cb77d1
- 0x8a73ea42b685d832f88c3928b04dafbf10e70a1af177f8885e6c3ff57e66bb27
- 0xaf909d72867b44b28d27b62dd1a9871623fe9f3589d36a21ad34a009fbab653a
- 0xea27996197dfdf1dffb31590f1a512e6206a8c51ca8f78c38534fe5bf31b37b7
- 0xf2381ca3135154cac94d3453c232f31feb3dabefbf1c73459b1e84459d545370
- 0xe7152aaccc7d7d5da2d13bc6ee8ec470b8c1a5abe7dfed1431f0ed53ec50ebc5
- 0xa6406b1a5540d26e0cbd03bb274a01c10968fadb17913a6043bb9427ddfb71ba
- 0x01c95624b1f2385ef774ee258a9ae58a4df07a1bdaa829de84e1d5201f3f39c2
- 0x7721d38652b6444b18e1193824e50490ade04851ce6221771f6e374c4527d80f
- 0x15039087bf60ae9b06b756ec3cbc299760e59923a438bbd91e34d105186db0ed
- 0x2b6e23e3624a1b66e1d2298cfbce99a93ce6b13d24a58112a71802d79c5f7a76
- 0xd21942ae3214eff88e08ab04884fd4b11958b51af9a0741b7668e2d07a2c56c9
- 0x9a9024edb5069d88a324facb310a5ce8e495214bbaa968f077bede437390194f
- 0x9b9ce5b74b9bab5121612ef6b64920a8d453cbf311096a423eef9702747e868a
- Day root
- 0xf43e8dcc3d451a4788b26be904c55e8c4c0fa75c9666796c51db38d37e2c0df8
- Chained
- 0x702d5ac508f08b0d1accf36af25822d8e5660367494edd17a642fb61e158a57a
- Published
- On Arc Testnet, block 69251483: 0x495162f8936e19f0039918feebe6c307f327cd6bf8c37219620b1970041fa9ae