loading…
Search for a command to run...
loading…
Read-only INDmoney portfolio access for Claude — Indian stocks, mutual funds, US stocks, gold, credit cards, loans, and Experian credit score. OTP browser login
Read-only INDmoney portfolio access for Claude — Indian stocks, mutual funds, US stocks, gold, credit cards, loans, and Experian credit score. OTP browser login with AES-256-GCM encrypted sessions.
PyPI PyPI Downloads MCP Badge Glama License: MIT
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.
Once connected, you can ask things like:
| 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 |
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
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
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 justpython.
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 |
{
"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
envblock, you can copy.env.exampleto.envin the project root and set values there. Both approaches work — the Claude configenvblock takes precedence over.envif the same key appears in both.
Quit completely and reopen. The indmoney server should appear in Settings → MCP Servers.
In Claude, say:
Connect me to INDmoney
Claude will:
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_statusafterward to confirm.
| 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 |
| 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 |
| Tool | Description |
|---|---|
discover_endpoints |
Navigates dashboard pages and logs all live API URLs — useful if endpoints change |
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:
document.cookie (token cookie on www.indmoney.com)Data fetching:
page.evaluate(fetch(url, {Authorization: Bearer <jwt>})) — direct API call from the browser context (avoids CORS)page.expect_response(predicate) while navigating to the relevant SPA page — captures the first matching network responseCopy .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_KEYis empty, one is auto-generated and printed on first run. Copy it to.envto keep sessions valid across restarts.
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
# 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
.env (gitignored).ToS notice: Browser-based scraping may be against INDmoney's Terms of Service. Use responsibly and at your own risk.
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) |
git checkout -b feature/my-thingpytest tests/ passesAll contributions welcome — new broker adapters, parser fixes, documentation improvements.
| Platform | Link |
|---|---|
| 📦 PyPI | pypi.org/project/indmoney-mcp |
| 🤖 LobeHub MCP Marketplace | lobehub.com/mcp/vickys-ai-stuffs-indmoney-mcp-python |
| ✨ Glama MCP Registry | glama.ai/mcp/servers/VIckys-AI-Stuffs/indmoney-mcp-python |
| ⭐ awesome-mcp-servers | github.com/punkpeye/awesome-mcp-servers — Finance & Fintech section |
| 📝 Dev.to Blog | I Built an MCP Server for INDmoney |
| 📰 Medium Blog | INDmoney is Great |
MIT — free to use, modify, and distribute.
Выполни в терминале:
claude mcp add indmoney-mcp -- npx Безопасность
Низкий рискАвтоматическая эвристика по публичным данным — не гарантия безопасности.