Skip to main content
Glama
smridhiwho

open-india-law-mcp

by smridhiwho

open-india-law-mcp

An MCP server that gives any MCP-compatible AI agent (Claude, Claude Code, Claude Desktop, or any other MCP client) structured, correctly-attributed access to Vaquill AI's Open India Law dataset:

  • 12.8M+ court judgments (Supreme Court + all 25 High Courts)

  • 813K+ tribunal/regulator matters

  • 1.1M+ legislation provisions (Central + every State/UT), section by section

It does not download the dataset. Court judgment files alone run to tens of GB per court, and the full corpus is ~53.6 GB of judgment text plus 463.6 GB of vector embeddings. Instead it uses DuckDB's hf:// support to run filtered SQL directly against the parquet files on the Hugging Face Hub, pulling only the row groups and columns a query actually needs.

Why this design ("accessing it rightly")

  • No hardcoded file list. The dataset can add or rename files between snapshots, so list_catalog asks the HF Hub what actually exists right now and categorizes it, instead of shipping a guess that goes stale.

  • No guessed schema for judgments. The README documents exact fields for legislation and tribunal records, but not for plain court judgments. search_judgments / get_judgment introspect the real schema at call time (get_schema) and pick the right columns, rather than assuming field names that might not exist.

  • CC BY 4.0 is honored automatically. Every tool response carries an attribution field (credit to Vaquill AI / Open India Law, CC BY 4.0) and a caveat field (point-in-time snapshot, not legal advice, verify against source_url/source_pdf_url). An agent doesn't have to remember the license terms — they travel with the data.

  • Scale-aware by construction. search_judgments requires a court (scanning all 26 courts in one call isn't something a single query should silently attempt), and every query tool caps results at 200 rows. The generic run_sql tool refuses anything that isn't a single read-only SELECT/WITH.

Related MCP server: pk-eli-mcp

Install

Requires Python 3.10+.

git clone <this-repo>  
cd open-india-law-mcp
pip install -e .

This pulls in mcp, duckdb, and huggingface_hub. The dataset is public, so no Hugging Face token is required — but if you hit HF rate limits, set HF_TOKEN in your environment and the server will use it.

Run it — 3 ways

Before any of these: run python smoke_test.py once. It hits the real Hugging Face API and DuckDB extension CDN and confirms the whole path works — nothing in this repo could be verified against live data during development (the build sandbox blocks both hosts), so this is the first real test.

1. As an MCP server (what Claude Desktop/Code actually run)

open-india-law-mcp
# equivalent: python -m open_india_law_mcp.server

This starts the stdio MCP server and blocks, waiting for a client to connect over stdin/stdout. You won't see output — that's normal; connect a client (below) rather than running it bare in a terminal to "test" it.

2. Directly from Python — no MCP protocol at all

@mcp.tool() registers a function with the server but returns it unchanged, so every tool is just a plain importable Python function. Skip the protocol entirely for a script, notebook, or test:

from open_india_law_mcp import server

catalog = server.list_catalog()
hits = server.search_legislation(query="arbitration", state="central", limit=5)
act = server.get_act(act_id="IND_central_1996_26")

Full runnable version: examples/direct_python.py.

3. As a real MCP client, in code

To drive it exactly the way Claude Desktop/Code do internally (spawn as a subprocess, speak MCP over stdio) — useful for testing, or as a template for a non-Claude agent:

import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client

params = StdioServerParameters(command="open-india-law-mcp")

async def main():
    async with stdio_client(params) as (read, write):
        async with ClientSession(read, write) as session:
            await session.initialize()
            result = await session.call_tool("list_catalog", {})
            print(result.content[0].text)

asyncio.run(main())

Full runnable version: examples/mcp_client.py.

Connecting real MCP clients

Claude Code (CLI)

claude mcp add open-india-law -- open-india-law-mcp

Or, if it's not on your PATH:

claude mcp add open-india-law -- python -m open_india_law_mcp.server

Check it registered: claude mcp list. Remove it: claude mcp remove open-india-law.

Claude Desktop

Edit your config file directly — ~/Library/Application Support/Claude/claude_desktop_config.json on macOS, %APPDATA%\Claude\claude_desktop_config.json on Windows:

{
  "mcpServers": {
    "open-india-law": {
      "command": "open-india-law-mcp"
    }
  }
}

If you installed into a virtualenv rather than globally, either use that venv's full path for command (/path/to/venv/bin/open-india-law-mcp), or:

{
  "mcpServers": {
    "open-india-law": {
      "command": "python",
      "args": ["-m", "open_india_law_mcp.server"],
      "cwd": "/path/to/open-india-law-mcp"
    }
  }
}

Restart Claude Desktop after editing the config.

MCP Inspector (interactive debugging, no client needed)

npx @modelcontextprotocol/inspector open-india-law-mcp

Opens a browser UI where you can call each tool by hand and see the raw JSON — the fastest way to poke at this without writing any code.

Any other MCP client

This is a standard stdio server; point any MCP-compatible client at the open-india-law-mcp command the same way you would point it at any other.

Tools

Tool

What it does

list_catalog(refresh=False)

Lists every court/regulator/state file that currently exists, with its hf:// URI. Call this first.

get_schema(file_uri)

Real column names + types for a file, from list_catalog.

run_sql(sql, limit=20)

Read-only DuckDB SQL against any file(s) from the catalog. Full flexibility, capped at 200 rows.

search_legislation(query, state="central", act_id=None, in_force_only=True, limit=20)

Section-level search of one jurisdiction's Acts.

get_act(act_id, state=None)

Every section of one Act, in order. state is inferred from act_id if omitted.

search_regulations(body, query=None, in_force_only=True, limit=20)

Section-level search of one regulator's instruments (SEBI, RBI, ...).

search_judgments(query, court, year_from=None, year_to=None, limit=20)

Full-text search over one court's judgment chunks. court is required.

get_judgment(case_id, court)

Reassembles a full judgment from its chunks.

Plus a static resource, open-india-law://about, with the license and caveats in one place for clients that want to show it up front.

How DuckDB reads parquet straight off the Hugging Face Hub

Nothing here is server-specific — it's plain DuckDB, so you can reproduce any query from the duckdb CLI with zero Python:

duckdb -c "
INSTALL httpfs; LOAD httpfs;
SELECT act_id, section_number, section_title
FROM read_parquet('hf://datasets/vaquill/open-india-law/in_central_legislation.parquet')
WHERE text ILIKE '%arbitration%'
LIMIT 5;
"

The hf:// URI. DuckDB's httpfs extension recognizes hf://datasets/<repo>/<path> and resolves it to the Hub's actual CDN/resolve URL under the hood — you never see or construct that URL yourself. catalog.hf_uri() in this repo just builds the hf:// string; DuckDB does the resolution.

Why this doesn't download whole files. Parquet stores its schema and per-row-group statistics (min/max, null counts) in a footer at the end of the file. httpfs does an HTTP range request for that footer first, then — for each column/predicate in your query — issues further range requests only for the row groups whose stats can't rule them out. A WHERE year = 2023 on a 2 GB file might read a few MB. This is exactly what lets search_legislation/search_judgments filter multi-GB files in place instead of streaming them wholesale.

Free-text search doesn't get this for free. ILIKE '%arbitration%' has no column statistic that can prove a row group doesn't contain the word — DuckDB has to actually read every row group it can't rule out by some other predicate. That's why search_judgments requires a court (one file, not 26) and accepts year_from/year_to: the year filter prunes row groups first, and only the survivors get scanned for text.

Caching within a connection. duck.py enables enable_object_cache (keeps parsed parquet footers in memory) and enable_http_metadata_cache (keeps ETag/size lookups in memory) on every connection it creates. Since each worker thread reuses one long-lived connection, calling get_schema then search_legislation against the same file only fetches that footer once. There's no cross-process or on-disk cache — a fresh server process starts cold.

Authentication. The dataset is public, so no token is required. If you hit Hub rate limits, set HF_TOKEN in the environment the server runs in — duck.py picks it up and registers it as a DuckDB secret (CREATE SECRET hf_token (TYPE HUGGINGFACE, TOKEN ...)) automatically.

Discovery vs. querying are two different Hub calls. list_catalog uses huggingface_hub.HfApi.list_repo_files (a small metadata API call, cached for 15 minutes in catalog.py) to find out what files exist at all. Actually reading a file's contents is a separate, unrelated path — DuckDB's own HTTP client via httpfs, not huggingface_hub. The Python package huggingface_hub is only ever used for that one discovery call.

Performance notes

  • Narrow before you search: pick one court/state/regulator file, and add a year range when the tool supports it. That's the difference between a sub-second query and one that has to scan a large fraction of a multi-GB file.

  • Tribunal decisions (CAT, ITAT, NCLT, ...) are ~2.1M scanned PDFs with no text layer per the source dataset — they aren't in the judgment parquet files and this server doesn't attempt OCR. Use list_catalog / run_sql against whatever tribunal metadata files do exist in the repo.

License

This server's code: MIT (add your own LICENSE file if you want one). The data it queries is CC BY 4.0 — see attribution.py and the attribution/caveat fields returned by every tool. The underlying legal text is Government of India material reproduced under s.52(1)(q) of the Copyright Act 1957. None of this is legal advice.

Available Tools

8 tools
get_actA

Fetch every section of one Act, in section order.

state is optional -- it's inferred from the act_id itself when omitted (e.g. "IND_west_bengal_1947_12" implies state="west_bengal"). Pass it explicitly if that inference is wrong.

ParametersJSON Schema
NameRequiredDescriptionDefault
stateNo
act_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

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 behavioral burden. It discloses the non-obvious state inference behavior, gives a concrete example, and explains when to override it. It could add more about pagination or errors, but the core behavior is clear and consistent.

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 short and front-loaded with the core purpose. Every sentence earns its place: the first gives the action, and the second paragraph clarifies an important optional parameter behavior without filler.

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 two-parameter fetch with an output schema, the description covers what the tool returns, the ordering, and the state inference rule. It does not explicitly point to search_legislation for broader search use cases, but that is a minor gap given the get-by-id nature of the tool.

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 0%, so the description must compensate. It does well for state, explaining that it is optional, inferred from act_id, and overridable. The required act_id is only illustrated via example rather than formally described, but the example makes its structure sufficiently inferable.

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 opens with a specific verb and resource: 'Fetch every section of one Act, in section order.' It clearly names the scope (every section), the resource (one Act), and the ordering, and it is readily distinguishable from sibling search tools like search_legislation.

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 first sentence gives clear context: use this when you need all sections of a specific Act in order. It does not explicitly name alternatives or state when not to use this tool, so it stops short of full routing guidance.

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

get_judgmentB

Reassemble a full judgment from its chunks, ordered by chunk index.

ParametersJSON Schema
NameRequiredDescriptionDefault
courtYes
case_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.3/5.0
Behavior3/5

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

With no annotations, the description carries the disclosure burden and does add one behavioral detail: the judgment is assembled from chunks in chunk-index order. It does not mention error behavior, what happens if chunks are missing, or any access constraints, so transparency is partial.

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?

A single sentence with no filler, front-loaded with the action, and all words earn their place. It is an appropriate length for such a simple tool.

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

Completeness2/5

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

Although an output schema exists, the definition lacks parameter semantics, usage guidance, and clarification of what 'chunks' means. An agent may infer the call shape from names, but it is not fully equipped to invoke the tool correctly in ambiguous cases.

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

Parameters1/5

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

Schema description coverage is 0%, and the description does not compensate by explaining how case_id or court are used. The property names are self-explanatory at a basic level, but the description adds no parameter-specific meaning beyond the schema.

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 a specific verb ('Reassemble') and a clear resource ('full judgment'), and explains the mechanism of ordering by chunk index. This is distinct from siblings like search_judgments (searching) and get_act (acts).

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

Usage Guidelines3/5

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

It implies use when a complete judgment text is needed, but it does not state when to prefer search_judgments or other alternatives, nor give explicit exclusions or prerequisites. The usage context is only inferable from the purpose statement.

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

get_schemaA

Return the real column names and types for a parquet file, given the hf:// URI you got from list_catalog. Use this before run_sql if you're not sure a field exists -- the plain court-judgment files don't have a schema documented anywhere.

ParametersJSON Schema
NameRequiredDescriptionDefault
file_uriYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior3/5

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

No annotations are provided, so the description carries the behavioral burden. It conveys read-only intent through 'Return' and adds useful context about undocumented schemas, but it does not mention error cases, authentication, or side effects. The core behavior is transparent enough for a schema lookup, but not richly detailed.

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?

Two sentences with no filler: the first sentence states the action and input source, the second provides usage guidance and context. Every clause earns its place and the key information is front-loaded.

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 required parameter, and the presence of an output schema, the description covers what the tool does, where the input comes from, when to use it, and why it may be needed. No critical missing information prevents correct invocation.

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 input schema only provides a string title for file_uri, and schema description coverage is 0%. The description compensates by explaining the parameter is an hf:// URI obtained from list_catalog and refers to a parquet file. It lacks an explicit example or format validation, but the single parameter's meaning is effectively conveyed.

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 states a specific verb and resource: 'Return the real column names and types for a parquet file.' It also clearly distinguishes itself from siblings by referencing the hf:// URI from list_catalog and being a schema-introspection step before run_sql.

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?

It explicitly says to use this before run_sql when unsure a field exists, and notes that plain court-judgment files lack documented schemas. It gives a concrete condition but does not detail exhaustive when-not-to-use scenarios or all alternative tools.

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

list_catalogA

List the parquet files that actually exist in the dataset right now, grouped into judgments (by court), regulations (by issuing body), and legislation (by jurisdiction). Call this first -- it's how you find the exact court/state/body names the other tools expect, and it hands back the hf:// URI for each file for use with run_sql.

Set refresh=True to bypass the 15-minute cache and re-check the repo.

ParametersJSON Schema
NameRequiredDescriptionDefault
refreshNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior4/5

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

With no annotations provided, the description carries the behavioral disclosure burden. It reveals useful behavior: the tool reflects the current state of the repo, groups results, returns file URIs, and caches results for 15 minutes with a refresh option. This goes well beyond a simple list operation, though it does not discuss failure modes or rate limits.

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 front-loaded with the core purpose, then explains why to call it first, and ends with the parameter behavior. Every sentence earns its place with no filler or redundancy.

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 one-parameter listing tool with an output schema, the description covers the discovery workflow, the returned URI format, grouping semantics, and caching behavior. An agent has everything needed to decide to call it and to understand what it will get back.

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 0%, so the description must add parameter meaning. It does: refresh=True bypasses the 15-minute cache and re-checks the repo. The default false value is provided by the schema, so the description meaningfully supplements the schema rather than repeating it.

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 lists parquet files that actually exist in the dataset, grouped into judgments, regulations, and legislation. It also distinguishes itself by framing it as the entry point for discovering names and URIs that other tools expect.

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?

It explicitly says 'Call this first' and explains the tool provides the exact court/state/body names and hf:// URIs needed by run_sql and sibling tools. It gives clear when-to-use context but does not enumerate when not to use it or compare against each sibling directly.

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

run_sqlA

Run a read-only SELECT against one or more Open India Law parquet files, referenced by the hf:// URIs from list_catalog, e.g.:

SELECT act_id, title, section_number, section_title
FROM read_parquet('hf://datasets/vaquill/open-india-law/in_central_legislation.parquet')
WHERE text ILIKE '%arbitration%' AND act_status = 'in_force'
ORDER BY year DESC

Only a single SELECT/WITH statement is allowed -- no DDL/DML, no multiple statements. limit is capped at 200 rows regardless of what the query asks for, since these files can be tens of GB and a filter still has to scan every row group it can't rule out via column stats. Narrow with a specific file (one court/state/regulator), a year range, and an indexed-looking equality filter (act_id, case_id) wherever you can -- it's the difference between a sub-second query and a slow scan.

ParametersJSON Schema
NameRequiredDescriptionDefault
sqlYes
limitNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior5/5

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

With no annotations provided, the description carries the full behavioral burden and delivers richly: read-only execution, 'only a single SELECT/WITH statement is allowed -- no DDL/DML, no multiple statements,' the hard 'limit is capped at 200 rows' stop, and the scan-cost rationale for tens-of-GB files. No contradiction with annotations exists since none are present.

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?

Though long, every sentence earns its place: purpose, a fully executable example, hard constraints, the row cap, and performance guidance. Each element of the example teaches a required convention (URI format, read_parquet invocation, filter patterns), so no portion is filler.

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?

The output schema covers return values, freeing the description to focus on behavior, and it covers everything else an agent needs: prerequisites (list_catalog URIs), structural constraints, the 200-row cap, and an optimization strategy for avoiding slow scans. Nothing needed for correct invocation is missing.

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

Parameters5/5

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

Schema description coverage is 0%, so the description must compensate for both bare parameters, and it does. It explains the required shape of `sql` (single SELECT/WITH, hf:// URI + read_parquet pattern, example query) and the `limit` cap behavior at 200 rows. This fully makes up for the schema's lack of descriptions.

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?

States a specific verb and resource immediately: 'Run a read-only SELECT against one or more Open India Law parquet files.' The concrete example with hf:// URIs and the reference to `list_catalog` make the scope unambiguous and distinguish it from the higher-level search_* siblings.

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?

Provides clear operational context: URIs come from list_catalog, and it advises narrowing 'with a specific file (one court/state/regulator), a year range, and an indexed-looking equality filter (act_id, case_id).' However, it never explicitly states when NOT to use this tool in favor of sibling search/get tools, so routing to alternatives is implied rather than exclusionary.

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

search_judgmentsA

Full-text search over one court's judgment chunks.

court is required and fuzzy-matched (e.g. "Bombay", "bombay high court") against list_catalog()['courts'] -- searching all 26 courts in one call would mean scanning tens of millions of chunks. Narrow further with year_from/year_to when you can; it prunes row groups instead of reading them.

Results are individual chunks, not whole judgments -- use get_judgment with the returned case_id to reassemble the full text of any hit.

ParametersJSON Schema
NameRequiredDescriptionDefault
courtYes
limitNo
queryYes
year_toNo
year_fromNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.9/5.0
Behavior5/5

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

With no annotations, the description carries the full burden, and it delivers: it reveals that court values are fuzzy-matched against list_catalog()['courts'], that year filters prune row groups for efficiency, and that results are chunks rather than complete judgments. This goes well beyond the structured schema.

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 compact, front-loaded with the core action, and every sentence adds meaning: required parameter, performance tradeoff, filtering guidance, and result shape. No filler or repetition.

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 search tool with five parameters, no annotations, and an existing output schema, the description covers the essential decision context: which parameter is required, how to scope the search, why narrowing matters, and how to follow up on a hit. Nothing critical for correct invocation is missing.

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 0%, so the description compensates for court and year_from/year_to by explaining requiredness, fuzzy matching, and performance behavior. Query and limit are less elaborated, but their purposes are reasonably inferable from the full-text-search framing and the schema defaults.

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 states a specific verb and resource: 'Full-text search over one court's judgment chunks.' It clearly distinguishes from the sibling search tools (search_legislation, search_regulations) by focusing on judgment chunks and requiring a court.

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?

The description explicitly says court is required, explains the fuzzy-matching behavior, warns against searching all 26 courts due to cost, and recommends using year_from/year_to when possible. It also directs the agent to get_judgment for reassembling full judgments from result chunks.

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

search_legislationA

Search Indian legislation at the section level for one jurisdiction.

  • query: free-text search over the section text, act title and section title (ILIKE, so it's a substring match, not ranked relevance).

  • state: jurisdiction slug, e.g. "central", "kerala", "west bengal". Fuzzy-matched against list_catalog's legislation_by_state keys.

  • act_id: exact match, e.g. "IND_central_1860_45", if you already know it.

  • in_force_only: excludes repealed/spent acts by default.

Each result includes source_url -- the authoritative government page for that exact provision.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
queryNo
stateNocentral
act_idNo
in_force_onlyNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

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

With no annotations present, the description carries the full burden and does so well: it discloses that query is an ILIKE substring match rather than ranked relevance, that state is fuzzy-matched, that in_force_only excludes repealed/spent acts by default, and that each result includes an authoritative source_url.

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 front-loaded with a clear summary sentence followed by tight bullet points. Every bullet adds meaningful information without redundancy.

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?

The description covers purpose, matching behavior, jurisdiction handling, default filtering, and result provenance, which is sufficient for most calls. It does not mention limit/pagination behavior or what happens when neither query nor act_id is supplied, though the output schema likely covers return structure.

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 descriptions are absent, so the description compensates for most parameters: query, state, act_id, and in_force_only all receive added semantics with examples. Only limit is left undocumented, which is a minor gap.

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 names a specific verb and resource: 'Search Indian legislation at the section level for one jurisdiction.' This immediately distinguishes it from siblings like get_act, search_regulations, and search_judgments.

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 gives clear context for using the tool, including what type of search it performs and that state values come from list_catalog. It does not explicitly state when not to use it or name alternatives, but the purpose is clear enough for an agent to choose correctly.

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

search_regulationsA

Search one regulator's instruments at the provision level, e.g. body="SEBI" or body="RBI". Same query semantics as search_legislation -- the regulator files share the same provision schema. Use list_catalog() to see which regulator slugs are currently published.

ParametersJSON Schema
NameRequiredDescriptionDefault
bodyYes
limitNo
queryNo
in_force_onlyNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior3/5

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

With no annotations, the description carries the behavioral disclosure burden. It adds useful context about provision-level granularity and shared schema semantics, but it does not disclose pagination, result ordering, whether only published instruments are returned, or other runtime behavior.

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 tight sentences front-load the tool's purpose and example, then point to the relevant sibling for schema semantics and list_catalog for valid inputs. Every sentence earns its place with no redundant phrasing.

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?

The core invocation path is covered: required body parameter, example values, where to find valid slugs, and the relationship to search_legislation. Gaps remain around the optional parameters and behavior, but the output schema and self-explanatory param names reduce the risk of incorrect calls.

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

Parameters2/5

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

Schema description coverage is 0%, so the description must compensate for all four parameters. It gives an example for 'body' but does not explain 'query', 'limit', or 'in_force_only'; the reference to 'same query semantics as search_legislation' is helpful only if the agent already knows that tool's parameter details.

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 states a specific verb and resource: 'Search one regulator's instruments at the provision level.' It also distinguishes itself from sibling search tools by emphasizing 'regulator' and by explicitly linking its query semantics to search_legislation while still framing it as a distinct corpus.

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?

It tells the agent when to use this tool—for regulator instruments—and points to list_catalog() to discover valid body slugs. It does not explicitly say when not to use it versus search_legislation or search_judgments, but the regulator/provision framing makes the intended domain clear.

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. 8 tool updatesv0.1.0
    • First observedget_act
    • First observedget_judgment
    • First observedget_schema
    • First observedlist_catalog
    • First observedrun_sql
    • First observedsearch_judgments
    • First observedsearch_legislation
    • First observedsearch_regulations

TDQS

A4.2/5.0

Scored across 8 tools

Disambiguation5/5

Each tool targets a clearly distinct function: catalog discovery, schema inspection, raw SQL, legislation search, act retrieval, regulation search, judgment search, and judgment reassembly. The search_* and get_* pairs are cleanly separated, and run_sql is explicitly framed as a lower-level alternative rather than a competing high-level search tool.

Naming Consistency5/5

All tool names follow a consistent verb_noun snake_case pattern: list_catalog, get_schema, run_sql, search_legislation, get_act, search_regulations, search_judgments, get_judgment. The naming convention is uniform and predictable.

Tool Count5/5

Eight tools is well-scoped for a legal research server: three low-level data-access tools and five domain-specific search/retrieval tools. Each tool earns its place and the count is neither thin nor bloated.

Completeness4/5

Legislation has both search and full-act retrieval, judgments have search and full-judgment reassembly, and regulations have search but no dedicated get_regulation tool analogous to get_act. That is a minor gap, though an agent can work around it using run_sql.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables semantic search over Polish court judgments and legislative acts via MCP. Allows LLMs to retrieve legal documents using natural language queries.
    Apache 2.0
  • A
    license
    A
    quality
    D
    maintenance
    Connects LLMs to the EcourtsIndia Partner API for searching Indian court cases, retrieving orders, reading cause lists, and accessing AI summaries.
    9
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Grounds external agents in public Indian judgments and statutes through MCP, enabling legal search and bounded document packets without requiring the full Roop platform.
    1
    MIT