Finance Intelligence MCP Server
by menlopy
README.md
# Finance Intelligence MCP Server
[](https://www.python.org/downloads/)
[](LICENSE)
[](https://github.com/astral-sh/ruff)
[](http://mypy-lang.org/)
A production-grade, asynchronous Model Context Protocol (MCP) server that grants AI assistants (Claude Desktop, Cursor, ChatGPT, VS Code, etc.) access to real-time financial market data, company metrics, and history.
Powered by **FastMCP**, **yfinance**, and **Pydantic**, this server uses advanced thread-offloading, caching, and robust error isolation to provide standard JSON-RPC tools with zero crashes.
---
## Architecture Overview
```
+--------------------------------------+
| LLM Client (e.g. Claude Desktop) |
+------------------+-------------------+
|
| (JSON-RPC over stdio / SSE)
v
+------------------+-------------------+
| Finance Intelligence MCP |
| |
| +------------------------------+ |
| | server.py | |
| +--------------+---------------+ |
| | |
| v |
| +------------------------------+ |
| | tools (stocks / companies) | |
| +--------------+---------------+ |
| | |
| v |
| +------------------------------+ |
| | clients/yahoo.py | |
| | (Thread Pool & TTL Cache) | |
| +--------------+---------------+ |
+------------------|-------------------+
|
v (asyncio.to_thread)
+------------------+-------------------+
| Yahoo Finance Service |
+--------------------------------------+
```
### Key Design Decisions
1. **Async Thread Pool Execution**
`yfinance` is fundamentally a blocking synchronous library. Directly calling it in async tool handlers would block the event loop, freezing the MCP server. We offload every `yfinance` call to a thread pool via `asyncio.to_thread`.
2. **In-Memory TTL Caching**
To prevent Yahoo Finance rate limits and reduce tool latency during conversational loops, we implement a thread-safe, in-memory cache with a configurable TTL (default: 5 minutes) for ticker info and history query responses.
3. **Safe Log Handling**
Stdout (`sys.stdout`) is strictly reserved for the MCP JSON-RPC protocol transport. Standard logs are redirected entirely to stderr (`sys.stderr`) using a custom structured logger to prevent channel corruption.
4. **Crash-Resilient Tool Handlers**
Every tool is wrapped in strict try-except blocks. Instead of crashing the server, exceptions (e.g., TickerNotFound, network timeouts) are caught, logged, and returned as structured JSON error responses.
---
## Features & Available MCP Tools
The server exposes 5 standardized tools:
| Tool Name | Parameters | Description | Returns |
| :--- | :--- | :--- | :--- |
| `search_company` | `query: str` | Search for matching company names, tickers, and exchanges | JSON array of results |
| `get_stock_price` | `symbol: str` | Retrieve real-time pricing and basic exchange details | Current price, state, currency, time |
| `get_stock_info` | `symbol: str` | Retrieve key fundamentals, stats, and company info | Market cap, P/E, beta, dividend yield, etc. |
| `compare_companies` | `symbol1: str`, `symbol2: str` | Side-by-side metric comparison of two tickers | Structured comparative matrix |
| `get_stock_history` | `symbol: str`, `period: str` | Download historical prices (1d, 5d, 1mo, 3mo, 6mo, 1y, 5y, max) | Chronological price records |
---
## Installation
### Prerequisites
- Python 3.12 or newer
- Virtual Environment or `uv` package manager
### Standard Setup
1. **Clone the repository:**
```bash
git clone https://github.com/yourusername/finance-intelligence-mcp.git
cd finance-intelligence-mcp
```
2. **Create a virtual environment and install dependencies:**
```bash
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -e ".[dev]"
```
3. **Configure the environment:**
Create a `.env` file from the example:
```bash
cp .env.example .env
```
*(Adjust values like `CACHE_TTL_SECONDS` or `LOG_LEVEL` if needed.)*
---
## Usage
### Running Locally
To run the server in the default **stdio** mode (which local clients like Claude Desktop use):
```bash
python -m src.main
```
To run the server in **SSE (HTTP)** mode:
```bash
python -m src.main --transport sse --port 8000
```
---
## Client Integration Configurations
### 1. Claude Desktop Configuration
Add the following to your Claude Desktop configuration file (typically at `~/Library/Application Support/Claude/claude_desktop_config.json` on macOS or `%APPDATA%\Claude\claude_desktop_config.json` on Windows):
#### Standard Execution (Python Venv):
```json
{
"mcpServers": {
"finance-intelligence": {
"command": "/Users/YOUR_USER/Desktop/finance mcp/.venv/bin/python",
"args": [
"-m",
"src.main"
],
"env": {
"LOG_LEVEL": "INFO",
"CACHE_TTL_SECONDS": "300"
}
}
}
}
```
#### Docker Execution:
```json
{
"mcpServers": {
"finance-intelligence-docker": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"finance-intelligence-mcp:latest"
]
}
}
}
```
### 2. Cursor Configuration
To add the server to Cursor:
1. Open Cursor Settings -> Features -> **MCP**.
2. Click **+ Add New MCP Server**.
3. Fill out the fields:
- **Name**: `Finance Intelligence`
- **Type**: `command`
- **Command**: `/path/to/project/.venv/bin/python -m src.main`
---
## Docker Containerization
1. **Build the image:**
```bash
docker build -t finance-intelligence-mcp:latest .
```
2. **Run the image locally in stdio mode:**
```bash
docker run -i --rm finance-intelligence-mcp:latest
```
3. **Run the image locally in HTTP/SSE mode:**
```bash
docker run -d -p 8000:8000 --name finance-mcp finance-intelligence-mcp:latest --transport sse --port 8000
```
---
## Example Prompts
Here are some prompt examples you can ask your AI model once the server is connected:
- **Search**: *"Find the stock ticker for Nvidia."* -> Triggers `search_company(query="Nvidia")`
- **Price**: *"What is the current stock price and market state of Apple (AAPL)?"* -> Triggers `get_stock_price(symbol="AAPL")`
- **Info**: *"Show me the key financials for Microsoft, including market cap, beta, and P/E ratio."* -> Triggers `get_stock_info(symbol="MSFT")`
- **Comparison**: *"Compare Apple and Microsoft stocks side by side."* -> Triggers `compare_companies(symbol1="AAPL", symbol2="MSFT")`
- **History**: *"Analyze the historical performance of Tesla (TSLA) over the past month."* -> Triggers `get_stock_history(symbol="TSLA", period="1mo")`
---
## Quality & Testing
We enforce code quality through automated checks.
### Run Tests
```bash
pytest tests/ -v
```
### Run Linter
```bash
ruff check src/ tests/
```
### Run Type Checker
```bash
mypy src/
```
---
## Roadmap
## Roadmap
- [x] Stock prices
- [x] Company information
- [x] Stock comparison
- [ ] Financial statements
- [ ] Crypto support
- [ ] Macroeconomic indicators
- [ ] Portfolio analysis
- [ ] DCF valuation
---
## Contributing
Contributions are welcome! Please open an issue or submit a pull request with any suggestions or improvements. Make sure to run the formatting and test suite before submitting code.
---
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues