Skip to main content
Glama
grusingh

gurbani-mcp

by grusingh

gurbani-mcp

A local, self-hosted tool for looking up and verifying that a quote is authentically from Sri Guru Granth Sahib (SGGS). This project covers SGGS only (not other Banis).

It runs entirely on your own machine. No data leaves your computer unless you choose to expose it to an AI client (Claude, ChatGPT, etc.), and even then, only the query text you send is transmitted — never the underlying database.

  • Search — keyword search with Gurbani concept expansion (e.g. "sewa" also matches "service", "selfless service")

  • Verify — check a Gurmukhi quote against SGGS; get back the verbatim text + citation (Ang, Shabad, author), or a clear "not found"

  • Guard — scan a block of text for every Gurmukhi quote in it and verify each one individually

  • Two ways to connect an AI client: an MCP server (Claude Desktop, Claude Code, Cursor) and a plain HTTP API (ChatGPT via Custom GPT Actions, or any REST client)

Gurbani text is only ever returned from the source database — never paraphrased, summarized, or generated. See Quote Verification below.


Quick start

Prerequisites:

Tool

Why

Install

Docker (or Colima on macOS)

one-time database build

brew install colima docker && colima start --cpu 4 --memory 8

uv

run the Python servers

curl -LsSf https://astral.sh/uv/install.sh | sh

git clone <this-repo-url> gurbani-mcp
cd gurbani-mcp
bash scripts/setup.sh

setup.sh builds database/dist/banidb.sqlite from the official Khalis Foundation BaniDB Docker image (the dataset behind SikhiToTheMax), then installs Python dependencies. It takes several minutes the first time (downloading + seeding a ~640MB dataset); nothing about your database is uploaded anywhere.

Verify it worked:

bash scripts/test_search.sh "benefits of sewa"
uv run --extra dev pytest

Related MCP server: anna-book-search

Connect to an AI client

Claude Desktop / Claude Code (MCP)

Add this to your Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json on macOS, %APPDATA%\Claude\claude_desktop_config.json on Windows):

{
  "mcpServers": {
    "gurbani": {
      "command": "uv",
      "args": ["run", "--directory", "/absolute/path/to/gurbani-mcp", "python", "-m", "mcp_server.server"]
    }
  }
}

Restart Claude Desktop. You should see a 🔨 tools icon indicating the gurbani server is connected, exposing search_gurbani, verify_quote, guard_text, get_shabad_by_ang, get_line, and get_shabad_by_line.

For Claude Code, add the same server with:

claude mcp add gurbani -- uv run --directory /absolute/path/to/gurbani-mcp python -m mcp_server.server

ChatGPT (Custom GPT Actions, via the HTTP API)

  1. Start the HTTP API:

    uv run uvicorn api_server.app:app --port 8421
  2. ChatGPT Actions need a public HTTPS URL — they can't reach localhost. The fastest way to get one without an account is a Cloudflare quick tunnel:

    cloudflared tunnel --url http://localhost:8421

    This prints a temporary https://<random>.trycloudflare.com URL. Treat it as sensitive while it's live — anyone with the URL can query your local API. It's meant for short sessions; for anything longer-lived, put an API key or auth layer in front of it first (not included here — see Follow-ups).

  3. In ChatGPT: Explore GPTs → Create → Configure → Actions → Import from URL, and paste https://<random>.trycloudflare.com/openapi.json. ChatGPT will pick up all the endpoints (/api/search, /api/verify, /api/guard, etc.) automatically.

  4. Give the GPT instructions like: "When asked to verify a Gurbani quote, always call the verify or guard action and quote its source_text back verbatim — never answer from your own memory."


Example: verifying every quote in a document

curl -s "http://localhost:8421/api/guard" --get \
  --data-urlencode "q=$(cat my_document.txt)" | jq

Returns every Gurmukhi span found in the text, each marked verified, verified_fuzzy (found, but with minor punctuation/spelling differences), or not_found — with the exact source citation (Ang, author, full line) for anything that verified.


Quote verification — how authenticity is guaranteed

Four layers, all sharing one matching core in gurbani_rag/verify.py:

  1. Build gate (scripts/validate_db.py) — structural checks (row counts, Ang coverage, no gaps/duplicates) run automatically during setup.sh, so an incomplete or corrupted database can never reach runtime.

  2. Retrieval — every search result comes straight from the source database with its citation attached. Authentic by construction.

  3. Verify (verify_quote) — exact match first (punctuation-agnostic), then fuzzy match via FTS5 + rapidfuzz with a 0.90 confidence floor. Below that: not_found. The text returned is always the source's own — never your input echoed back.

  4. Guard (guard_text) — scans arbitrary text for every Gurmukhi span and verifies each one independently. This is the tool for auditing any drafted or existing content.

See CLAUDE.md for the full architecture and schema.


The default search is keyword + concept expansion (works well, no extra setup). An optional ChromaDB-based semantic index can also be built:

uv run python scripts/build_index.py

Running tests

uv run --extra dev pytest

tests/test_golden.py checks known-authentic quotes verify at their correct Ang, and known fakes are correctly rejected.

Data attribution

Scripture text, translations, and transliterations: Khalis Foundation BaniDB (SikhiToTheMax dataset).

BaniDB's compiled/proprietary form is not redistributed by this repo — database/dist/banidb.sqlite is always built locally from the official BaniDB Docker image (see scripts/setup.sh).

Follow-ups (not built yet)

  • The HTTP API has no authentication — fine for a short-lived tunnel session, not for leaving it exposed long-term.

  • No CI workflow yet.

License

MIT — see LICENSE.

Available Tools

6 tools
get_lineA

Fetch a specific line from the SGGS by its BaniDB verse ID (an integer, as returned by search_gurbani).

ParametersJSON Schema
NameRequiredDescriptionDefault
line_idYesBaniDB verse ID (e.g. 3)

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden. It clearly indicates a read operation ('Fetch') but does not disclose what the response contains (e.g., line text, metadata), error behavior for invalid IDs, or any other side effects. This is a moderate gap given the simplicity of the tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, well-structured sentence with no redundancy. It front-loads the action ('Fetch a specific line') and packs essential context (the ID source) without wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple tool with one parameter and no output schema, the description is nearly complete: it explains what it does and where the ID comes from. However, it doesn't specify the return format, which could be inferred but is not explicit. Given the low complexity, this is adequate but not perfect.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already provides a description for line_id, giving 100% coverage. The description adds value by clarifying that the ID is 'as returned by search_gurbani', establishing provenance and expected format beyond the schema's 'BaniDB verse ID (e.g. 3)'.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses the specific verb 'Fetch' with a clear resource ('a specific line from the SGGS') and identifies the unique identifier ('BaniDB verse ID'), distinguishing it from siblings like get_shabad_by_ang or get_shabad_by_line. It also references search_gurbani as the source of the ID, adding precision.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the tool should be used when you have a verse ID returned by search_gurbani, providing clear context for its use. However, it does not explicitly mention when to use alternatives (e.g., fetch by Ang or line number), so it stops short of full exclusionary guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_shabad_by_angA

Fetch all lines on a given Ang (page number) of the SGGS. Ang range: 1–1430.

ParametersJSON Schema
NameRequiredDescriptionDefault
angYesAng (page) number, 1–1430

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Since no annotations are provided, the description carries the full burden. It communicates that the operation is a read ('Fetch') and defines the scope ('all lines') plus the valid Ang range. It does not mention error handling, ordering, or return format, but for a simple read-only tool, this is adequate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence that states the action and resource immediately, followed by the range constraint. There is no unnecessary detail; every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter read tool with no output schema, the description is largely complete: it defines the purpose, input scope, and implied output. It lacks explicit discussion of edge cases or alternatives, but the simplicity of the tool makes this acceptable.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema covers the 'ang' parameter completely with its description 'Ang (page) number, 1–1430'. The description adds the meaning of fetching 'all lines' on that page, which slightly enriches the parameter context, but since schema coverage is 100%, the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses the specific verb 'Fetch' and clearly identifies the resource: 'all lines on a given Ang (page number) of the SGGS'. This distinguishes it from siblings like get_line (single line) and get_shabad_by_line (fetch by line number), making the tool's scope unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context by stating that the tool fetches all lines for a page, and it constrains the input range (1–1430). However, it does not explicitly mention when to prefer this tool over alternatives or state exclusions, so it lacks explicit when/when-not guidance but is still inferable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_shabad_by_lineA

Given any line ID from the SGGS, return the complete Shabad (hymn) it belongs to — all lines in order, with Gurmukhi text, English transliteration, translation, and Ang reference. Use this after search_gurbani to expand a matching line into its full hymn context.

ParametersJSON Schema
NameRequiredDescriptionDefault
line_idYesAny BaniDB verse ID from the Shabad you want

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden. It discloses that it returns all lines in order, with Gurmukhi, transliteration, translation, and Ang reference, which is the key behavioral output. It also implies it is a read-only operation by using 'return', and provides workflow context. It does not cover edge cases or errors, but for a simple read tool this is adequate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with the core action and return details, and ends with a clear usage directive. Every word earns its place; no redundancy or fluff.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter, no-output-schema tool, the description covers all necessary context: input (line ID), action (return full Shabad), output structure (all lines, fields), and usage scenario (after search_gurbani). It is complete for an agent to select and invoke correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already provides 100% coverage, describing line_id as 'Any BaniDB verse ID from the Shabad you want'. The tool description's 'Given any line ID from the SGGS' adds no new meaning beyond the schema. Baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool 'return the complete Shabad (hymn)' given a line ID, listing the output fields. It distinguishes itself from siblings by specifying it expands a single line into the full hymn, explicitly pointing to search_gurbani as the preceding step. This is a specific verb+resource+scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says 'Use this after search_gurbani', giving a clear when-to-use context. It does not mention when-not-to-use or alternatives, but the workflow guidance is unambiguous enough for this lookup tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

guard_textA

Audit a block of prose: find every Gurmukhi span in it and verify each against the source scripture. Use to check a drafted answer (or existing content) before presenting it. Returns each span's verdict (verified / not found) with citations.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYesProse possibly containing Gurmukhi quotes

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral disclosure burden. It transparently explains that the tool verifies each Gurmukhi span and returns a verdict (verified / not found) with citations, making the primary behavior clear. It does not explicitly state read-only behavior or edge cases, but these are reasonably inferred from 'audit' and 'returns'.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences, front-loaded with the core action, followed by a usage note and expected output. Every sentence serves a distinct purpose—what it does, when to use it, and what it returns—with no wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the simplicity (one parameter, no output schema), the description is complete: it states the operation, usage context, and return format. It provides enough information for an agent to select and invoke the tool correctly without additional clarification.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema description covers 100% of the single parameter with a clear description ('Prose possibly containing Gurmukhi quotes'). The tool description adds context by referring to 'block of prose' and 'every Gurmukhi span' but does not significantly enrich the parameter semantics beyond what the schema already provides. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool audits a block of prose, identifying and verifying Gurmukhi spans against scripture. The verb 'audit' and resource are specific, and the scope ('every Gurmukhi span') implies a batch operation, which distinguishes it from sibling tools like verify_quote without naming them explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage guidance is explicit: 'Use to check a drafted answer (or existing content) before presenting it.' This provides a clear context for when to invoke the tool. However, it does not mention alternatives or when not to use it, leaving some room for clarification.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_gurbaniA

Search Sri Guru Granth Sahib (SGGS) by concept or keyword. Query in plain English — e.g. 'get rid of ego', 'love for God', 'fear of death'. Searches the English translations and returns matching lines with Gurmukhi text, English transliteration, translation, author, and Ang (page) reference.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYesSearch query
n_resultsNoNumber of results

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It discloses that the search targets English translations and returns lines with Gurmukhi text, transliteration, translation, author, and Ang reference. This provides useful behavioral context, though it does not mention potential limitations or edge cases.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences: the first states the core purpose with a verb and resource, the second provides examples and return fields. Every sentence contributes essential information without redundancy or padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple search tool with no output schema, the description sufficiently outlines what the tool does and what it returns. It lacks explicit details on result ordering or pagination, but these are minor gaps given the tool's simplicity and the clarity of its return fields.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds value by giving concrete example queries ('get rid of ego', 'love for God'), which helps the agent formulate valid and effective queries beyond the schema's simple 'Search query' description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool searches Sri Guru Granth Sahib by concept or keyword, with specific examples. It distinguishes itself from sibling tools that are focused on specific lookups (by Ang, line, etc.), making its purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use this tool (for searching by concept/keyword) and provides examples that clarify the intended use cases. It does not explicitly name alternatives or exclusions, but the context from sibling tool names reinforces the differentiation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

verify_quoteA

Check whether a Gurmukhi quote is authentically present in the source scripture. ALWAYS call this before presenting any Gurmukhi quote that did not come directly from another tool's result (e.g. a quote recalled from memory). Returns the verbatim source text + citation (Ang, author) if found, or NOT FOUND — in which case the quote must not be presented as authentic. Tolerates vishraam/punctuation/spelling differences; the returned text is always the source's own.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYesGurmukhi quote to verify

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description fully carries the burden of behavioral disclosure. It specifies return values (verbatim source text + citation, or NOT FOUND), tolerance for vishraam/punctuation/spelling differences, and guarantees that returned text is always the source's own. This is unusually transparent for a simple verification tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three focused sentences deliver all necessary information without redundancy. The most critical instruction is front-loaded ('ALWAYS call this'), and every sentence contributes a distinct, valuable point.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's low complexity (one parameter, no output schema, no annotations), the description is complete. It covers purpose, unambiguous usage guidance, return behavior, tolerances, and a post-condition for NOT FOUND, making it fully self-contained for an AI agent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so baseline is 3. The description adds meaningful semantics by clarifying the input is a quote under authenticity review and that spelling/vishraam/punctuation differences are tolerated. It stops short of 5 because it provides no additional format or encoding requirements beyond 'Gurmukhi quote'.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: checking whether a Gurmukhi quote is authentically present in the source scripture. It uses a specific verb ('verify') and resource, and is easily distinguished from sibling tools like search_gurbani or get_line, which retrieve rather than authenticate.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides an explicit and prominent instruction: ALWAYS call before presenting any Gurmukhi quote not directly from another tool's result. This clearly defines when to use the tool, and the NOT FOUND consequence prevents misuse of unverified quotes.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 6 tool updatesv0.1.0
    • First observedget_line
    • First observedget_shabad_by_ang
    • First observedget_shabad_by_line
    • First observedguard_text
    • First observedsearch_gurbani
    • First observedverify_quote

TDQS

A4.4/5.0

Scored across 6 tools

Disambiguation5/5

Each tool serves a clearly distinct purpose: search, retrieval by Ang or line, expanding to full Shabad, and two levels of quote verification (single quote vs. full text audit). No two tools appear to do the same thing.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern with snake_case: search_, get_, verify_, guard_. The naming style is uniform and predictable.

Tool Count5/5

Six tools is well-scoped for a scripture server covering search, retrieval, and verification. Each tool earns its place with no redundancy.

Completeness5/5

The domain is covered end-to-end: search to find lines, retrieve by page or line, expand to full shabad, and verify quotes with the source. No obvious gaps for the stated purpose.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    An MCP server that provides powerful search capabilities for Jewish texts and literature. This server enables Large Language Models to search and reference Jewish texts through a standardized interface.
    23
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Self-hosted MCP server for searching and discovering books using Anna's Archive and Goodreads datasets, enabling full-text search, ISBN/md5 lookup, similarity matching, and optional download URL retrieval.
    3 npm
    2
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    MCP server to search and retrieve passages from a corpus of 7,872 classical Islamic books via the Sahifah API, with full citations and mu'tabar filtering.
    6 npm
    MIT