MyFinanceMCP
Sends personalised daily portfolio briefings with per-stock signals and LLM-written summaries to users via WhatsApp.
Click on "Install 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., "@MyFinanceMCPget my daily portfolio briefing"
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.
MyFinanceMCP — Angel One Portfolio Tracker
A multi-user MCP server and web dashboard for tracking your Angel One portfolio, with AI-powered daily briefings, a trading agent, and ML-based price predictions.
Features
MCP Server (SSE transport) — connect from Cursor, Claude Desktop, or any MCP-compatible client
Web Dashboard — browser-based portfolio viewer with login, holdings, positions, orders, and P&L pages
Finance ADK Agent — chat with the Google ADK finance assistant (Angel One + research tools) via the Agent tab. Requires
OPENROUTER_API_KEYon the serverTrading ADK Agent — risk-aware, proposal-based order execution agent. Analyses prices and technicals; proposes trades but never places orders without explicit approval
Daily Briefing Scheduler — automatically sends a WhatsApp message each day with per-stock signals (green/yellow/red), LightGBM predictions, and an LLM-written summary of your portfolio
ML Price Prediction — LightGBM model predicts price direction across 7 timeframes (10 min → 1 year) using technical indicators, price-action features, and sentiment
Admin API — REST endpoints (
/api/admin/*) for registering premium users with Fernet-encrypted Angel credentials and managing their schedulesMulti-user — each session authenticates with its own Angel One credentials; premium users' credentials are stored encrypted in Postgres
Zero plaintext credential storage — transient sessions live only in RAM; premium user credentials are encrypted at rest with a Fernet key
Related MCP server: groww-mcp
Project Structure
├── main.py # Combined entry point (MCP + Web on one port)
├── mcp_server.py # MCP FastMCP app (tools: login, portfolio, trading)
├── web_app.py # FastAPI web dashboard + briefing schedule API
├── angel_client.py # Angel One SmartAPI client wrapper
├── session_manager.py # Per-session client management (in-memory)
│
├── db/ # Postgres layer (SQLModel + Neon)
│ ├── engine.py # Engine, init_db, additive column migrations
│ ├── models.py # User, Schedule, Log tables
│ ├── crypto.py # Fernet encrypt/decrypt for stored credentials
│ └── __init__.py
│
├── adminApi/ # Admin REST API (X-Admin-Key protected)
│ ├── router.py # /api/admin/users, /api/admin/schedules, /api/admin/logs
│ └── __init__.py
│
├── agents/ # Google ADK agents
│ ├── factory.py # LlmAgent builder (OpenRouter via LiteLLM)
│ ├── finance/ # Finance research agent
│ └── trading/ # Proposal-based trading agent
│
├── services/ # Domain logic
│ ├── schedular/ # Scheduler pipeline
│ │ ├── runner.py # APScheduler tick (every 1 min)
│ │ ├── repository.py # DB claim / finish (FOR UPDATE SKIP LOCKED)
│ │ ├── job_executor.py # Per-schedule pipeline (session → briefing → WhatsApp)
│ │ ├── daily_briefing.py # LLM briefing generation (holdings + candles + LightGBM)
│ │ └── whatsapp.py # WhatsApp delivery via webhook
│ ├── prediction_service.py # LightGBM price-direction predictions
│ ├── ai_service.py # OpenRouter AI helpers
│ ├── technical_service.py # RSI, MACD, Bollinger, SMA, volume signals
│ ├── fundamental_service.py # Fundamental data
│ ├── sentiment_service.py # News sentiment scoring
│ ├── sector_service.py # Sectoral analysis
│ ├── news_service.py # News fetching
│ ├── risk_profile.py # User risk profile
│ ├── trade_proposals.py # In-memory proposal store for trading agent
│ └── realtime_feed.py # Real-time price feed
│
├── integrations/ # Adapters bridging sessions ↔ MCP / local accounts
├── models/ # LightGBM model training scripts
├── frontend/ # Jinja2 templates and static assets (CSS, JS)
├── data/ # JSON data files served under /static/data
├── requirements.txt # Python dependencies
├── Dockerfile # Container definition
└── .env.example # Environment variable templateArchitecture
One process (main.py) mounts the MCP app under /mcp and the FastAPI web app at / on a single Uvicorn port. The scheduler runs inside the same process (APScheduler async) when SCHEDULER_ENABLED=1.
flowchart TB
subgraph clients [Clients]
Browser[Web browser]
MCPClient[MCP client e.g. Cursor]
WhatsApp[WhatsApp ← user's phone]
end
subgraph server [MyFinanceMCP process]
Starlette[Starlette / Uvicorn]
Web[FastAPI web_app]
MCP[mcp_server FastMCP SSE]
Admin[adminApi router]
SM[session_manager in-memory]
FinanceADK[Finance ADK agent]
TradingADK[Trading ADK agent]
Scheduler[APScheduler tick 1 min]
AngelWrap[angel_client AngelOneClient]
end
subgraph db [Postgres / Neon]
Users[users encrypted creds]
Schedules[schedules next_run status]
Logs[logs run history]
end
subgraph external [External services]
AngelAPI[Angel One SmartAPI]
OR[OpenRouter API]
WAHook[WhatsApp webhook service]
Other[yfinance gnews NSE data etc.]
end
Browser -->|HTTPS session cookie| Starlette
MCPClient -->|SSE /mcp/sse| Starlette
Starlette --> Web
Starlette --> MCP
Web --> Admin
Web --> SM
Web --> FinanceADK
Web --> TradingADK
MCP --> SM
SM --> AngelWrap
AngelWrap --> AngelAPI
FinanceADK --> OR
TradingADK --> OR
Web --> Other
Admin --> db
Scheduler --> db
Scheduler -->|run_one| AngelWrap
Scheduler -->|send| WAHook
WAHook --> WhatsAppRequest paths
Path | Purpose |
| Jinja pages + static assets |
| JSON for dashboard, news, research, |
| MCP over SSE ( |
| Swagger UI (FastAPI auto-generated) |
Session flows
Web login: Browser posts Angel credentials → server creates an
AngelOneClientin memory and stores an opaquesidin a signed session cookie.Daily briefing: Scheduler ticks every minute → queries
schedulesfor rows wherenext_run <= now()→ claims them withFOR UPDATE SKIP LOCKED→ for each claimed schedule: decrypts credentials fromusers, creates an ephemeral Angel session, generates the briefing, sends WhatsApp, writes tologs, and armsnext_run.MCP: Client calls the
logintool; session stored under a key derived from the MCP connection (id(ctx.session)). Web and MCP logins are separate unless bridged explicitly.
Getting Your Angel One API Credentials
You need 4 credentials from the Angel One SmartAPI portal:
https://smartapi.angelbroking.com/signin
Credential | How to get it |
API Key | SmartAPI → My Apps → Create App → copy the API Key |
Client ID | Your Angel One account ID (e.g. |
PIN | The 4-digit trading PIN you use to log into Angel One |
TOTP Secret | SmartAPI → My Profile → Enable TOTP → copy the Base32 secret key |
Note: The TOTP secret is only shown once when you enable it. Save it immediately.
Run Locally
1. Create a virtual environment
python3 -m venv .venv
source .venv/bin/activate # macOS / Linux
# .venv\Scripts\activate # Windows2. Install dependencies
pip install -r requirements.txt3. Set up Postgres
The scheduler and admin API require a Postgres database. The easiest option for development is a free Neon database. Tables are created automatically on first startup via init_db().
4. Configure environment variables
cp .env.example .envEdit .env with your values:
Variable | Required | Description |
| For ADK CLI only | Bootstrap credentials for local ADK agent testing |
| For ADK CLI only | See above |
| For ADK CLI only | See above |
| For ADK CLI only | See above |
| Yes (for Agent/Trading/Briefing) | Server-side LLM key |
| Yes | Postgres connection string (e.g. Neon pooler URL with |
| Yes | Fernet key for encrypting Angel credentials in DB. Generate with: |
| Yes | Static key protecting all |
| Yes (for briefings) | Set to |
| Recommended | Signs session cookies. Random key generated on each restart if unset (invalidates existing cookies) |
Note on two OpenRouter keys: The server
OPENROUTER_API_KEYis used by the ADK agents and the daily briefing pipeline. There is a separate optional per-browser OpenRouter key for Dashboard → AI Insights / Ask AI (/api/ai/*) — that is stored only in the browser and never sent to the server's env.
Scaling note: The ADK integration uses in-memory runners in the same process. Use a single Uvicorn worker (the default with python main.py) so chat state and Angel sessions stay consistent.
5. Start the server
python main.pyThe server starts on http://localhost:8000:
Web dashboard:
http://localhost:8000/Swagger UI:
http://localhost:8000/docsMCP SSE endpoint:
http://localhost:8000/mcp/sse
Daily Briefing Scheduler
The scheduler sends a personalised WhatsApp message to each premium user at their configured time each day. The message includes:
Per-stock signals (🟢 / 🟡 / 🔴) with price and % changes
LightGBM 1-day and 1-week direction predictions
An LLM-written portfolio summary via OpenRouter
How to set it up
Create a user via the Admin API (see below).
Set a schedule — log in as that user and go to the Trading tab → Daily Briefing, or call
POST /api/briefing/schedulewith{"time_ist": "08:30"}.Ensure
SCHEDULER_ENABLED=1in your environment and restart.
How it works internally
APScheduler tick (every 1 min)
└── repository.claim_due_schedules() ← SQL: next_run <= now(), FOR UPDATE SKIP LOCKED
└── job_executor.run_one(claim)
├── Load user + decrypt credentials (Fernet)
├── Create ephemeral Angel session
├── generate_daily_briefing() ← holdings + candles + LightGBM + LLM
├── whatsapp.send() ← POST to webhook service
├── Write Log row
└── finish_schedule() ← advance next_run by interval_minutesAdmin API
All endpoints require the X-Admin-Key: <your ADMIN_API_KEY> header. Browse to /docs for interactive Swagger UI.
Endpoint | Method | Description |
| GET | List all registered users |
| POST | Create a user (encrypts password + TOTP before storing) |
| GET | Get a single user |
| DELETE | Deactivate a user |
| GET | List all schedules |
| POST | Create a schedule for a user |
| GET | Get a single schedule |
| PATCH | Update schedule (enable/disable, interval, next_run) |
| DELETE | Delete a schedule |
| GET | Recent scheduler run logs (filterable by user_id) |
Example: register a user
curl -X POST http://localhost:8000/api/admin/users \
-H "X-Admin-Key: admin123" \
-H "Content-Type: application/json" \
-d '{
"whatsapp_number": "918107037133",
"angel_api_key": "Z0hsKZYf",
"angel_client_id": "PPSU16696",
"angel_password": "8107",
"angel_totp_secret": "FP4O3EVUYXZ5Q3WTF6I7JR772Y"
}'Connect from an MCP Client
Cursor
Add to your .cursor/mcp.json:
{
"mcpServers": {
"angelone-portfolio": {
"url": "http://localhost:8000/mcp/sse"
}
}
}Then call the login tool with your Angel One credentials to start a session.
Claude Desktop
Add to your claude_desktop_config.json:
{
"mcpServers": {
"angelone-portfolio": {
"command": "npx",
"args": ["-y", "mcp-remote", "http://localhost:8000/mcp/sse"]
}
}
}ChatGPT Desktop
Go to Settings → Beta features → MCP Servers → Add Server and enter:
Command:
npxArguments:
-y mcp-remote http://localhost:8000/mcp/sse
Available MCP Tools
Tool | Description |
| Authenticate with Angel One (must call first) |
| Discard session credentials |
| Account profile |
| Stock holdings with P&L |
| Complete holdings overview |
| Open positions |
| Today's orders |
| Executed trades |
| Account funds / margin |
| Last traded price |
| Search stocks by name |
| High-level portfolio summary |
| Historical OHLC data |
| Place a new order |
| Modify an existing order |
| Cancel an order |
Deploy to Railway (Recommended)
Push this repo to GitHub
Go to railway.app and create a new project
Connect your GitHub repository
Railway auto-detects the Dockerfile and deploys
Set the following environment variables in Railway:
DATABASE_URL(Postgres connection string)ENCRYPTION_KEYADMIN_API_KEYOPENROUTER_API_KEYSCHEDULER_ENABLED=1SESSION_SECRET
Get your public URL (e.g.
https://myfinancemcp.up.railway.app)
After Deployment
Web users: Visit https://your-app.up.railway.app and log in with Angel One credentials.
MCP users: Update the url in your MCP client config:
{
"mcpServers": {
"angelone-portfolio": {
"url": "https://your-app.up.railway.app/mcp/sse"
}
}
}Deploy to Render (Free Tier)
Push to GitHub
Go to render.com, create a new Web Service
Connect your repo, select Docker as the runtime
Set all required environment variables (same list as Railway above)
Deploy
Note: Render free tier spins down after inactivity. The scheduler resumes when the service wakes up, but will immediately fire all overdue schedules on the next tick.
Security
What lives where
Location | What is stored | Notes |
Server memory | Transient | Not written to DB; cleared on logout, session expiry (~8 hours), or process restart |
Postgres DB | Premium | Encrypted with Fernet ( |
Server |
| Protect the host and use a secrets manager in production |
Signed session cookie | Opaque | Signed with |
Server memory (ADK) |
| Lost on restart. Use a single Uvicorn worker |
Browser | Optional encrypted OpenRouter key for Dashboard → AI Insights only | Not used by |
Browser (typical) | No Angel credentials after login | Sent once over HTTPS at login; session cookie identifies the server-side session |
Practices reflected in the app
Transient Angel credentials are never persisted by the application; they live in RAM for the session lifetime.
Stored premium credentials are Fernet-encrypted at rest; the raw values are only decrypted in the scheduler worker for the duration of a briefing run and then discarded.
Web-backed Angel sessions expire after 8 hours (
SESSION_TTL_SECONDSinsession_manager.py).The
FOR UPDATE SKIP LOCKEDpattern inrepository.pymakes the scheduler safe to run across multiple replicas, though only one process should haveSCHEDULER_ENABLED=1.Terminate TLS at the edge for public deployments (Railway, Render, etc.).
Operational cautions
Lock down
.env(file permissions, no commits) and use platform secret stores in production.Dashboard "Save OpenRouter key" keeps ciphertext in
localStorage— treat the device as trusted.Provider rate limits (Angel, OpenRouter, news APIs) still apply; heavy polling can trigger throttling.
The TOTP secret stored in the DB allows the scheduler to generate TOTP codes autonomously. Treat it with the same sensitivity as a password.
License
MIT
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/raghav18482/MyFinancesMCP'
If you have feedback or need assistance with the MCP directory API, please join our Discord server