tripitaka-mcp
An MCP server that lets an AI client search, read, verify, and cite the Pāli Tipiṭaka (~444K segments across Vinaya, Sutta, and Abhidhamma) with clickable links back to a bilingual Pāli/English reader.
Concept search —
search_hybridmerges keyword + semantic hits via Reciprocal Rank Fusion; the recommended tool for "discourses about X" (uselimit15–20).Exact word search —
search_by_keywordfor trigram/fuzzy matches of a specific term (appamāda,ānāpānassati), filterable by pitaka and Thai edition.Meaning-based search —
search_semanticfor pure vector similarity with tunable cosinethreshold.Exhaustive counting —
survey_corpusreturns exact totals, per-pitaka breakdowns, matched surface forms, and paginated enumeration when you need every occurrence ("how many times does Kusinārā appear?").Read suttas —
get_suttaby SuttaCentral ID (mn1,dn22,sn56.11,dhp1-20) with outline/TOC mode, context windows around a segment, segment ranges, and offset paging for long texts likedn16(1,664 segments).Verify quotes — check a passage against the canon (
verify_quote) before attributing it to a source.Cite —
get_referenceproduces a formatted academic citation with canonical location and source URLs.Compare translations —
compare_translationsshows a single segment across editions;list_editionsreports what's loaded.Pāli word study —
get_word_definitionbridges Payutto/PTS/DPPN dictionaries with sutta usage examples, andparse_pali_wordstrips inflections to recover root stems (bhikkhūnaṁ→bhikkhu).Orientation —
list_structurereports the three-pitaka hierarchy with live segment counts andactiveflags so you can confirm coverage before promising results.Verifiability — every response carries deep-link URLs (sutta- and segment-level) into the project's bilingual reader, so users can check the authoritative text in one click.
Tripitaka MCP Server
An MCP server for searching and citing content from the Pāli Tipiṭaka. It lets AI clients such as Claude or Cursor look up suttas, quote the teachings, and compare translations across languages.
🙏 This project is offered as Dhamma Dāna: 100% free, non-commercial only. License details: LICENSE (code) and NOTICE.md (data)
✨ Features
Full Tipiṭaka coverage, at parity with SuttaCentral. All three baskets are indexed, about 444K segments. Sutta carries Pāli plus English from
bilara-data's translators (Bhikkhu Sujato for DN/MN/SN/AN and most of the Khuddaka Nikāya, with John Kelly, Bhikkhu Kovilo and others for a few KN books). Vinaya carries Pāli plus Bhikkhu Brahmali's English. Abhidhamma is Pāli only, because upstreambilara-datahas no English for any Abhidhamma book.list_structurereports live counts.Hybrid search merges keyword and semantic results through Reciprocal Rank Fusion (RRF). It is the most precise of the search tools and needs no configuration.
Keyword search with trigram fuzzy matching and cross-language alignment.
Semantic search by meaning, using vector similarity (pgvector).
Translation comparison across editions, aligned segment by segment.
Dictionary bridge with 20,000+ entries (P. A. Payutto, PTS, DPPN).
Sutta fetch and citations. Get a sutta by ID (
mn1,pli-tv-bu-vb-pj1,patthana1.1) and generate a properly formatted academic citation.Pāli word analyzer that strips inflectional suffixes to find the root form when a dictionary lookup misses (
bhikkhūnaṁ→bhikkhu).Cross-reference URLs in every response: a clickable deep link into the project's own bilingual reader (Pāli + English, with a segment anchor that highlights the cited verse). The reader renders SuttaCentral's
bilara-dataverbatim, so it is the authoritative text, and AI clients surface the link so users can verify the source in one click.Dual transport: legacy SSE (
/sse) and canonical Streamable HTTP (/mcp, MCP spec 2025-03-26).MCP resources:
tripitaka://structure,tripitaka://sutta/{id},tripitaka://word/{w}, for clients that pin context as resources.Curated reference pages at
/topics/*: six markdown pages covering canon structure, getting started and tool selection, places (Mahājanapada, holy sites, cosmology), 10 foundational themes with locus classicus, about 30 major figures, and a phase-based timeline of the Buddha's 45-year mission. Sutta IDs are verified against live data, and an AI client can fetch one page instead of running 30+ tool calls.Claude skill.
skills/tipitaka-research.mdis a ready-to-install workflow file that turns on a multi-step research pattern (clarify → verify coverage → search → drill in → cite) on Claude Desktop and Claude Code.Postman collection included for testing the API.
Related MCP server: sacred-texts-mcp
🏗️ Tech stack
Technology | Role |
Python + FastMCP | MCP Server |
PostgreSQL + pgvector | Database + Vector Search |
sentence-transformers | Embeddings for semantic search |
Docker Compose | Infrastructure |
🚀 Quick start
🌐 No setup: connect to the public Dhamma Dāna server
The maintainers run a free public instance at tripitaka-mcp.com.
Endpoint | Use |
| Streamable HTTP (MCP spec 2025-03-26) |
| Legacy SSE (older clients) |
Connecting Claude Desktop takes three steps. Nothing to install but Node.js, and no Docker or GPU.
1. Find your absolute npx path. Claude Desktop doesn't read your shell profile, so a bare npx won't resolve. Open a terminal:
which npx
# example: /Users/you/.nvm/versions/node/v22.14.0/bin/npx2. Open claude_desktop_config.json (~/Library/Application Support/Claude/ on macOS, %APPDATA%\Claude\ on Windows) and add the entry below. Substitute YOUR_NPX_PATH with the output from step 1, and YOUR_NODE_BIN_DIR with that path's parent directory:
{
"mcpServers": {
"tripitaka": {
"command": "YOUR_NPX_PATH",
"args": ["-y", "mcp-remote", "https://mcp.tripitaka-mcp.com/mcp"],
"env": { "PATH": "YOUR_NODE_BIN_DIR:/usr/local/bin:/usr/bin:/bin" }
}
}
}3. Quit Claude Desktop completely (⌘Q on macOS, tray → Quit on Windows) and reopen. The 🔌 indicator in the bottom-left should show tripitaka with 14 tools available.
The first connection takes 5 to 10 seconds while
npxdownloadsmcp-remoteon demand. Give Claude Desktop a moment after the restart before deciding it failed.
Once connected, try asking Claude things like:
"What does the Buddha teach about mindfulness of breathing? Quote the relevant passages from MN 118."
"Show me the full text of the Karaṇīyamettasutta in Pāli and English."
"What does the Pāli word sati mean according to the Payutto dictionary?"
"Find suttas where the Buddha discusses anger."
Claude will pick the right tool, fetch the canonical Pāli, and surface a clickable link to the project's bilingual reader for verification.
The hosted server is a small free service offered for personal study, research, and dhamma practice. Keep your request rate reasonable; bursts may be throttled at the edge. Read NOTICE.md before redistributing it or using it commercially.
💻 Run it fully offline (pipx, local SQLite, no server)
If you would rather keep everything on your own machine, with no network calls to the hosted server, install the local edition. It carries the whole Pāli canon as a single SQLite file (~120 MB) and runs as a local stdio MCP server.
pipx install tripitaka-mcp # needs Python 3.10+
tripitaka-mcp init # one-time: downloads the SQLite database
tripitaka-mcp serve # runs the MCP server over stdioIf the install fails like this:
Because the current Python version (3.9.6) does not satisfy Python>=3.10pipx is using a different interpreter than you think. It builds its own isolated environment on purpose and ignores whatever venv you have active, so an old system Python gets picked even when the shell you typed in has 3.12. Tell it which to use:
pipx install --python python3.12 tripitaka-mcp(Any 3.10 or newer works; pipx environment shows what it defaults to.)
Then point Claude Desktop or Cursor at the local command, with no npx bridge and no internet:
{
"mcpServers": {
"tripitaka": {
"command": "tripitaka-mcp",
"args": ["serve"]
}
}
}(If tripitaka-mcp isn't on the client's PATH, use the absolute path from which tripitaka-mcp.)
Need a URL instead of stdio? Scripts, notebooks, and anything that shares one server across several clients want an HTTP endpoint rather than a subprocess:
tripitaka-mcp serve --http # http://127.0.0.1:8765/mcp
tripitaka-mcp serve --http --port 9000 # or MCP_HOST / MCP_PORTIt binds 127.0.0.1 unless you say otherwise; the canon is read-only, but
nothing here asks who is calling, so think before binding a public interface.
Hosted vs local
Both serve the same ~444K-segment canon. The differences:
Hosted ( | Local ( | |
Tools | all 14 | 11, or 12 with |
Concept / semantic search | ✅ vector search (pgvector) | ❌ use |
Keyword search | PostgreSQL trigram: fuzzy, typo tolerant, similarity ranked | SQLite FTS5: whole-word / token match, so results and ranking can differ from hosted |
Canon data | always current | a snapshot from when you ran |
Updates | automatic |
|
Privacy | queries reach the hosted server (nothing logged, see the Privacy Policy) | nothing leaves your machine |
Internet | required | not needed after |
Rate limit | bursts may be throttled at the edge | none |
Setup | zero / one-click | Python 3.10+, pipx, one-time ~120 MB download |
search_semantic, search_hybrid, and the trigram keyword index need PostgreSQL, pgvector, and a ~1 GB embedding model, which is more than a lightweight local install should carry, so they stay hosted-only. In local mode those two tools are never registered: a connected client sees only the 11 it can actually call.
Because the local server is a standard stdio MCP server, it also gives you a fully offline AI stack. Pair it with a local model such as Ollama and any MCP-capable chat UI, and nothing leaves your machine.
🏎️ Fastest local path: the installer (recommended for non-developers)
git clone https://github.com/dhamma-seeker/tripitaka-mcp.git
cd tripitaka-mcp
./scripts/install.shThe installer downloads a prepared database dump from Hugging Face (dhamma-seeker/tripitaka-mcp-dump) and restores it for you, which brings setup down from two to four hours (loading the data, then generating embeddings) to about five minutes. (If a dump file is already on disk, the installer uses that copy instead.)
The installer will:
Verify that
docker,compose,openssl, andcurlare installedGenerate
.envwith random passwords (for both the admin and the readonly user)Download the dump from Hugging Face (if not already local)
Start the DB and restore the dump
Set up the readonly role and runtime timeouts
Print a ready-to-paste Claude Desktop config
Options:
./scripts/install.sh --dump PATH # use an existing dump file
./scripts/install.sh --dump-url URL # override the dump source
./scripts/install.sh --no-dump # skip restore (load data yourself later)🔧 Manual setup (for developers)
1. Clone & setup
git clone https://github.com/dhamma-seeker/tripitaka-mcp.git
cd tripitaka-mcp
cp .env.example .env
# Set POSTGRES_PASSWORD in .env to a random password2. Start database
docker compose up db -d3. Install dependencies
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt4. Initialize database & load data
# 1. Seed metadata (pitaka, nikāya)
python scripts/seed_metadata.py
# 2. Download & load Sutta Piṭaka data from SuttaCentral
python scripts/data_loader.py
# 3. Load Thai CC0 translations (Dhīranando & Jayasāro)
python scripts/load_thai_cc0.py
# 4. Load dictionaries (DPD, PTS, DPPN, and the Payutto dictionary)
python scripts/load_dictionary.py
# 5. Generate embeddings for semantic / hybrid search
python scripts/generate_embeddings.py5. Run MCP server
python main.py🧪 Testing with Postman
You can drive the tools from Postman in SSE mode:
Run the server with:
MCP_TRANSPORT=sse python main.pyImport postman_collection.json into Postman
Invoke the tools directly
🚢 Production deployment
For production, restore from a database dump instead of re-loading the data and re-running the embedding model.
docker compose -f docker-compose.prod.yml up -d --buildThe production stack runs 5 services:
db: PostgreSQL + pgvector (internal only, no exposed port)mcp-server: FastMCP over legacy SSE, behind/sse(readonly DB user, read-only FS,cap_drop: ALL)mcp-server-http: the same server over Streamable HTTP, behind/mcpreader: the bilingual reader that every cross-reference URL points at, behind/read/*caddy: reverse proxy and Let's Encrypt. Itsrate_limitblock for the MCP site is declared but does not run as written, which DEPLOYMENT.md explains
For another layer of hardening, put Cloudflare in front of Caddy (DNS proxy, rate-limit rules, and DDoS protection on the free tier).
Full details are in DEPLOYMENT.md.
🔧 Connecting to Claude Desktop
The repo ships claude_desktop_config.example.json with three ready-to-use entries. Copy whichever fits your setup into claude_desktop_config.json (~/Library/Application Support/Claude/ on macOS, %APPDATA%\Claude\ on Windows), then edit the absolute paths:
Entry | When to use | Transport |
| You ran the installer locally on the same machine as Claude Desktop | stdio (no network) |
| You self-hosted the server on a VPS and want the modern transport | Streamable HTTP ( |
| Your client doesn't support Streamable HTTP yet | Legacy SSE ( |
The remote entries route through mcp-remote, a bridge from Claude Desktop through npx to the remote MCP server. The example file comments every field; remove the _comment keys before saving.
For nvm users:
commandandenv.PATHneed absolute node paths, because Claude Desktop doesn't read your shell profile. Get them fromwhich npxandwhich pythonwhile your normal shell is active.
Optional: install the research skill
On Claude Desktop and Claude Code, copying the bundled skill turns on the multi-step research workflow:
mkdir -p ~/.claude/skills
cp skills/tipitaka-research.md ~/.claude/skills/
# Restart Claude Desktop (Cmd+Q then reopen) to pick up the skillDetails in skills/README.md.
📦 MCP tools (14 total)
Tool | Description |
| Combined keyword + semantic search via RRF. Recommended for concept search, when you are after "discourses about X". |
| Trigram keyword search, best for the top few matches of an exact word ( |
| Exhaustive corpus survey: exact total, per-pitaka breakdown, and the matched word-forms. For "how many times" or "every place X appears", where you need every occurrence rather than the best matches. |
| Pure vector similarity. Usually |
| Check a quote against the canon before repeating it. Returns |
| Fetch a sutta by ID (e.g. |
| Interactive sutta viewer (MCP Apps). Renders the sutta inline in the chat as Pāli + English side by side, with the cited segment highlighted. The calling model can attach an AI translation of the displayed segments into the user's own language ( |
| Generate a properly formatted academic citation with all source URLs. |
| Compare renderings of a single segment across editions. |
| Show the Tipiṭaka structure with segment-count coverage per nikāya. |
| List any additional translation editions loaded beyond the bundled Pāli + English. The public server currently carries none, so it answers plainly that there are no extra editions. |
| Pāli dictionary lookup (PTS, DPPN, and the Payutto Thai dictionary). |
| Find how the suttas and Vinaya define a term in their own words: canonical formulas like "Katamañca X? ... ayaṁ vuccati X", "X adhivacana", and the Vinaya's "X nāma". Gives primary-source definitions where |
| Strip Pāli suffixes to recover the root form when |
⚠️ Note on search_semantic
The vector index is built only on text_pali, using a multilingual MiniLM model that was not trained specifically on Pāli. (bilara-data carries Thai for 6 files in all, and the public server loads no Thai edition.) So:
Pāli and English queries come back accurate, with good cross-lingual alignment.
Thai queries return loose matches and aren't recommended.
For an exact keyword like
appamāda,search_by_keywordis more precise.For general-purpose search,
search_hybrid(keyword + semantic) tolerates the limitation best.
Moving to a Pāli-trained embedding model such as bge-m3, and embedding the Thai edition, are both on the roadmap.
📁 Project structure
tripitaka-mcp/
├── main.py # Main MCP Server (14 tools, 1 resource + 2 resource templates)
├── cli.py # `tripitaka-mcp` CLI (init / serve) for the pipx edition
├── sutta_verify.py # Quote matching behind `verify_quote`
├── sutta_definitions.py # Canonical definition formulas behind `define_from_suttas`
├── sutta_titles.py # Sutta title resolution
├── mcp_app.py # MCP Apps registration (env-gated, `TRIPITAKA_MCP_APP`)
├── db/
│ ├── connection.py # Database connection pool
│ └── schema.py # Schema (supports translation table)
├── embedding/
│ └── model.py # SentenceTransformer wrapper
├── scripts/
│ ├── install.sh # One-shot installer (HF dump → DB)
│ ├── deploy.sh # Deploy / restart on a VPS
│ ├── backup.sh # pg_dump → S3-compatible store
│ ├── dump_and_publish.sh # Verify embeddings → pg_dump → upload to HuggingFace
│ ├── seed_metadata.py # Seed pitaka/nikāya metadata
│ ├── data_loader.py # Load Sutta Piṭaka (Pāli + bilara EN, per-book translator)
│ ├── load_vinaya.py # Vinaya loader (Vibhaṅga + Pātimokkha + Khandhaka + Parivāra, Brahmali EN)
│ ├── load_abhidhamma.py # Abhidhamma loader (7 books, Pāli — bilara has no EN)
│ ├── load_thai_cc0.py # Thai translation loader
│ ├── load_dictionary.py # Load dictionary data
│ ├── scrape_payutto.py # Web scraper for the Payutto dictionary
│ ├── generate_embeddings.py # Generate vector embeddings
│ ├── run_embedding_with_retry.sh # Resilient wrapper around embedding generation (retries on DB drop)
│ ├── check_embedding_progress.py # Live progress snapshot (or --watch mode) for the embedding job
│ ├── smoke_test.sh # Endpoint smoke test (TLS + /sse + /mcp + /health)
│ ├── test_full_sutta.py # Full-content smoke test (22 size-tiered suttas, exact pinned counts)
│ ├── test_corpus_parity.py # Check the corpus against the bilara-data clone it claims parity with
│ ├── test_definitions.py # `define_from_suttas` regression + snapshot + backend parity
│ ├── test_verify_quote.py # `verify_quote` regression, both backends
│ ├── test_survey_counts.py # `survey_corpus` count drift
│ ├── test_pagination.py # Slice / window / offset behaviour
│ └── test_mcp_prompts.py # Prompt-level test — a real model picks the tools, a judge reads the answer
├── reader/ # Bilingual reader served at /read/* (FastAPI)
│ ├── app.py # Routes: /read/, /read/{sutta_id}, search, browse
│ ├── queries.py # Read-side queries
│ ├── featured.py # Landing-page sutta cards
│ └── sutta_id_decoder.py # Turn a sutta id into a human-readable location
├── site/ # Static landing page served at the apex domain
├── topics/ # Static markdown pages served at /topics/*
│ ├── README.md # Index of available topic pages
│ ├── tipitaka-overview.md # Canon structure + coverage
│ ├── getting-started.md # Connection paths, tool selection, prompt patterns
│ ├── places.md # Geography of the suttas (Mahājanapada, holy sites, cosmology)
│ ├── themes.md # 10 foundational teachings + locus classicus
│ ├── people.md # ~30 major figures (chief disciples, lay supporters, kings)
│ └── timeline.md # Phase-based timeline of the 45-year teaching career
├── skills/ # Portable Claude skills for AI clients
│ ├── README.md # How to install
│ └── tipitaka-research.md # Multi-step research workflow
├── infra/ # Reverse proxy + deploy config
│ ├── Caddyfile # Caddy: TLS, CORS for /mcp, /topics, /sse, /mcp
│ ├── Dockerfile.caddy # Caddy + caddy-ratelimit plugin
│ ├── cloud-init.yml # VPS bootstrap
│ └── *.tf # Terraform (provider-agnostic)
├── docs/
│ └── CAPACITY.md # Capacity planning per VPS spec
├── claude_desktop_config.example.json
├── docker-compose.yml # Dev (single mcp-server)
├── docker-compose.prod.yml # Prod (db + 2 mcp-server + reader + caddy)
├── Dockerfile
└── requirements.txt📜 Data sources & license
This project aggregates data from several sources under different licenses. Please read NOTICE.md in full before redistributing.
Source | License | Note |
Source code | MIT | Free to use, fork, modify |
CC0 | Public domain | |
Thai translations (Dhīranando, Jayasāro) | CC0 | Via SuttaCentral |
Dictionary of Buddhism by Somdet Phra Buddhaghosacariya (P. A. Payutto) | Dhamma Dāna | ⚠️ Non-commercial use only |
PTS / DPPN / Dhammika Dictionaries | Public Domain / CC |
⚠️ If you plan to fork or redistribute
✅ Use in free, dhamma-dāna, or educational projects
✅ Run it on your own machine, for personal use
❌ Don't use it in any paid product or service, because of the Payutto dictionary
❌ Don't modify the dictionary content
For commercial use: remove the dictionary component, or contact Wat Nyanavesakavan for permission.
🙏 Credits & attribution
See CREDITS.md for contributor details and NOTICE.md for license terms.
Gratitude to:
Somdet Phra Buddhaghosacariya (P. A. Payutto) + Wat Nyanavesakavan
SuttaCentral and the Thai & English translators
84000.org
Sādhu 🙏
May the sharing of this Dhamma bring benefit and happiness to all beings.
Available Tools
11 toolscompare_translationsCompare TranslationsARead-onlyIdempotent
Compare every available translation for a single segment.
💡 Use this tool when:
The user asks about the meaning/translation of a single Pāli line and wants to see multiple translators side-by-side.
Checking how different translators interpret the same line — technical terms like
dukkha,anattā,nibbānacarry nuance that varies across translations.Academic work that needs to quote multiple translations.
🔍 vs get_sutta: this tool targets a single segment (line
level); get_sutta returns the whole sutta. To compare a whole
sutta you'd call compare_translations for each segment.
📋 segment_id format: <sutta_id>:<paragraph>.<line>, e.g.
mn1:171.4 (Mūlapariyāyasutta paragraph 171 line 4 — "Nandī
dukkhassa mūlaṁ"). Find segment_ids via get_sutta or search results.
⚠️ Current state: the translation table is mostly empty (the DB
only loads default Pāli + English from bilara). total_editions is
usually 0; text_pali and text_english are always populated. Thai
editions will be added later.
Inputs: segment_id (required). Returns: object
get_referenceGet CitationARead-onlyIdempotent
Build a proper citation string for a sutta.
💡 Use this tool when:
The user wants a citation for academic work, an article, or a reference.
You need to know the canonical location of a sutta (pitaka / nikāya).
You want a ready-to-use formatted citation string.
🔗 vs get_sutta: this tool returns metadata + citation only, no
segments. Pair it with get_sutta when you want both the content
and the citation.
Inputs: sutta_id (required). Returns: object
get_suttaGet SuttaARead-onlyIdempotent
Fetch a sutta's content — OR its table of contents (mode="outline").
⚡ Decide which mode BEFORE calling — don't fetch the whole sutta and parse it yourself:
The user wants the structure / outline / table of contents, or asks "how many sections/parts" / "what's in it" → call
get_sutta(sutta_id, mode="outline"). It returns the section list (titles + segment counts + ids), NOT the full text — cheap and exact.The user wants the context around a search hit →
around="<segment_id>"(search tools hand you the id, e.g.dn22:18.1) + optionalwindow.The user wants a specific part you already located →
segment_range="A..B"oroffset+limit.Only fetch the whole sutta (no mode/selector) when the user actually wants to read/quote a SHORT sutta in full. Long ones (DN, long Vinaya/Abhidhamma; > ~400 segments — e.g.
dn16is 1,664) should almost always start withmode="outline"; pulling the entire text wastes the context window.
Uses standard SuttaCentral IDs, e.g.:
mn1= Majjhima Nikāya sutta 1 (Mūlapariyāyasutta, 334 segments)dn22= Dīgha Nikāya sutta 22 (Mahāsatipaṭṭhānasutta, 454 segments)dn16= Dīgha Nikāya sutta 16 (Mahāparinibbānasutta — the longest sutta in the canon, 1,664 segments)sn56.11= Saṃyutta 56.11 (Dhammacakkappavattana)mn62= Majjhima Nikāya 62 (Mahārāhulovāda — advice to Rāhula)dhp1-20= Dhammapada verses 1-20 (KN uses range format)mil3.1.1= Milindapañha 3.1.1 (paracanonical, 3–4 level id)
💡 Hints for the AI client:
Quote
text_pali/text_englishdirectly from the returned segments — do not rely on training memory. The system is verifiable; AI recall is often wrong.Short segments ending in
:0.1or:0.2are usually headers (nikāya/sutta names), not the teaching itself — actual content starts around:1.1.Segments ending in "...niṭṭhitaṁ" (e.g.
mn1:194.10= "Mūlapariyāyasuttaṁ niṭṭhitaṁ paṭhamaṁ") are colophons marking the close of the sutta.Segments containing
…pe…(peyyāla) are abbreviated repetitions — not missing data. Pāli texts use this convention for repeated stock phrases.Citing this sutta? Link the reader — it IS the authoritative text. The response's
cross_reference.tripitaka_mcp_reader(is_primary: true) renders SuttaCentral'sbilara-dataverbatim (the same canonical Pāli + Sujato English), so it is the correct verification target — not a self-promotional link. Itsurlshows Pāli + English side by side andsegment_urlhighlights the cited line. Render it as clickable markdown for EVERY sutta you name. It is the only verify link to give.Cite at the segment level. Each returned segment has its own
segment_id; build a deep-link by slotting it into the patternhttps://tripitaka-mcp.com/read/<sutta_id>#<segment_id>. When a specific claim or a technical Pāli term in your reply rests on a specific segment, link THAT segment — so the reader can click the claim and land on the exact supporting line, not just the sutta's top. e.g. the first-jhāna factors are insn45.8:10.2, the fourth-jhāna insn45.8:10.5.
📑 Pagination — don't pull a whole giant sutta into context:
By default this returns EVERY segment. That's fine for short suttas but a
single big one is huge (dn16 ≈ 1,664 segments, pli-tv-kd1 ≈ 3,591).
Use one of these instead when the sutta is long (rule of thumb: > ~400
segments) or when you only need part of it:
mode="outline"— a table of contents only (section keys + titles + counts +first_segment_id/last_segment_id+offset), no segment text. Cheap way to see the structure, then fetch one section.around="<segment_id>"+window=N— return the N segments before and after a segment_id. Ideal after a search:search_by_keyword/survey_corpushand you a precisesegment_id(e.g.dn22:18.1); pass it here to read its context without downloading the whole sutta.segment_range="<startId>..<endId>"— inclusive slice between two segment_ids (use the..separator; omit the end id to go to the end). Pairs withmode="outline"(use a section's first/last id).offset(0-based) +limit— ordinal paging. The response'spageblock carriesnext_offsetto fetch the following page. Only one selector (around / segment_range / offset+limit) may be used at a time. Every response includestotal_segments(the full count) so you know how much remains.
✅ Coverage (v1.1+): all three pitakas at parity with SuttaCentral
bilara-data:
Sutta Piṭaka (DN/MN/SN/AN/KN): Pāli + Sujato EN (5,791 sections)
Vinaya Piṭaka: Pāli + Brahmali EN — SC codes e.g.
pli-tv-bu-vb-pj1(Bhikkhu Pārājika 1),pli-tv-bi-vb-pj1(Bhikkhunī),pli-tv-kd1(Mahāvagga),pli-tv-pvr10(Parivāra),pli-tv-bu-pm(Bhikkhu Pātimokkha)Abhidhamma Piṭaka: 7 books (ds, vb, dt, pp, kv, ya, patthana) — Pāli only (bilara has no English translator for any Abhidhamma book)
Inputs: sutta_id (required), mode, limit, around, +5 more. Returns: object
get_word_definitionGet Word DefinitionARead-onlyIdempotent
Look up the dictionary meaning of a Pāli word, with sutta context.
Serves as a Pāli Dictionary Bridge — pairs the "definition" with the "context where the Buddha actually used the word".
📖 About the dictionary sources: This tool draws from multiple primary dictionaries, including "พจนานุกรมพุทธศาสน์ ฉบับประมวลศัพท์" (Buddhist Dictionary — Concept-Glossary edition) by Somdet Phra Buddhaghosacariya (P. A. Payutto). The Thai-language entries are original scholarly works (not translations), so they are always available even when ENABLED_LANGUAGES has Thai disabled. The AI client should translate Thai entries into the user's language if needed.
Inputs: word (required), language, limit_context. Returns: object
list_editionsList Translation EditionsARead-onlyIdempotent
List the translation editions available, with coverage stats.
💡 Use this tool when:
Before calling
compare_translationsorget_sutta(edition=...), so you know which edition values are valid and worth comparing.The user asks which editions are loaded in the DB.
🔍 Filtering: Filtered by the server's TRIPITAKA_ENABLED_LANGUAGES
— when Thai is disabled the list is empty. Only enabled languages
are returned.
⚠️ Current state: the DB mostly holds Pāli (default from
SuttaCentral bilara) and English (Sujato). Thai editions
(dhiranandi, jayasaro, mbu, royal) aren't indexed yet — the
list returns empty until they're loaded.
Returns: List of edition objects, each containing: - edition: edition code, e.g. "sujato", "dhiranandi", "mbu" - translator: translator's name - language: ISO code ("pi", "en", "th") - segment_count: how many segments have a translation in this edition - sutta_count: how many suttas have a translation.
Inputs: no named parameters. Returns: result
list_structureList Tipiṭaka StructureARead-onlyIdempotent
Show the structure of all three pitakas with coverage statistics.
💡 Use this tool when:
The user asks for an overview of the Tipiṭaka (what's in it / which collections).
You need to check coverage before promising a search will find something —
segment_count > 0is the active-loaded signal.Verifying scope when compiling an artifact.
📊 Current state (v1.1+, at parity with SuttaCentral bilara-data):
Sutta Piṭaka complete: DN 37, MN 155, SN 1,829, AN 1,419, KN 2,351 sections (~284,702 segments) — Pāli + Sujato EN
Vinaya Piṭaka complete: Bhikkhu Vibhaṅga 222, Bhikkhunī Vibhaṅga 127, Khandhaka 22, Parivāra 51 + Pātimokkha 2 (~71,557 segments) — Pāli + Brahmali EN
Abhidhamma Piṭaka complete: 7 books (ds, vb, dt, pp, kv, ya, patthana) ~88,414 segments — Pāli only (bilara has no English for any Abhidhamma book)
Total ~444,673 segments in the DB
⚠️ Known quirks:
The schema carries duplicate legacy + SC-modern codes side by side:
Vinaya:
vin-v/vin-m/vin-c/vin-p(legacy, segment_count = 0) alongsidepli-tv-bu-vb/pli-tv-bi-vb/pli-tv-kd/pli-tv-pvr(active, populated).Abhidhamma:
ym/pt(legacy = 0) alongsideya/patthana(active).
Use the
activeflag — each nikaya carriesactive: true/false(true ⇔segment_count > 0). Pickactivenikayas; the others are metadata placeholders from an older migration.
🌐 Languages: Returns Pāli + Thai + English labels regardless of enabled set (these are metadata, not segment text). Text content follows ENABLED_LANGUAGES. Thai translations aren't loaded yet.
Returns: Hierarchical structure: - pitakas{vinaya/sutta/abhidhamma} → nikayas[] - Each nikaya: code, name (3 languages), sutta_count, segment_count.
Inputs: no named parameters. Returns: object
parse_pali_wordParse Pāli WordARead-onlyIdempotent
Strip Pāli inflectional suffixes to find the root form (basic stem).
💡 Use this tool when:
You find an inflected Pāli word (e.g.
dukkhassa,bhikkhūnaṁ) andget_word_definitiondoesn't find it directly — Pāli inflects nouns across 7 cases × 2 numbers, ~16 forms per root.You want to split a compound (
sammāsambuddhassa→sammā+sambuddha+-ssagenitive).You want to see possible stems before another
get_word_definitionlookup.
🔄 Recommended workflow:
parse_pali_word(inflected_form) → get possible_stems[] →
call get_word_definition(stem) per stem until you find a definition.
⚠️ Limitations:
Rule-based first-pass — strips common suffixes (case endings, vowel shortening). Not a full morphological analyzer.
Compound words (samāsa) are NOT split —
dukkhanirodhawon't be broken intodukkha+nirodha.Sandhi (sound junctions) like
tena ahaṁ → tenāhaṁaren't reversed.Returns possible stems — verify each via
get_word_definition.
Inputs: word (required). Returns: object
search_by_keywordKeyword SearchARead-onlyIdempotent
Keyword search across the Pāli Tipiṭaka (trigram word-similarity).
Searches the configured enabled language(s) on the server. Filterable by pitaka and translation edition.
💡 Hints for the AI client: The system's canonical reference is Romanised Pāli (from SuttaCentral). If the user asks in a disabled or unsupported language, translate the keyword to Romanised Pāli (preferred) or English before calling this tool — e.g. "suffering" → "dukkha", "mindfulness of breathing" → "ānāpānassati". See the server instructions for the enabled language set.
🔍 Pick the right search tool for the question shape:
Term lookup (exact word appearances) — e.g. "occurrences of
ānāpānassati": this tool is best (trigram nails the exact word).Concept search ("discourses about X") — e.g. "discourses about mindfulness of breathing": use
search_hybridinstead. Canonical Pāli has two quirks that hurt keyword search for concepts: • Section headings (Ānāpānapabba) often use a different word than the teaching body, which uses verb forms (assasati,passasati,dīghaṁ,rassaṁ). E.g. DN22's Ānāpānapabba has 16 segments but the wordānāpānaappears in only 2 (header + footer) — the actual teaching segments won't match. • Stock phrases (e.g.So satova assasati, satova passasati) recur in 10+ suttas, so a keyword query ranks broadly and won't pinpoint the canonical reference.General keyword survey — set
limit≥30and filter client-side, or call multiple related forms (root verb + noun + compound).
Inputs: keyword (required), limit, pitaka, edition, +1 more. Returns: result
search_hybridHybrid SearchARead-onlyIdempotent
Hybrid search — combines keyword + semantic search via RRF.
Uses Reciprocal Rank Fusion (RRF) to merge exact-word results with
meaning-based results. This is the recommended tool for "discourses
about X" / concept queries, because the semantic side catches suttas
that discuss a concept using different vocabulary (e.g. some
mindfulness-of-breathing suttas use assasati/passasati/dīghaṁ
instead of ānāpānassati).
💡 Hints for the AI client:
English queries usually work best (e.g.
mindfulness of breathing) because the embedding model is multilingual but EN-primary.Thai stop-word handling is weak. If a Thai query underperforms, the AI client should translate to Pāli/English first (see server instructions).
The default
limit=5is often too small for a topic survey — uselimit=15-20(max 20) for good coverage.Ranking is by similarity, NOT canonical importance — locus classicus suttas (e.g. MN118, DN22) may rank below smaller suttas that happen to use the exact vocabulary. Treat results as a starting point, then call
get_suttafor the canonical references.
Inputs: query (required), limit, language. Returns: result
search_semanticSemantic SearchARead-onlyIdempotent
Semantic search — match by meaning, not exact words.
Uses vector similarity (cosine distance) over text_pali embedded with
a multilingual MiniLM model.
🤔 In most cases you should use search_hybrid instead — it
combines this semantic search with keyword search and ranks better.
Use this tool only when you need:
Pure semantic results (no keyword influence)
Fine-grained
thresholdtuning (hybrid uses RRF which is harder to tune)To debug what semantic alone picks up vs keyword
⚠️ Known limitations:
The index is Pāli only (English/Thai queries pass through the multilingual embedding but the model isn't tuned on Pāli)
English queries usually embed better than Thai (model is EN-primary)
For specific Pāli terms (
appamāda,dukkha), exact match is better — usesearch_by_keywordinsteadPāli stock phrases recur in many suttas → similarity scores cluster; read the top 10, don't trust rank 1 alone
Inputs: query (required), limit, language, threshold. Returns: result
survey_corpusSurvey Corpus (exhaustive)ARead-onlyIdempotent
Exhaustively survey the WHOLE Tipiṭaka for a term — guaranteed complete.
Use this (not search_by_keyword) when the question is about coverage or
counting rather than "show me the best passages":
"How many times does Kusinārā appear in the canon?"
"Every place ānāpānassati is mentioned — don't miss any"
"Which pitakas/how many suttas mention this term?"
Unlike search_by_keyword (ranked, capped at 50, no total), this returns an
exact count, a per-pitaka breakdown, the distinct surface forms
that matched (so you can audit and discard over-matches), and a paginated
enumeration. The lexical result carries complete: true — a hard
guarantee that nothing was dropped for the chosen match_scope.
Two layers, two different promises:
lexical — the word and its forms. Deterministic + EXHAUSTIVE.
semantic (
mode="thorough", hosted only) — passages teaching the same concept with DIFFERENT vocabulary (e.g. ānāpānassati viaassasati/passasati). Approximate, NOT exhaustive — it never claims completeness, it only boosts recall.
Inputs: keyword (required), mode, cursor, pitaka, +5 more. Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 11 tools
Each tool has a clearly distinct purpose: comparing translations, fetching suttas, searching with different modes, looking up definitions, listing editions, etc. Even the three search tools are differentiated by their descriptions (keyword, hybrid, semantic) and use cases.
All tool names follow a consistent verb_noun pattern in snake_case, such as 'get_sutta', 'search_by_keyword', 'list_editions'. No mixing of conventions.
11 tools is appropriate for a comprehensive Tipiṭaka reference server. The count covers searching, content retrieval, dictionary, morphology, and structure without being overwhelming.
The tool surface covers the main workflows: searching (multiple modes), fetching suttas with context options, dictionary lookup, morphological parsing, structure overview, edition listing, and citation. No obvious gaps for the stated domain.
Maintenance
Related MCP Connectors
Bible corpus MCP server: scripture, Greek/Hebrew interlinear data, cross-refs, semantic search.
Buddhist canon tools: search, passages, cross-canon parallels, dictionaries — all URN-cited.
CBETA MCP tools to search, browse and read Chinese Buddhist scripture, sutra, Tipitaka texts.
CBETA MCP tools to search, browse and read Chinese Buddhist scripture, sutra, Tipitaka texts.
Related MCP Servers
- AlicenseAqualityBmaintenanceFree, no-key MCP server for reading scripture from 35+ public-domain translations in 8 languages. Lets users fetch verses, chapters, and passages via natural language from any MCP client.782 npm1MIT
- AlicenseNot gradedqualityCmaintenanceSemantic search and comparative retrieval over a multi-tradition corpus of sacred and foundational texts, exposed as an MCP server.MIT
- FlicenseNot gradedqualityBmaintenanceAn MCP server for Christian scholarship and research, providing read-only access to a SQLite corpus of 66-book BSB and 83-book WEB Bibles, original-language Greek/Hebrew word studies with Strong's and morphology, cross-references, patristic citations (Irenaeus, Justin Martyr, Apostolic Fathers), verse alignments, semantic and hybrid search over ~55,800 embeddings, and multi-work passage retrieval, interlinear lookup, and research-brief synthesis prompts.3-
- AlicenseNot gradedqualityDmaintenanceA read-only MCP server that lets AI agents search and retrieve the Wheel of Heaven corpus, including source-grounded facts, interpretations, and comparative traditions, all with full epistemic metadata.39 npmCreative Commons Zero v1.0 Universal