Financial Context Engine
An MCP server that exposes personal financial data — transaction ledger, portfolio holdings, live/historical market prices, and quantitative risk metrics — as standardized tools, resources, and prompts, enabling natural language reasoning over real computed numbers.
README
Financial Context Engine
An MCP (Model Context Protocol) server that exposes personal financial data — transaction ledger, portfolio holdings, live/historical market prices, and quantitative risk metrics — as standardized Tools, Resources, and Prompts. Any MCP host (Claude Desktop, Claude.ai, Cursor) can connect to it and reason over real, deterministically computed numbers instead of estimating them.
This project is 100% pure Python. It runs natively on Windows — no WSL, no Docker, no Linux subsystem required. DuckDB, FastMCP, numpy/pandas, and yfinance are all pip-installable packages with native Windows wheels.
Architecture
┌──────────────────────────────────────────────┐
│ MCP HOST (Claude Desktop, etc.) │
└────────────────────┬───────────────────────────┘
│ MCP protocol (stdio)
┌────────────────────▼───────────────────────────┐
│ FINANCIAL CONTEXT ENGINE (this repo) │
│ ┌───────────┐ ┌────────────┐ ┌──────────────┐ │
│ │ RESOURCES │ │ TOOLS │ │ PROMPTS │ │
│ └─────┬─────┘ └─────┬──────┘ └──────┬───────┘ │
└────────┼─────────────┼───────────────┼──────────┘
│ │ │
┌────────▼─────────────▼───────────────▼──────────┐
│ DuckDB │ Rate Limiter + yfinance │ Quant │
│ (local) │ (token bucket, cached) │ (numpy) │
└───────────────────────────────────────────────────┘
No LLM lives inside this server. It's a data + compute backend that any MCP-compatible chat client connects to.
Setup on Windows (VS Code, no WSL)
1. Install Python
Python 3.11+ from python.org (check "Add to PATH" during install). Verify in a regular Windows PowerShell or VS Code terminal (not WSL):
python --version
2. Open the project folder in VS Code
File > Open Folder... → select the financial-context-engine folder.
3. Create a virtual environment
In the VS Code terminal (make sure it's PowerShell or Command Prompt, not a WSL terminal — check the terminal dropdown in the top-right of the terminal panel):
python -m venv .venv
.venv\Scripts\activate
Your prompt should now show (.venv). If PowerShell blocks the activation script with an execution-policy error, run this once (you've hit this before with other projects):
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
4. Install dependencies
pip install -r requirements.txt
5. Copy the environment template
copy .env.example .env
Defaults work out of the box (in-memory rate limiting, no Redis needed). Only edit .env if you want an Alpha Vantage API key or Redis-backed rate limiting later.
6. Seed demo data
python -m db.seed
This creates data/finance.duckdb with ~6 months of synthetic transactions and 7 sample holdings — safe to demo, no real financial data involved.
7. Run the full test suite
pytest tests/ -v
You should see 33 passed.
8. Run the server in MCP Inspector (interactive dev mode)
fastmcp dev server.py
This opens a browser-based inspector where you can call every tool and view every resource manually — no LLM needed, no config files needed. This is the fastest way to confirm everything works after any change.
Connecting to Claude Desktop
Once you've verified the server works in MCP Inspector, add it to Claude Desktop's config so you can chat with it directly.
- Open Claude Desktop → Settings → Developer → Edit Config (or find
claude_desktop_config.jsondirectly — on Windows it's usually at%APPDATA%\Claude\claude_desktop_config.json). - Add an entry (use the full absolute Windows path to your project and to the venv's python.exe):
{
"mcpServers": {
"financial-context-engine": {
"command": "C:\\path\\to\\financial-context-engine\\.venv\\Scripts\\python.exe",
"args": ["C:\\path\\to\\financial-context-engine\\server.py"]
}
}
}
- Restart Claude Desktop. You should see a 🔨 tools icon indicating the server connected — try asking: "What's my current net worth?" or "Compute my portfolio's Sharpe ratio."
Project Structure
financial-context-engine/
├── server.py # MCP server entrypoint — run this
├── db/
│ ├── schema.sql # DuckDB table definitions
│ ├── models.py # Pydantic models (typed, shared everywhere)
│ ├── store.py # LedgerStore — the only module that touches SQL
│ └── seed.py # generates synthetic demo data
├── market/
│ ├── rate_limiter.py # token bucket (in-memory + Redis modes)
│ ├── client.py # yfinance wrapper: cache -> rate limiter -> fetch
│ ├── history.py # historical price fetching for quant calcs
│ └── demo.py # standalone script proving the limiter works
├── analytics/
│ └── quant.py # Sharpe, Monte Carlo VaR, correlation, HHI — pure numpy
├── mcpapp/ # (named mcpapp, not mcp, to avoid shadowing the MCP SDK)
│ ├── context.py # wires store + rate limiter + market client together
│ ├── tools.py # @mcp.tool() definitions
│ ├── resources.py # @mcp.resource() definitions
│ ├── prompts.py # @mcp.prompt() definitions
│ └── stream.py # background polling for "live" prices
└── tests/ # 33 tests across every module above
What Each Tool Does
| Tool | Purpose |
|---|---|
get_market_quote(symbols) |
Current price/P-E/52-week range, rate-limited + cached |
query_ledger(category, start_date, min_amount) |
Filter transaction history |
get_recent_transactions(days) |
Last N days of transactions |
get_net_worth() |
Cash + invested totals, per-account breakdown |
compute_portfolio_health_report() |
Sharpe ratio, Monte Carlo VaR (95%/99%, 1-day/1-month), correlation matrix, concentration (HHI) — all computed in Python, not estimated by the model |
get_live_prices() |
Latest background-polled prices for your holdings |
get_rebalance_suggestions(target_allocation) |
Dollar-value buy/sell suggestions vs. a target allocation |
What Each Resource Exposes
| Resource URI | Content |
|---|---|
finance://summary |
Net worth snapshot |
finance://transactions/recent |
Last 30 days of transactions |
finance://portfolio/holdings |
Current holdings |
finance://portfolio/live |
Background-polled live prices |
finance://api-usage |
Rate limiter decision log (allowed/blocked/cached) — transparency into throttling |
Design Notes
Why deterministic Python math instead of letting the LLM calculate? LLMs are unreliable at multi-step arithmetic, especially statistics like Sharpe ratio or Value-at-Risk where a small error compounds. Every number this server returns is computed by numpy/pandas from real data, so the model's job is reasoning and communication, not arithmetic.
Why rate-limit market data calls? Free-tier providers (yfinance's soft limits, Alpha Vantage's 25 calls/day) get exhausted fast if an LLM calls them on every message. The token-bucket limiter (reused from a standalone Distributed Rate Limiter project) plus a 60-second TTL cache keeps usage sane — see market/demo.py for a runnable proof: 50 rapid requests → 5 fetched, 30 cache hits, 15 correctly throttled.
Why polling instead of true SSE push for "live" prices? True MCP resource-subscription push depends on transport/session details that vary across FastMCP versions and host clients, and is genuinely fragile to get right without a Linux dev environment. A background-thread poller (mcpapp/stream.py) is the reliable choice here — it reads from the same rate-limited, cached client, so it never floods the market data provider even while "live." If you later deploy this on Linux/Codespaces, the polling loop can be swapped for mcp.send_resource_updated() calls without touching the state management.
Security & privacy:
- All credentials load from
.env(gitignored), never logged, never returned in tool output. data/finance.duckdbis local-only and gitignored — nothing syncs to the cloud.- The only outbound network calls are to the market data provider (ticker symbol only, no personal data).
- Redis mode (for shared rate-limiting across multiple server instances) is opt-in via
.env, not required for normal use.
Running Individual Test Files
pytest tests/test_store.py -v # data layer (6 tests)
pytest tests/test_rate_limiter.py -v # token bucket (6 tests)
pytest tests/test_market_client.py -v # market data + cache (5 tests)
pytest tests/test_quant.py -v # Sharpe/VaR/correlation (10 tests)
pytest tests/test_stream.py -v # live price polling (3 tests)
pytest tests/test_tools.py -v # MCP tool logic (3 tests)
python -m tests.smoke_test # end-to-end, no pytest needed
python -m market.demo # rate limiter demo output
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。