Skip to main content
Glama
BharatPay MCP

BharatPay MCP

๐Ÿ‡ฎ๐Ÿ‡ณ BharatPay MCP

Workbench backend

The repository now has two adapters over shared Python services: the original seven-tool MCP server and an optional FastAPI backend with private vendor records, CSV batch jobs, and NAV ingestion. The original MCP command still works without MongoDB, accounts, or the API extra. No tools move money.

Run the complete local backend

API_PORT=8011 AIRFLOW_PORT=8081 docker compose -p bharatpay-nav-demo \
  -f compose.yaml -f compose.nav-replica.yaml up --build -d --wait

Open http://127.0.0.1:8011 for the responsive dashboard, or http://127.0.0.1:8011/docs for interactive API documentation. The dashboard covers sign-in, vendor CRUD, validation, CSV upload/results/reports and NAV history. Compose starts the API, a separate worker and MongoDB. This opt-in deployment creates a new nav-rs-data volume in a separate project; it does not migrate or delete an existing mongo-data volume. MongoDB has no host port. Stop with the same project/files and down without --volumes. The base compose.yaml alone still uses standalone MongoDB: NAV ingestion now fails closed there, because fencing requires replica-set transactions. Read the deployment and rollback guide before upgrading an existing installation. /health is liveness; /ready also checks the configured database.

  1. Use POST /api/v1/auth/register with a username (3โ€“40 letters, digits, dots, underscores or hyphens) and a password (10โ€“128 characters).

  2. Call /api/v1/auth/login, copy access_token, and enter it through Swagger's Authorize button. Sessions expire after two hours; logout revokes them.

  3. Create a record through POST /api/v1/vendors, for example {"name":"Demo","pan":"ABCPE1234F"}. Use synthetic identifiers.

  4. Call POST /api/v1/vendors/{id}/validate, then list /validation-runs and /stats. Each user's records and jobs are private to that account.

  5. Upload examples/vendors.csv to POST /api/v1/batch-jobs. Poll the returned job id, inspect /results, and download /report.csv. Invalid rows do not stop the other rows. An optional Idempotency-Key header deduplicates uploads.

  6. Queue POST /api/v1/ingestions/nav. The worker ingests public AMFI data; inspect /ingestion-runs and /funds/{scheme_code}/nav-history afterward.

Routes

All application routes below start with /api/v1.

Group

Routes

Offline utilities

POST /validations/pan, /validations/gstin, /validations/upi, /format/inr

Async lookups

GET /lookups/ifsc/{code}, /lookups/pincode/{code}, /funds/search?q=...

Accounts

POST /auth/register, /auth/login, /auth/logout; GET /auth/me

Vendors

POST/GET /vendors; GET/PUT/DELETE /vendors/{id}; POST /vendors/{id}/validate

History

GET /validation-runs, /stats

Durable jobs

POST/GET /batch-jobs; GET /batch-jobs/{id}, /{id}/results, /{id}/report.csv; POST /{id}/retry

Public-source ingestion

POST /ingestions/nav; GET /ingestion-runs, /ingestions/metrics, /funds/{scheme_code}/nav-history

Vendor, job, history and ingestion routes require a bearer token. List routes support page and page_size (maximum 100). Public-source ingestion history is shared between accounts; private vendor data is not. Failed private-id lookups return 404, without revealing another account's record.

Malformed request bodies return 422. Offline validation results use 200 with valid: false for a completed domain check. Lookup routes distinguish invalid input (422), missing records (404), provider failure (502) and timeout (504). The API owns a shared async HTTP client. The process-local lookup-cache refresh is protected by a lock; when refresh fails, older cached data is explicitly marked stale: true. NAV dates are source-record dates (ISO); fetched_at is download time. NAV values are decimal strings. INR uses half-up rounding to integer paise.

Tests and local Python development

python3 -m venv .venv-api
source .venv-api/bin/activate
python -m pip install -e ".[api,dev]"
python -m pytest tests/ -q
python -m uvicorn bharatpay_mcp.api.app:app --reload

Without MONGO_URL, pure validation and lookup routes work; saved workflows explicitly return 503. For the full persistence flow, use Compose, which supplies MONGO_URL; the replica-set override adds replicaSet=bharatpay-rs. MONGO_DATABASE defaults to bharatpay. The offline suite mocks providers and requires no database. To explicitly test the running API, MongoDB indexes, worker, lease recovery and ETL replay:

python scripts/run_isolated_checks.py

This local runner requires mongod on PATH. It creates temporary replica-set and standalone MongoDB processes, API/worker processes, free ports and synthetic data; then stops only its processes and removes their temporary directories. No existing service or volume is used. To run checks inside a separately deployed test project, use python scripts/check_backend.py in its API container. Never point the backend integration check at production. See test commands and results.

Standalone ETL and optional Airflow

API_PORT=8011 AIRFLOW_PORT=8081 docker compose -p bharatpay-nav-demo \
  -f compose.yaml -f compose.nav-replica.yaml exec api python -m bharatpay_mcp.ingest
# Use the same project/files plus --profile airflow to start the optional DAG service.
# Offline source replay (still writes to the configured DB; use a test deployment):
python -m bharatpay_mcp.ingest --fixture tests/fixtures/nav_synthetic.txt

The optional local Airflow standalone instance uses port 8081 with the settings above. Its authentication details are generated by Airflow in the container; follow its startup logs/local authentication configuration. The bharatpay_daily_nav DAG runs weekdays at 19:00 UTC with two retries, no catchup, and one active run. It calls the same ETL used by the CLI and worker. Unpause the DAG in Airflow to enable scheduled runs. The current DAG changes have not been executed in Airflow during this reliability upgrade; the integration suite exercises its shared service with an Airflow trigger. Both the current eight-column and legacy six-column AMFI formats are supported. The latest AMFI file cannot recreate historical dates: this project accumulates history from each successful fetch; Airflow backfill does not magically provide older source data.

NAV ingestion architecture

flowchart TD
    API[FastAPI queue endpoint] --> Jobs[(Mongo job queue)]
    Jobs --> Worker[Async worker]
    CLI[CLI / fixture replay] --> ETL[Shared ingestion service]
    DAG[Airflow daily task] --> ETL
    Worker --> ETL
    Source[Streamed AMFI bytes or saved fixture] --> Hash[SHA-256 and quality checks]
    ETL --> Source
    Hash --> Tx[Per-batch fenced transaction]
    subgraph RS[MongoDB replica set]
      Tx --> Lease[(Global lease and version)]
      Tx --> NAV[(Unique scheme/date upserts)]
      Tx --> Runs[(Run metadata and exact counters)]
      Tx --> Done[(Worker completion on final transaction)]
    end
    Runs --> Metrics[Authenticated ingestion metrics]
    Jobs --> Metrics
    Presence[Worker heartbeat] --> Metrics
    Metrics --> Dashboard[Existing FastAPI dashboard]

Every snapshot transaction writes the global lease document first. After a newer owner acquires it, an old transaction cannot commit a snapshot write. This is per-batch atomicity; earlier committed batches survive a later failure. Completed runs distinguish accepted source rows from new inserts and existing matches. The authenticated GET /api/v1/ingestions/metrics endpoint reports ingestion and worker health; the NAV dashboard shows those metrics. MCP and public search use their existing process-local cache, independently of stored NAV history.

See the baseline audit and design, metric definitions, fault tests, deployment and remaining risks.

Scope and limits

This is a local portfolio backend. Passwords are scrypt-hashed; only bearer-token hashes are stored; database expiry is checked independently of MongoDB TTL cleanup. Auth rate limits and lookup caches are per process. MongoDB is isolated inside the Compose network without database auth: add deployment secrets, TLS and database auth before hosting it. CSV uploads are limited to 1 MB and 500 rows. Workers use five concurrent row checks, a 120-second renewable lease, three automatic attempts, and stable row ids for restart recovery. Execution is at least once, not exactly once. Pagination uses bounded offsets and is intended for portfolio-scale data.

Format/checksum checks do not prove identity, registration or account activeness. Use synthetic data. A small HTML/CSS/JavaScript dashboard is served by FastAPI; the Django exercise remains later learning work. Taskflow is the primary full-stack portfolio project. See architecture and milestones.

An MCP server that gives any AI agent โ€” Claude Desktop, Cursor, Windsurf โ€” instant access to Indian fintech utilities. IFSC bank lookups, PAN/GSTIN validation with checksums, mutual fund NAVs, UPI VPA identification, pincode lookups, and Indian-style INR formatting. Seven tools. Zero auth. Zero cost. Designed to complement Razorpay's official MCP server โ€” they handle execution, BharatPay handles validation and lookups.

๐ŸŽฅ Demo coming soon ยท ๐Ÿ“ฆ pip install bharatpay-mcp ยท ๐Ÿ”— PyPI


Related MCP server: eco-policy-mcp

Why this exists

Razorpay shipped an official MCP server in early 2025 for executing payment operations โ€” creating orders, capturing payments, refunding. It's excellent.

But every Indian fintech project also needs a layer below that: validation and enrichment. Is this PAN's format correct? Does this GSTIN's mod-36 checksum verify? What bank does this IFSC code belong to? What's the PSP behind user@oksbi? What's today's NAV for Parag Parikh Flexi Cap?

Currently, an AI agent has to either hallucinate these answers or call seven different APIs with seven different auth schemes. BharatPay collapses all of it into a single MCP server an agent can install in 30 seconds.

Position-wise: BharatPay sits next to Razorpay's MCP, not in competition with it. They handle transactions; we handle validation. Use both together for a complete Indian-fintech AI stack.


Demo

Claude Desktop autonomously calling lookup_ifsc for an Indian bank lookup:

PyPI version Downloads Tests Python License MCP

Claude calling bharatpay's lookup_ifsc tool


What's in the box

Tool

Input

What it returns

lookup_ifsc

KKBK0000261

Bank, branch, address, MICR/SWIFT, supported rails (NEFT/RTGS/IMPS/UPI). Source: Razorpay's open IFSC API.

validate_pan

AABCT3518Q

Format check, entity type (Individual/Company/HUF/Trust/...) decoded from the 4th character.

validate_gstin

29AABCT1332L1ZS

Format + mod-36 checksum verification, embedded state and PAN extraction.

lookup_pincode

302001

District, state, all post offices. Source: India Post API.

get_mutual_fund_nav

parag parikh flexi cap or 122639

Latest NAV from AMFI's daily file. Fuzzy name search or exact code lookup. Cached for 6h.

validate_upi_vpa

angelina@oksbi

PSP identification (Google Pay/PhonePe/Paytm/...) and underlying bank from the handle suffix.

format_inr

100000 or 29500 (paise mode)

โ‚น1,00,000 (Indian comma style) + word form (1 Lakh, 1.5 Crore, etc.).

Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   AI Agent          โ”‚   MCP / stdio      โ”‚   BharatPay MCP      โ”‚
โ”‚   (Claude / Cursor) โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€> โ”‚   (this server)      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                                      โ”‚
                          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                          โ”‚                           โ”‚                           โ”‚
                   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”         โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                   โ”‚  Pure-logic โ”‚         โ”‚   Live HTTP APIs   โ”‚        โ”‚   Cached file   โ”‚
                   โ”‚  validators โ”‚         โ”‚ (no auth, no cost) โ”‚        โ”‚   (refreshed 6h)โ”‚
                   โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค         โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค        โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
                   โ”‚ PAN         โ”‚         โ”‚ ifsc.razorpay.com  โ”‚        โ”‚ AMFI NAVAll.txt โ”‚
                   โ”‚ GSTIN+mod36 โ”‚         โ”‚ postalpincode.in   โ”‚        โ”‚ (~6 MB, ~30K    โ”‚
                   โ”‚ UPI VPA     โ”‚         โ”‚                    โ”‚        โ”‚  schemes)       โ”‚
                   โ”‚ INR format  โ”‚         โ”‚                    โ”‚        โ”‚                 โ”‚
                   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜         โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Design notes worth calling out:

  1. Validators are pure functions. PAN, GSTIN, UPI, and INR run entirely offline โ€” zero network, zero failures from API outages. The mod-36 GSTIN checksum is implemented from the GSTN spec (verified self-consistent: see tests/test_validators.py::test_gstin_checksum_self_consistent).

  2. Network tools are async. IFSC and pincode lookups use httpx.AsyncClient so the MCP server can handle parallel tool calls without blocking.

  3. AMFI data is cached, not re-fetched per call. A single 6 MB file covers all ~30,000 Indian mutual fund schemes; refreshing it on every NAV query would be wasteful and slow. Cache TTL: 6 hours.

  4. Tool descriptions are LLM-tuned. Each tool's docstring is written for the model to read โ€” explicit input formats, examples, and what it returns. This is what determines whether an agent successfully picks the right tool.

  5. No data leaves your machine for offline tools. PAN/GSTIN/UPI/INR validation never touches the network. Useful for compliance-sensitive contexts.

Install

pip install bharatpay-mcp

Then add to ~/Library/Application Support/Claude/claude_desktop_config.json (Mac) or the Windows equivalent:

{
  "mcpServers": {
    "bharatpay": {
      "command": "python",
      "args": ["-m", "bharatpay_mcp"]
    }
  }
}

Restart Claude Desktop. Look for the ๐Ÿ”Œ icon โ€” bharatpay should be listed.

Option 2: From source

git clone https://github.com/angelina10504/bharatpay-mcp
cd bharatpay-mcp
pip install -e .

For Cursor

Add to .cursor/mcp.json in your project:

{
  "mcpServers": {
    "bharatpay": {
      "command": "python",
      "args": ["-m", "bharatpay_mcp"]
    }
  }
}

Try it

Once connected, try these prompts in Claude Desktop:

"Look up IFSC code KKBK0000261 and tell me what payment rails it supports."

"Is 29AAGCB7407Q1ZN a valid GSTIN? If so, what state is the entity registered in?"

"What's today's NAV for Parag Parikh Flexi Cap regular growth?"

"My friend's UPI ID is priya@oksbi โ€” which app does she use?"

"Format โ‚น12,00,000 in Indian style and tell me what it would be in paise."

The agent will autonomously pick the right tool. You'll see the tool call and its structured JSON response inline.

Tests

pip install -e ".[dev]"
pytest tests/ -v

The offline suite covers validators, REST contracts, mocked provider failures, cache concurrency, CSV limits, and password hashing. Explicit MongoDB/worker checks live in scripts/check_backend.py.

What's next (V2)

  • validate_aadhaar(number) โ€” Verhoeff checksum (offline, no UIDAI API needed)

  • get_holiday_calendar() โ€” RBI bank holidays (settlement-day awareness)

  • stock_quote(symbol) โ€” NSE/BSE live quotes for RELIANCE.NS-style tickers

  • tax_slab_calculator(income, regime) โ€” Old vs new regime estimation

  • Bundle as npx @bharatpay/mcp for zero-install distribution

Open an issue on GitHub if you want any of these prioritized.

A note on "AI-first India"

When Razorpay launched their MCP server, they framed it as "designed for an AI-first world." That framing is right โ€” but transactions are only half the picture. Half the engineering effort in any Indian fintech goes into validation, enrichment, and lookups that an AI agent can't reliably hallucinate. That's the gap BharatPay fills.

If you're building AI tools for Indian fintech and you find a utility missing, open an issue or send a PR.

License

MIT โ€” see LICENSE. All upstream APIs (Razorpay IFSC, India Post, AMFI) are themselves free and publicly available under their respective terms.


Built by Angelina Gupta ยท April 2026

Available Tools

7 tools
format_inrA

Format an INR amount in Indian numbering conventions (lakh/crore grouping with comma every two digits after the first three) and return word form. Set paise=True if amount is in paise (Razorpay API style, where 1 INR = 100 paise).

Inputs: amount (required), paise. Returns: object

get_mutual_fund_navA

Get the latest daily NAV for an Indian mutual fund scheme. Accepts either an AMFI scheme code (digits only) or a name fragment for fuzzy search. Data sourced from AMFI India's public daily file.

Inputs: query (required). Returns: object

lookup_ifscA

Look up bank, branch, address, and supported payment rails (NEFT/RTGS/IMPS/UPI) for an Indian IFSC code. Uses Razorpay's free public IFSC API.

Inputs: ifsc (required). Returns: object

lookup_pincodeA

Look up state, district, and post offices for an Indian PIN code using the free India Post API.

Inputs: pin (required). Returns: object

validate_gstinA

Validate Indian GSTIN: format, mod-36 checksum, and extract embedded state and PAN. Returns the registration state name from the leading state code.

Inputs: gstin (required). Returns: object

validate_panA

Validate Indian PAN format and identify the entity type (Individual / Company / HUF / Trust / Partnership Firm / etc.) from the 4th character.

Inputs: pan (required). Returns: object

validate_upi_vpaA

Validate a UPI VPA's format and identify the issuing PSP and underlying bank from the handle suffix (e.g., 'oksbi' โ†’ Google Pay on State Bank of India).

Inputs: vpa (required). Returns: object

Tool Schema Changelog

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

Loading tool schema changelogโ€ฆ

    TDQS

    A4.2/5.0

    Scored across 7 tools

    Disambiguation5/5

    Each tool addresses a unique Indian financial or address validation task, with no overlap. IFSC, PAN, GSTIN, pincode, mutual fund NAV, UPI VPA, and INR formatting are all distinct and clearly separated.

    Naming Consistency5/5

    All tool names follow a consistent verb_noun pattern (e.g., lookup_ifsc, validate_gstin, format_inr). Verbs like 'lookup', 'validate', 'get', and 'format' are used appropriately, with no mixing of conventions.

    Tool Count5/5

    Seven tools is an appropriate number for a focused domain of Indian financial utilities. Each tool covers a key operation, and the count is neither too sparse nor excessive.

    Completeness5/5

    The tool set covers common Indian financial identifiers (IFSC, PAN, GSTIN, UPI), address lookup (pincode), mutual fund data, and currency formatting. This appears comprehensive for the intended use case, with no obvious missing operations.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      D
      maintenance
      Enables 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.
      6
      9 npm
      1
      MIT
    • A
      license
      A
      quality
      B
      maintenance
      Enables AI agents to fetch Indian mutual-fund NAVs and NSE market data, calculate GST and income-tax amounts, and look up RBI policy rates, with provenance blocks for citations. Works with any MCP client over stdio or HTTP.
      17
      MIT
    • A
      license
      A
      quality
      B
      maintenance
      Enables LLMs to look up, validate, and search Indian bank branch data by IFSC โ€” returning real branch addresses, MICR codes, and settlement-rail support, plus mapping bank names to their 4-letter codes, so models query a tool instead of hallucinating payment details.
      6
      MIT