bharat-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@bharat-mcpvalidate GSTIN 27AAPFU0939F1ZV and tell me the state"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
bharat-mcp
Give your AI agent accurate Indian GST, PAN, pincode and compliance knowledge.
An MCP server with eight small tools for Indian data that an AI agent should not work out in its head: checksums, code tables, lookups and due dates. It runs offline. The checksums are calculated, the datasets ship inside the package, and nothing you type is sent anywhere. Every answer says what it is based on and how old that data is.
Real output from the built server over stdio, saved by npm run proof. The fake differs from the real one in the last character only.
Does it actually help? What we measured
We put the same questions to Claude models with no tools and compared them with the tool. Everything below is reproducible; see Reproduce everything.
Test 1: is this GSTIN valid? 40 GSTINs, 20 real and 20 with exactly one character changed (so the shape is right and only the checksum can tell). The answer key is the checksum itself. A separate Python implementation of the checksum agrees with this package on 20,000 random strings (cross-check), and the algorithm reproduces the commonly published sample GSTINs used in the tests.
Opus and Sonnet scored 40/40 with no tools. Haiku scored 38/40: it accepted one fake (
25WKRPW1917M3ZS) and rejected one real GSTIN (01RLFCG9549K2Z7).The tool scored 40/40 in 9 ms for all 40 calls over stdio. The three models took 43 to 70 seconds for the same 40 questions.
So, to be straightforward about it: current Claude models are mostly right on this when asked carefully, and we could not reproduce "an AI approves a fake GSTIN" with Sonnet or Opus. What the tool gives you is a different kind of answer: the same one every time, in microseconds, with the reason ("the check character should be 4, not 5") and a clear note that well-formed is not the same as registered. A cheaper model, a rushed prompt or a long agent run is where a slip like Haiku's shows up.
Test 2: data a model cannot calculate.
Pincode to state (30 random pincodes): both Haiku and Sonnet got 29/30. Both put
262122(Pilibhit) in Uttarakhand instead of Uttar Pradesh. We do not headline the district results, because India Post lists post-office divisions, not always revenue districts, and some names changed after our data (Allahabad is now Prayagraj, Karimganj is now Sribhumi). That is also a limit of this package: see data sources.2027 Central Government holidays (17): the DoPT order for 2027 was issued in July 2026. Haiku matched 5 and said "unknown" for 12, which is the honest answer. Sonnet matched 13 and differed on 4, with no hedging, including Dussehra on 20 October 2027, which is the 2026 date (the order says 9 October 2027). Holi, Muharram and Guru Nanak's Birthday differ by one day; the order is the authority for these, not an astronomical calendar.
How the model runs were made, and their limits. Each model was a fresh Claude Code subagent given one prompt with all the questions and told not to use tools, code, files or the web. The transcripts were checked afterwards: the only tool call in every run was the one that returns the answer. Limits: all 40 GSTINs went into one prompt (a single casual question may behave differently); only Claude models were tested; 40 questions is a small sample (one mistake is 2.5 points); and the tool's own data cannot be used to prove the tool right, which is why Test 2 has no score for it. The raw answers and scored results are in bench/results/ and the method is in bench/llm/. To test your own model: npm run bench:llm -- --backend api --model <model-id> (needs ANTHROPIC_API_KEY in your shell). That runner is tested with a stand-in model only; the Claude results above were produced the way described here, not with it.
Related MCP server: BharatPay MCP
Tools
Tool | What it does | Works offline |
| 15-character structure, state code, embedded PAN and the mod-36 check character, with decoded parts. Regular-taxpayer GSTINs only (14th character Z) | yes |
| Shape plus holder type (individual, company, firm, HUF, trust and so on) | yes |
| Format and Verhoeff checksum only. Nothing is stored or looked up; only the last 4 digits are returned | yes |
| IFSC format and bank code, with the bank name for well-known banks | yes |
| State, district, postal circle and post offices for a 6-digit pincode | yes (bundled data) |
| State and union territory by name, GST code, ISO code or RTO prefix; QRMP GSTR-3B due-day group | yes |
| Central Government closed holidays for 2026 and 2027, or check one date | yes |
| GST, TDS, advance tax, EPF/ESI and ROC due dates in a date range, with legal basis and authority | yes |
All tools are read-only.
See it work in a terminal
git clone https://github.com/lllakshit/bharat-mcp.git
cd bharat-mcp && npm install && npm run build
npm run demonpm run demo starts the built server over stdio, exactly as Claude Desktop or Cursor would, and calls every tool:
Bad input comes back as an MCP error (isError: true), not as a guess.
Install
Requires Node 18 or newer.
Claude Desktop: add this to claude_desktop_config.json (on macOS: ~/Library/Application Support/Claude/claude_desktop_config.json), then restart Claude:
{
"mcpServers": {
"bharat": {
"command": "npx",
"args": ["-y", "bharat-mcp"]
}
}
}Cursor: add the same block to ~/.cursor/mcp.json (or .cursor/mcp.json in a project).
Claude Code:
claude mcp add bharat -- npx -y bharat-mcpFrom source (before or instead of npm): npm run build, then use "command": "node", "args": ["/path/to/bharat-mcp/dist/cli.js"] in the config above.
Then ask your agent: "Is GSTIN 29AAGCB7383J1Z5 valid?" It should call validate_gstin and tell you the check character is wrong.
You can also use the functions directly: import { validateGstin } from "bharat-mcp".
Speed and size
Measured on Apple M1 (8 cores, 16 GB, darwin arm64, Node v26.12.1) with npm run bench:
| 1,920,322 calls/s (0.52 µs each) |
| p50 0.07 ms, p99 0.25 ms |
| p50 0.05 ms (first call 24 ms, which reads the data file once) |
| p50 0.16 ms |
Cold start to tool list | 228 ms median |
Memory after loading all data | about 151 MB |
Package | 911 KB download, 4.5 MB unpacked, 40 files |
These are one machine and one run. Treat them as the order of magnitude, not a guarantee.
Tests
57 tests cover the validators (including every single-character mistake in the sample GSTINs and Aadhaar numbers), the data, the date logic and the MCP server end to end. CI runs them on Node 22 and 24, runs the built server on Node 18 and 20, and audits the dependencies.
Data sources and limits
Short version; the full detail is in DATA-SOURCES.md.
Data | Source | As of | Limit |
Pincodes | India Post All India Pincode Directory (data.gov.in), listed as Government Open Data License - India on the mirror it was taken from | 30 May 2019 | Old. Pincodes created since are missing. District names are as in 2019 (for example Allahabad, not Prayagraj). |
States, GST codes, RTO prefixes | CBIC/GSTN GST state codes, ISO 3166-2:IN, MoRTH series | 7 Nov 2026 | Hand-curated |
Holidays | DoPT orders for 2026 (dated 3 Jul 2025) and 2027 (dated 16 Jul 2026; checked against the official memorandum) | 7 Nov 2026 | Central Government (Delhi) closed holidays only. No state, bank or stock-exchange holidays. Moon-dependent dates can shift. |
Compliance deadlines | Statutory due dates under the CGST Rules, Income-tax rules, EPF/ESI and Companies Act | 7 Nov 2026 | Starter set. Standard dates only; government extensions are not included. Checked against secondary calendars, not yet line by line against each notification, so every entry is marked |
Things this server deliberately does not do:
It does not tell you a GSTIN, PAN or Aadhaar number is real or registered. A pass (
valid_format: true) means well-formed. Only the GST portal, the Income Tax Department or UIDAI can say more.It does not look up Aadhaar numbers, store them, or log them.
It does not scrape government portals or captcha-protected pages.
It does not recognise TDS/TCS, UN-body or non-resident GSTIN formats; they are reported as not supported, not as fake.
It does not include IFSC branch data yet. The RBI data has no clear reuse licence, so only the format and bank code are checked.
It does not shift a due date that falls on a Sunday or holiday. It flags it.
Every tool result carries its own note or data_as_of, so a model reading the answer can see how far to trust it.
Reproduce everything
npm install && npm run build
npm test # 57 tests
npm run demo # the terminal tour above
npm run bench # speed and size
python3 bench/crosscheck.py # independent Python checksum vs this package, 20,000 strings
node bench/llm/tool-check.mjs # the 40 GSTIN questions put to the tool over stdio
node bench/llm/report.mjs # the benchmark table, from the saved results
npm run proof # regenerates every screenshot in docs/img from real runsThe screenshots in docs/img are SVG renderings of real terminal output. The raw text of each run is in docs/proof/, so you can compare them line by line.
Develop
npm install
npm test
npm run typecheck
npm run build
npm run smoke # starts the built server over stdio and calls itRebuild the pincode file from a CSV: node scripts/build-pincodes.mjs path/to/pincode.csv 2019-05-30.
Contributing
Issues and pull requests are welcome, especially:
a wrong or out-of-date due date (please link the official notification),
a state or bank code that is missing,
tell me which Indian data you want next.
Licence
Code: MIT. Bundled data keeps the licence of its source; see DATA-SOURCES.md.
Available Tools
8 toolscompliance_deadlinesGST, TDS, ROC and payroll due datesARead-onlyIdempotent
Lists standard Indian compliance due dates (GST returns, TDS deposits and returns, advance tax, EPF/ESI, ROC filings) falling between two dates, with the legal basis and official authority for each. Defaults to the next 31 days from today in IST. Pass a state to get the right QRMP GSTR-3B date. These are the standard statutory dates; government extensions are not included, so always confirm with the official notification before relying on a date.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | End date YYYY-MM-DD (default: 30 days after `from`) | |
| from | No | Start date YYYY-MM-DD (default: today in IST) | |
| state | No | State of GST registration, for the QRMP GSTR-3B date | |
| categories | No | Limit to: gst, tds, income_tax, roc, labour |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish read-only, idempotent, closed-world behavior, yet the description adds genuinely new context: dates are standard statutory dates, government extensions are excluded, and each entry comes with legal basis and official authority. That tells the agent how much to trust the output before it calls. It does not discuss output ordering or completeness limits, so it is not exhaustive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, front-loaded with purpose, followed by defaults, parameter nuance, and the accuracy caveat. The defaults and state sentences overlap with what the schema already states, so some content is duplicated rather than wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, and the description compensates by stating what each date carries (legal basis, official authority) and, crucially, the limitation that extension dates are missing. For a four-parameter, zero-required read-only lookup this is close to complete; a hint on the shape or count of returned entries would close the remaining gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all four parameters are already documented, including that `state` drives the QRMP GSTR-3B date and that `from`/`to` default to today in IST and 30 days later. The description restates those defaults rather than adding new meaning, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
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 ("Lists standard Indian compliance due dates"), enumerates the covered categories (GST, TDS, advance tax, EPF/ESI, ROC), and scopes the result to a date range. It is unmistakably distinct from the sibling tools, which are all single-value validators or holiday/pincode lookups.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear operating context: defaults to the next 31 days in IST, pass a state only when QRMP GSTR-3B applies, and a warning that extensions are excluded so dates must be confirmed against the official notification. It stops short of naming alternatives (e.g. pointing to india_holidays for public holidays or state_info for registration details), which keeps it from a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
india_holidaysIndian central government holidaysARead-onlyIdempotent
Lists the Central Government closed (gazetted) holidays for a year, or checks whether a given date is one (if both are given, date is used). Covers 2026 and 2027, from the DoPT order. It does NOT include state holidays, bank holidays or stock-exchange holidays, and moon-dependent festival dates can shift by a day.
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | A date YYYY-MM-DD to check instead of listing a year | |
| year | No | The year, for example 2026 |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, it discloses the authoritative source (DoPT order), supported years (2026 and 2027), coverage limits (no state, bank, or stock-exchange holidays), and a key accuracy caveat that moon-dependent festival dates may shift by a day.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tightly written sentences, front-loaded with purpose and followed by exclusions and caveats. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter read-only lookup with no output schema, the description gives enough context to call it correctly, understand its coverage, and interpret its limitations. Nothing material is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so baseline is 3, but the description adds meaningful semantics: `date` triggers a check rather than a list, and when both parameters are given, `date` takes precedence. It does not add format details beyond what the schema already states.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: it lists Central Government closed (gazetted) holidays for a year or checks whether a given date is one. It clearly scopes the dataset to DoPT orders and 2026-2027, and distinguishes this from broader holiday categories.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly explains the two usage modes: list by year or check a date, and states precedence when both are supplied (`date` is used). It also names what is excluded, which prevents misuse for state, bank, or stock-exchange holidays.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lookup_pincodeLook up an Indian pincodeARead-onlyIdempotent
Returns the state, district, postal circle and post offices for a 6-digit Indian pincode from the bundled India Post directory. The directory is dated (see data_as_of), so a pincode created after that date will not be found.
| Name | Required | Description | Default |
|---|---|---|---|
| pincode | Yes | The 6-digit pincode |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint, idempotentHint, and openWorldHint=false. The description adds meaningful context beyond that: it identifies the bundled India Post directory and warns that dated data means newer pincodes will not be found. It does not describe error behavior for malformed input, but the key data-source limitation is disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with what is returned and followed by the important staleness caveat. Every sentence earns its place with no unnecessary wording.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-parameter read tool with no output schema, the description enumerates the returned fields and explains the source and date limitation. It is nearly complete, though it could explicitly state what happens for an invalid or not-found pincode.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the schema already documents the single pincode parameter as a 6-digit value. The description repeats the 6-digit requirement but adds no additional syntax or format meaning beyond what the schema provides, so this is the baseline score.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: it returns state, district, postal circle, and post offices for a 6-digit Indian pincode. This clearly distinguishes it from sibling validators such as validate_gstin and validate_pan, which check formats rather than look up directory data.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a clear lookup context and adds a useful staleness caveat about pincodes created after the directory date. However, it does not explicitly name alternatives or state when not to use this tool versus sibling tools like state_info.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
state_infoState and union territory codesARead-onlyIdempotent
Looks up an Indian state or union territory by name, GST state code (for example 27), ISO code (IN-MH) or vehicle registration prefix (MH). Returns the GST code, RTO prefixes, capital, and the QRMP GSTR-3B due day group. With no query it lists all 36.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | A name, GST code, ISO code or RTO prefix. Leave out to list all. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnly, idempotent and closed-world, so the safety profile is covered. The description adds genuinely useful behavior that annotations cannot convey: the exact return payload (GST code, RTO prefixes, capital, QRMP GSTR-3B due day group) and the 'no query returns all 36' default. It stops short of saying how an unmatched query is handled or whether the result is a single record or a list when a partial name matches several states.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler: accepted inputs first, returned fields second, the list-all default front-loaded at the end where it is immediately actionable. Examples are embedded inline rather than given their own clauses.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
A one-parameter, optional-parameter lookup with full schema coverage has modest requirements, and the description fills them by naming the returned fields in lieu of an output schema and stating the empty-query behavior. Nothing an agent needs in order to call it correctly appears to be absent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, and the schema's own description already says 'A name, GST code, ISO code or RTO prefix. Leave out to list all.' The prose restates that almost verbatim with illustrative values, adding only marginal meaning beyond the structured field, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
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 ('Looks up an Indian state or union territory') and enumerates the four accepted identifier types with concrete examples (27, IN-MH, MH). It is clearly a static reference lookup, which distinguishes it from the sibling tools, all of which validate or compute against inputs rather than resolve a code.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear invocation contexts: supply any of four identifier forms, or omit the query to enumerate all 36. What is missing is any exclusion or error guidance, such as what happens on a misspelled name or an out-of-range code, and it does not explicitly redirect to a sibling for adjacent needs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validate_aadhaar_formatCheck an Aadhaar number's formatARead-onlyIdempotent
Checks only the FORMAT of an Aadhaar number: 12 digits, not starting with 0 or 1, and the Verhoeff checksum. Nothing is stored, logged or looked up, and only the last 4 digits are returned. A pass does not mean the number was issued to anyone. Do not use this to identify people.
| Name | Required | Description | Default |
|---|---|---|---|
| aadhaar | Yes | The 12-digit number, spaces allowed |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent and closed-world, but the description goes well past them: nothing is stored, logged or looked up, and only the last 4 digits come back. That is exactly the privacy-relevant behavior an agent needs to know before sending a sensitive identifier, and it is information the annotations could not convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, each doing distinct work: what is checked, what is not done with the input, and what the result does and does not prove. The scope restriction is front-loaded, and there is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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 validator, the description covers the input rules, the privacy behavior, and the return shape (last 4 digits plus a pass/fail semantics). Nothing an agent needs in order to call it correctly or interpret the answer is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 real meaning about what the parameter must contain (12 digits subject to a starting-digit rule and a Verhoeff checksum), while the schema supplies the 'spaces allowed' detail and length bounds; the two are complementary rather than redundant.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Checks only the FORMAT of an Aadhaar number') and enumerates the exact rules applied: 12 digits, not starting with 0 or 1, Verhoeff checksum. The word 'only' immediately separates it from any sibling that might look up or verify real numbers, so an agent can distinguish it from validate_gstin/validate_pan/lookup_pincode without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit negative guidance ('Do not use this to identify people') and a critical caveat that a pass does not mean the number was issued, which defines the boundary of what the result means. What it lacks is a positive framing of when to reach for this versus the other validate_* siblings, though the resource named in the description makes the split fairly obvious.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validate_gstinValidate a GSTINARead-onlyIdempotent
Checks an Indian GSTIN offline: 15-character structure, state code, embedded PAN, and the mod-36 check character. Returns the decoded parts. Use this instead of guessing whether a GSTIN is well-formed; a model cannot calculate the check character reliably. Covers regular-taxpayer GSTINs (14th character Z); TDS/TCS, UN-body and non-resident formats are not supported. A pass only means well-formed, not registered or active.
| Name | Required | Description | Default |
|---|---|---|---|
| gstin | Yes | The GSTIN, with or without spaces or hyphens |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnly/idempotent/closed-world; the description adds genuinely new behavior: validation is done offline with no registry lookup, and a pass means only well-formed, 'not registered or active.' That last caveat is exactly the kind of interpretive guardrail an agent needs when acting on the result.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four tight sentences, front-loaded with what is checked, then motivation, then format limits, then the result caveat. No filler and no repetition of the name or title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description must carry the return contract, and 'Returns the decoded parts' is only a sketch — an agent does not know which fields come back or what a failure looks like. Everything else an agent needs (scope, exclusions, meaning of success) is present.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only one parameter and the schema already documents it at 100% coverage, including that spaces or hyphens are accepted. The description adds no input-format detail (e.g. case normalization or the 40-char max), so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific verb and resource ('Checks an Indian GSTIN') and enumerates exactly what is verified: 15-character structure, state code, embedded PAN, and mod-36 check character. The offline scope plus the stated format boundary (regular-taxpayer, 14th char Z) cleanly separates it from validate_pan and the other validate_* siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit use case ('use this instead of guessing whether a GSTIN is well-formed; a model cannot calculate the check character reliably') and explicit exclusions (TDS/TCS, UN-body, non-resident formats unsupported). It falls short of 5 because it never names where the agent should go for the excluded formats, so alternatives remain unstated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validate_ifscCheck an IFSC code's formatARead-onlyIdempotent
Checks the format of an IFSC code (4 bank letters, a zero, 6 branch characters) and names the bank for well-known bank codes. It does not confirm that the branch exists or give the branch address.
| Name | Required | Description | Default |
|---|---|---|---|
| ifsc | Yes | The 11-character IFSC |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, and closed-world behavior, so the safety profile is covered. The description adds real value beyond that by disclosing that bank names are resolved only for well-known codes (partial coverage) and by stating the negative capabilities. It does not say what happens on a malformed input (error vs. a failed-validation result), which is a meaningful gap for a validator.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences: the positive capability with its rule comes first, the limitation second. No filler, no repetition of the title, every clause carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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 validation tool, the description covers what is checked, what extra data (bank name) may come back, and the limits of the result. The only omission is the shape of an invalid-format response, which matters somewhat since no output schema exists.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single parameter is documented, so the baseline is 3. The description does add structural meaning beyond the schema by decomposing the code into 4 letters + zero + 6 branch characters, though it leaves a slight inconsistency with the schema's maxLength of 30 versus the stated 11 characters unaddressed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb ('Checks the format') and resource (IFSC code) and spells out the validation rule (4 bank letters, a zero, 6 branch characters), so an agent knows exactly what is examined. The IFSC resource is inherently distinct from the sibling validators (GSTIN, PAN, Aadhaar), though no sibling is named explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Clear scope boundaries are given: it validates format only and explicitly does NOT confirm branch existence or return an address, which steers an agent away from using it as a branch lookup. It stops short of naming an alternative tool to use instead when branch or address data is needed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validate_panValidate a PANARead-onlyIdempotent
Checks an Indian PAN offline: the 5 letters, 4 digits, 1 letter shape and the holder type in the 4th character (individual, company, firm, HUF, trust and so on). A pass does not prove the PAN was issued or who owns it.
| Name | Required | Description | Default |
|---|---|---|---|
| pan | Yes | The 10-character PAN |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and openWorldHint=false, so safety is covered. The description adds behavior beyond that: the check is performed offline and a pass has bounded meaning (no issuance, no ownership attestation), which prevents over-trusting the result. What's missing is the shape of the return value (boolean vs. structured result), so it falls short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no filler. The positive capability is stated first and the limitation ('a pass does not prove...') is front-loaded as a caveat in the second sentence. Every clause carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter, read-only, no-output-schema validator this is nearly sufficient: the rules checked and the limits of a pass are both covered. The only gap is that it doesn't indicate the response shape — e.g., whether it returns only a boolean or also the decoded holder type — which matters since no output schema exists.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and there is only one parameter, so baseline is 3. The description earns above baseline by adding real meaning to the input: the exact 10-character structure and the fact that character 4 encodes holder type, which the schema's 'The 10-character PAN' does not convey.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb and resource: 'Checks an Indian PAN offline', and then enumerates exactly which rules are checked — the 5-letter/4-digit/1-letter shape and the holder-type character in position 4. This is enough to tell it apart from siblings like validate_gstin or validate_aadhaar_format without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage context is clear: it is an offline format validator, not an issuance or ownership check, and the description states that a pass does not prove the PAN was issued or who owns it. It doesn't explicitly contrast with a hypothetical online lookup or name alternatives, but with a sibling set of distinct per-identifier validators the selection is unambiguous.
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.
8 tool updates
v0.1.0- First observed
compliance_deadlines - First observed
india_holidays - First observed
lookup_pincode - First observed
state_info - First observed
validate_aadhaar_format - First observed
validate_gstin - First observed
validate_ifsc - First observed
validate_pan
TDQS
Scored across 8 tools
Each tool targets a clearly distinct identifier or reference domain: GSTIN, PAN, Aadhaar format, IFSC, pincode, state metadata, holidays, and compliance deadlines. The validate_* tools could superficially look similar, but their descriptions make the input types and purposes unambiguous. No two tools compete for the same task.
Four tools follow a clear validate_<identifier> pattern, but the remaining tools use varied forms: lookup_pincode, state_info, india_holidays, and compliance_deadlines. The names are readable and not confusing, but there is no single predictable convention across the set.
Eight tools is well-scoped for an offline Indian validation and compliance-reference server. Each tool covers a distinct lookup or validation need, and there appear to be no redundant or trivial entries.
The surface covers the main Indian identifier validators plus useful reference data for pincodes, states, holidays, and statutory deadlines. There are minor gaps such as bank-branch lookup beyond IFSC format, GST rate/HSN lookup, or broader identifier formats, but core workflows are supported.
Maintenance
Related MCP Connectors
15 deterministic validation tools for AI agents: tax IDs (15 countries), VAT, IBAN, LEI, HS codes.
Free Indian data and AI: pincode, IFSC, GSTIN, holidays, GST invoice, OCR, translation. No key.
Validate IBAN, BIC, VAT, national IDs, phones, postal codes offline; 240+ identifiers.
Offline IBAN/BIC/EU VAT/card/ISBN/GTIN validators + live USD stablecoin peg-health verdict.
Related MCP Servers
- AlicenseAqualityAmaintenanceAn offline-first MCP server for Indian financial, tax, and government APIs, providing tools for identity validation (PAN, Aadhaar, GSTIN), tax calculations (Income Tax, TDS, GST), and master data lookups (IFSC, Pincode, HSN/SAC) with zero authentication required.76145 PyPI83MIT
- AlicenseAqualityCmaintenanceProvides AI agents with Indian fintech utilities including IFSC bank lookups, PAN/GSTIN validation, mutual fund NAVs, UPI VPA identification, pincode lookups, and INR formatting, all with zero authentication and zero cost.7MIT
- AlicenseAqualityDmaintenanceEnables LLMs to query real-time Indian bank branch details, postal PIN codes, validate GSTIN/PAN structures, check e-commerce serviceability, and compute GST breakdowns using free public APIs and offline verification logic.621 npm1MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI assistants to validate IBAN, BIC, EU VAT, GTIN/EAN/UPC, and ISBN codes offline through format and check-digit checks, and retrieve related metadata.26,592 npmMIT