Skip to main content

INDmoney MCP Server

A Model Context Protocol (MCP) server that gives Claude read-only access to your INDmoney portfolio — stocks, mutual funds, US stocks, gold, credit cards, liquid savings, loans, and debt.

Built with Python + Playwright. Uses browser automation for OTP login and network interception to capture live API data. Sessions are encrypted and persist across restarts.


What you can ask Claude

Once connected, you can ask things like:

  • "Show me my stock holdings and P&L"
  • "How are my mutual funds performing?"
  • "What's my US stocks portfolio in INR?"
  • "What's my outstanding credit card balance?"
  • "Give me a full portfolio summary with asset allocation"
  • "How much cash do I have in my savings accounts?"

Features

14 MCP tools Status, connect, disconnect, holdings, MF, US stocks, gold, loans, credit cards, liquid, debt, summary, credit score, discover
Persistent sessions AES-256-GCM encrypted session survives server restarts (12-hour TTL)
Two-level cache In-memory (5 min) + disk (60 min) — subsequent queries are instant
Reliable fetching Direct JWT Bearer calls + page-nav interception fallback
Read-only No order placement, no fund transfers — portfolio data only
Type-safe Pydantic models throughout; all responses are structured JSON

Requirements

  • Python 3.11+
  • macOS / Linux / Windows (WSL2)
  • Claude Desktop (or any MCP-compatible client)
  • An INDmoney account

Installation

1. Clone and install

git clone https://github.com/VIckys-AI-Stuffs/indmoney-mcp-python.git
cd indmoney-mcp-python

python3.11 -m venv venv
source venv/bin/activate        # Windows: venv\Scripts\activate

pip install -e .
python -m playwright install chromium

2. Generate an encryption key

The server encrypts your session on disk with AES-256-GCM. Generate a persistent key once and keep it — losing it means losing your saved session (you'll just need to log in again):

python3 -c "import secrets; print(secrets.token_hex(32))"
# example output: a3f1c8e2b4d7...  ← copy this value

3. Configure Claude Desktop

Open your Claude Desktop config file and add the indmoney server block. All configuration is passed directly via the env key — no .env file needed.

Platform Config file location
macOS ~/Library/Application Support/Claude/claude_desktop_config.json
Linux ~/.config/Claude/claude_desktop_config.json
Windows %APPDATA%\Claude\claude_desktop_config.json
{
  "mcpServers": {
    "indmoney": {
      "command": "/absolute/path/to/indmoney-mcp-python/venv/bin/python",
      "args": ["/absolute/path/to/indmoney-mcp-python/main.py"],
      "env": {
        "PYTHONUNBUFFERED": "1",
        "SESSION_ENCRYPTION_KEY": "paste-your-32-byte-hex-key-here"
      }
    }
  }
}

Important: Use the full absolute path to venv/bin/python, not just python.

All supported env variables

Variable Required Default Description
SESSION_ENCRYPTION_KEY Recommended (auto-generated) 32-byte hex key for AES-256-GCM session encryption. If omitted, a new key is generated on every restart and your saved session will be lost each time.
SESSION_TTL_HOURS No 12 How long a logged-in session stays valid before requiring re-login
CACHE_TTL_MINUTES No 60 Disk cache TTL — how long fetched portfolio data is kept on disk
IN_MEMORY_CACHE_TTL_MINUTES No 5 In-memory cache TTL — subsequent queries within this window return instantly
API_REQUEST_TIMEOUT No 10 Per-request timeout in seconds
API_TOTAL_TIMEOUT No 60 Total timeout for a full data fetch in seconds
LOG_LEVEL No INFO Log verbosity: DEBUG, INFO, WARNING, ERROR
BROWSER_HEADLESS No false Set true to hide the browser window (not recommended — you need to see it for OTP login)
BROWSER_DATA_DIR No ./browser-data Path to store the persistent Playwright browser profile (cookies, localStorage)
SESSIONS_DIR No ./sessions Path to store encrypted session + cache files

Advanced: full config example with all options

{
  "mcpServers": {
    "indmoney": {
      "command": "/absolute/path/to/indmoney-mcp-python/venv/bin/python",
      "args": ["/absolute/path/to/indmoney-mcp-python/main.py"],
      "env": {
        "PYTHONUNBUFFERED": "1",
        "SESSION_ENCRYPTION_KEY": "paste-your-32-byte-hex-key-here",
        "SESSION_TTL_HOURS": "12",
        "CACHE_TTL_MINUTES": "60",
        "IN_MEMORY_CACHE_TTL_MINUTES": "5",
        "LOG_LEVEL": "INFO",
        "BROWSER_HEADLESS": "false"
      }
    }
  }
}

Alternative: Instead of the env block, you can copy .env.example to .env in the project root and set values there. Both approaches work — the Claude config env block takes precedence over .env if the same key appears in both.

3. Restart Claude Desktop

Quit completely and reopen. The indmoney server should appear in Settings → MCP Servers.


Connecting for the first time

In Claude, say:

Connect me to INDmoney

Claude will:

  1. Open a Chromium browser window
  2. Navigate to INDmoney login
  3. Wait while you enter your phone number + OTP
  4. Detect successful login, save the encrypted session, and close the browser

The OTP login window may timeout after ~30 seconds on Claude's side — that's okay. The browser stays open and the session is saved when you complete the OTP. Call broker_status afterward to confirm.


MCP Tools Reference

Session Management

Tool Description
broker_status Connection status, session age, cache inventory
broker_connect Open browser for OTP login (saves encrypted session)
broker_disconnect Log out, wipe session + cache

Portfolio Data

Tool What it returns
get_holdings Indian stock holdings — symbol, quantity, avg price, current value, P&L
get_mutual_funds MF holdings — scheme name, invested, current value, returns, XIRR
get_us_stocks US stock holdings — ticker, quantity, value in INR
get_gold Gold holdings (digital gold, SGBs, ETFs)
get_liquid Cash / savings — bank balances, FDs, EPF
get_credit_cards Credit card outstanding balances and due dates
get_loans Loan accounts and outstanding amounts
get_debt Debt instruments (bonds, NCDs, debt MFs)
get_credit_score Experian credit score, rating factors, active loans, and credit card limits
get_portfolio_summary Aggregated total invested, current value, P&L, asset allocation

Utilities

Tool Description
discover_endpoints Navigates dashboard pages and logs all live API URLs — useful if endpoints change

How it works

Claude ──STDIO JSON-RPC──► MCP Server (Python)
                                │
                    ┌───────────┴───────────┐
                    │                       │
              Session Manager         INDmoney Scraper
              (disk + AES-256-GCM)    (Playwright)
                    │                       │
              sessions/indmoney/       browser-data/indmoney/
              ├── session.json         (persistent browser profile
              └── cache/               with cookies + localStorage)
                  ├── holdings.json
                  └── ...

Authentication flow:

  1. Playwright launches a persistent Chromium context (keeps cookies/localStorage between runs)
  2. User completes OTP login manually in the browser window
  3. Server extracts the JWT from document.cookie (token cookie on www.indmoney.com)
  4. JWT is stored encrypted on disk; browser context preserves cookies for the lifetime of the session

Data fetching:

  • Most endpoints: page.evaluate(fetch(url, {Authorization: Bearer <jwt>})) — direct API call from the browser context (avoids CORS)
  • Some endpoints (gold, fallbacks): page.expect_response(predicate) while navigating to the relevant SPA page — captures the first matching network response

Configuration

Copy .env.example to .env and edit as needed:

cp .env.example .env
Variable Default Description
SESSION_ENCRYPTION_KEY (auto-generated) 32-byte hex key for AES-256-GCM
SESSION_TTL_HOURS 12 How long a session stays valid
CACHE_TTL_MINUTES 60 Disk cache TTL
IN_MEMORY_CACHE_TTL_MINUTES 5 In-memory cache TTL
API_REQUEST_TIMEOUT 10 Per-request timeout (seconds)
LOG_LEVEL INFO DEBUG, INFO, WARNING, ERROR
BROWSER_HEADLESS false Set true to hide the browser window

If SESSION_ENCRYPTION_KEY is empty, one is auto-generated and printed on first run. Copy it to .env to keep sessions valid across restarts.


Project structure

indmoney-mcp-python/
├── main.py                          # Entry point — STDIO MCP transport
├── pyproject.toml
├── .env.example
│
├── mcp_server/
│   ├── server.py                    # All 14 MCP tool handlers
│   ├── config.py                    # Config (env vars + paths)
│   ├── logger.py                    # stderr-only logger
│   │
│   ├── types/                       # Pydantic models
│   │   └── portfolio.py             # Holding, MutualFundHolding, CreditCardAccount, …
│   │
│   ├── adapters/indmoney/
│   │   ├── scraper.py               # Playwright fetch + page-nav interception
│   │   ├── endpoints.py             # All API URLs (Octopus, apixt-*, etc.)
│   │   ├── auth.py                  # OTP login flow
│   │   └── parser.py                # Raw API → Pydantic models
│   │
│   ├── session/
│   │   ├── manager.py               # SessionManager singleton
│   │   ├── store.py                 # Disk read/write
│   │   ├── crypto.py                # AES-256-GCM encrypt/decrypt
│   │   └── cache.py                 # Multi-level cache
│   │
│   ├── browser/
│   │   ├── manager.py               # Playwright context lifecycle
│   │   └── interceptor.py           # Network response interception
│   │
│   └── utils/
│       └── retry.py                 # Exponential backoff retry decorator
│
├── tests/
│   ├── conftest.py                  # Autouse fixture — isolates session dir per test
│   ├── test_integration_basic.py
│   ├── test_phase2_session_management.py
│   ├── test_phase3_browser_automation.py
│   └── test_phase4_scraper_and_parser.py
│
├── sessions/                        # GITIGNORED — encrypted session data
├── browser-data/                    # GITIGNORED — Playwright persistent profile
└── logs/                            # GITIGNORED — runtime logs

Development

# Activate venv
source venv/bin/activate

# Run tests
pytest tests/ -v

# Run with coverage
pytest --cov=mcp_server tests/

# Code quality
black mcp_server/
isort mcp_server/
flake8 mcp_server/

# Test server directly (no Claude needed)
python -c "
import asyncio
from mcp_server.server import INDmoneyMCPServer

async def main():
    s = INDmoneyMCPServer()
    r = await s._handle_broker_status({})
    print(r[0].text)

asyncio.run(main())
"

# Interactive tool testing
mcp dev main.py

Security

  • Encrypted at rest: Session tokens are encrypted with AES-256-GCM before being written to disk. The key lives only in .env (gitignored).
  • OTP stays in your browser: The OTP you type never passes through the MCP server — it goes directly from your keyboard to the INDmoney website.
  • Read-only: The server has no tools for placing orders, transferring funds, or modifying your account.
  • Local only: All data stays on your machine — nothing is sent to any third-party server.

ToS notice: Browser-based scraping may be against INDmoney's Terms of Service. Use responsibly and at your own risk.


Troubleshooting

See TROUBLESHOOTING.md for detailed solutions to common issues.

Quick fixes:

Symptom Fix
Server not showing in Claude Check absolute path in config; restart Claude fully
"not connected" after OTP Call broker_status — session may have saved after timeout
Tools return stale data Ask Claude to "clear cache and refresh"
Session deleted unexpectedly Never run pytest without the test isolation fixture
Gold returns nothing Your gold holding may already be in get_holdings (e.g., GOLDBEES ETF)

Contributing

  1. Fork the repo
  2. Create a feature branch: git checkout -b feature/my-thing
  3. Write tests for your changes
  4. Make sure pytest tests/ passes
  5. Open a pull request

All contributions welcome — new broker adapters, parser fixes, documentation improvements.


License

MIT — free to use, modify, and distribute.

Metadata

Release files for indmoney-mcp 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for indmoney-mcp 1.0.0
File Size Uploaded Provenance Actions
indmoney_mcp-1.0.0.tar.gz 59.5 kB Without provenance Details for indmoney_mcp-1.0.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for indmoney-mcp 1.0.0
File Interpreter ABI Platform Actions
indmoney_mcp-1.0.0-py3-none-any.whl Python 3 none any Details for indmoney_mcp-1.0.0-py3-none-any.whl

Total release size: 113.7 kB

Release files / indmoney_mcp-1.0.0.tar.gz

Download URL indmoney_mcp-1.0.0.tar.gz
Size 59.5 kB
Tags Source
SHA-256 checksum
How to use checksums
f8861e4def763413987a53719b2429bb4dbf66584561fd04fa67b228f736eae5
BLAKE2b-256 checksum
How to use checksums
a500630124d16ec75c11da32fd60063c1554c3db40b54ae8539481ce9353ebff
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.4

Release files / indmoney_mcp-1.0.0-py3-none-any.whl

Download URL indmoney_mcp-1.0.0-py3-none-any.whl
Size 54.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b4ee3440c13adeb827f9e26c284838c76cf61617bf6d78277de0603654bff3b8
BLAKE2b-256 checksum
How to use checksums
5bbe2fa341bad272b36079c983ea4fa525a362d5bd3118b5aeb9740c9f443a51
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.4

Security for indmoney-mcp 1.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page