The Model Context Protocol (MCP) enables seamless integration of contextual data into AI tools like Claude Desktop, enhancing their capabilities. In this guide, we'll walk through creating an MCP server using the fastapi-mcp package, integrated with FastAPI, to serve stock analysis endpoints. We'll use code from a stock analysis project, set up Claude Desktop on Windows, and demonstrate how to use the server with an example using the stock ACB
Table of Contents
- Introduction
- Setting Up the Environment
- Installing and Configuring Claude Desktop on Windows
- Building the FastAPI Application
- Integrating fastapi-mcp
- Configuring the Client
- Running the Server
- Example Usage and Results
- Using with Claude Desktop
- Conclusion
- References
Introduction
MCP servers provide structured data to AI models, making them more context-aware. The fastapi-mcp package extends FastAPI to support MCP, simplifying server creation. We'll build an MCP server based on the provided code from the Stock Price for Fun repository, expose stock analysis endpoints, and connect it to Claude Desktop on Windows.
Setting Up the Environment
Prepare your development environment with these steps:
Install Python: Ensure Python 3.7+ is installed. Download from python.org.
Install uv: The provided README uses
uv
for package management. Install it with:
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
set Path=%USERPROFILE%\.local\bin;%Path%
uv tool install mcp-proxy
This installs uv
and mcp-proxy
, which proxies MCP requests.
-
Install Dependencies: Install required packages using
uv
orpip
:
uv pip install fastapi uvicorn fastapi-mcp pydantic pyyaml
Or with pip
:
pip install fastapi uvicorn fastapi-mcp pydantic pyyaml
-
fastapi
: Web framework for the API. -
uvicorn
: ASGI server to run the app. -
fastapi-mcp
: MCP integration for FastAPI. -
pydantic
,pyyaml
: For data validation and config parsing.
Note: The stock analysis code requires additional dependencies (e.g., for PayBackTime
, Stock
). Refer to the Stock Price for Fun repo for a full list or setup a requirements.txt
.
- Project Structure: Organize your project as follows:
project_root/
├── config/
│ ├── config.yaml
├── src/
│ ├── api.py
│ ├── apis/
│ │ ├── stock_apis.py
│ ├── Utils/
│ │ ├── utils.py
Ensure config.yaml
exists with settings like:
api_host: 0.0.0.0
api_port: 8668
asset_data_path: path/to/asset/data
pbt_params: [5, 20] # Example: report_range, window_size
motif_data_path: path/to/motif/data
buy_sell_df_path: path/to/buy_sell/data
win_loss_df_path: path/to/win_loss/data
Installing and Configuring Claude Desktop on Windows
To use the MCP server with Claude Desktop:
- Download Claude Desktop:
- Visit Anthropic’s website or the official Claude Desktop download page.
- Download the Windows installer (
.exe
or.msi
). - Run the installer, follow prompts, and accept the license agreement.
- Launch Claude Desktop:
- Open Claude Desktop from the Start menu or desktop shortcut.
- Sign in with your Anthropic account. If you don’t have one, create an account at Anthropic.
- Configure MCP Settings:
Locate the configuration file at
C:\Users\
.\AppData\Roaming\Claude\claude_desktop_config.json If it doesn’t exist, create it.
-
Add the MCP server configuration as per the README:
{ "mcpServers": { "filesystem": { "command": "npx", "args": [ "-y", "@modelcontextprotocol/server-filesystem", "C:\\Users\\
\\Desktop", "C:\\Users\\ \\Downloads", "D:\\" ] } } Save the file.
Ensure
mcp-proxy
is installed (viauv tool install mcp-proxy
or equivalent).
- Verify Claude Desktop:
- Restart Claude Desktop to load the new configuration.
- Check if Claude recognizes the MCP server (this may depend on Claude’s UI; consult Anthropic’s documentation for details).
Building the FastAPI Application
Use the provided src/api.py
to create the FastAPI application:
import sys
sys.path.append("")
from fastapi import FastAPI
import uvicorn
from fastapi_mcp import FastApiMCP
from src.apis.stock_apis import router as stocks_router
from src.apis.mcp_apis import router as mcp_router
from src.Utils.utils import config_parser
app = FastAPI(title="Stock Bot API", description="API for stock analysis and control panel operations")
# Include routers
app.include_router(stocks_router)
app.include_router(mcp_router)
# Read configuration
data = config_parser(data_config_path='config/config.yaml')
# Add MCP server to the FastAPI app
mcp = FastApiMCP(
app,
name="Item API MCP",
description="MCP server for the Item API",
base_url="http://localhost:8668",
)
mcp.mount()
mcp.setup_server()
if __name__ == "__main__":
host = data.get('api_host', '0.0.0.0')
port = data.get('api_port', 8000)
uvicorn.run(app, host=host, port=port)
And src/apis/stock_apis.py
for stock analysis endpoints (abridged for brevity, full code as provided):
import sys
sys.path.append("")
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel
from typing import List, Dict, Any
import os
from src.PayBackTime import PayBackTime, find_PBT_stocks
from src.stock_class import Stock
from src.motif import MotifMatching, BestMarketMotifSearch
from src.support_resist import SupportResistFinding
from src.trading_record import BuySellAnalyzer, WinLossAnalyzer, AssetAnalyzer
from src.summarize_text import NewsSummarizer, NewsScraper
from src.Utils.utils import filter_stocks, general_rating, config_parser, validate_symbol
from functools import wraps
router = APIRouter(prefix="/stocks", tags=["Stock Operations"])
data = config_parser(data_config_path='config/config.yaml')
class SymbolRequest(BaseModel):
symbol: str
class PatternRequest(BaseModel):
symbol: str
start_date: str # Format: YYYY-mm-dd
class NewsSummaryRequest(BaseModel):
url: str
def validate_symbol_decorator(func):
@wraps(func)
async def wrapper(request: SymbolRequest | PatternRequest, *args, **kwargs):
if not validate_symbol(request.symbol.upper()):
raise HTTPException(status_code=400, detail=f"Invalid symbol: {request.symbol}")
return await func(request, *args, **kwargs)
return wrapper
@router.post(
"/paybacktime",
operation_id="calculate_payback_time",
)
@validate_symbol_decorator
async def get_paybacktime(request: SymbolRequest):
"""Calculates the payback-time price for a given stock symbol"""
try:
pbt_params = data.get('pbt_params')
pbt_generator = PayBackTime(symbol=request.symbol.upper(), report_range=pbt_params[0], window_size=pbt_params[1])
report = pbt_generator.get_report()
return {"report": report}
except Exception as e:
raise HTTPException(status_code=500, detail=f"Error calculating payback time: {str(e)}")
@router.post(
"/support-resistance",
operation_id="find_support_resistance",
)
@validate_symbol_decorator
async def get_support_resistance(request: SymbolRequest):
"""Finds the closest support and resistance levels for a given stock symbol"""
try:
sr_finding = SupportResistFinding(symbol=request.symbol.upper())
result = sr_finding.find_closest_support_resist(current_price=sr_finding.get_current_price())
report = (
f"The current price for {request.symbol.upper()} is {sr_finding.get_current_price()}\n"
f"- The closest support is {round(result[0], 2)}\n"
f"- The closest resistance is {round(result[1], 2)}\n"
)
return {"report": report}
except Exception as e:
raise HTTPException(status_code=500, detail=f"Error calculating support/resistance: {str(e)}")
# ... (other endpoints)
This code:
- Sets up a FastAPI app with stock and MCP routers.
- Loads configuration from
config.yaml
. - Defines endpoints like
/stocks/paybacktime
and/stocks/support-resistance
for stock analysis. -
Note:
mcp_apis.py
is assumed to exist for MCP-specific routes, as referenced inapi.py
.
Integrating fastapi-mcp
The src/api.py
already integrates fastapi-mcp:
- Initializes
FastApiMCP
with the app, name, description, andbase_url="http://localhost:8668"
. - Calls
mcp.mount()
to add MCP routes (likely/mcp
). - Calls
mcp.setup_server()
to configure the MCP server. - Runs on the host and port from
config.yaml
(defaults to0.0.0.0:8000
, but we’ll use 8668 to match the README).
Ensure the base_url
and port align with the client configuration (http://localhost:8668/mcp
).
Configuring the Client
Configure Claude Desktop to connect to the MCP server by editing C:\Users\
:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"C:\\Users\\\\Desktop",
"C:\\Users\\\\Downloads",
"D:\\"
]
},
"paybacktime": {
"command": "mcp-proxy",
"args": ["http://127.0.0.1:8668/mcp"]
}
}
}
-
"paybacktime"
: Name of the MCP server entry. -
"command": "mcp-proxy"
: Usesmcp-proxy
to connect. -
"args"
: Points to the MCP endpoint.
Restart Claude Desktop to apply changes.
Running the Server
Run the server from the project root:
python src/mcp_server.py
Note: The README mentions running mcp_server.py
, but based on the provided code, it’s likely meant to be src/api.py
. Update the command if your file is named differently:
python src/api.py
This starts the server on http://localhost:8668
(per config.yaml
). Access:
- API docs at
http://localhost:8668/docs
. - Stock endpoints at
http://localhost:8668/stocks/*
. - MCP endpoint at
http://localhost:8668/mcp
.
Example Usage and Results
Test the API using curl
, Postman, or the FastAPI docs at http://localhost:8668/docs
.
Key Endpoints
- POST /stocks/paybacktime:
-
Input: JSON with
symbol
(e.g.,{"symbol": "ACB"}
). - Output: Payback time analysis report.
- Purpose: Analyzes the stock’s payback time based on financial metrics.
- POST /stocks/support-resistance:
-
Input: JSON with
symbol
. - Output: Current price, closest support, and resistance levels.
- Purpose: Identifies key price levels for trading.
- GET /stocks/find-paybacktime-stocks:
- Input: None.
- Output: List of stocks meeting payback time criteria.
- Purpose: Screens stocks with favorable payback times.
Testing the Paybacktime Endpoint
Test the /stocks/paybacktime
endpoint for ACB:
curl -X POST "http://localhost:8668/stocks/paybacktime" -H "Content-Type: application/json" -d '{"symbol": "ACB"}'
Example Response (simplified, as actual output depends on PayBackTime.get_report()
):
{
"report": "Payback time for ACB: 3.5 years based on current financials."
}
The actual report will include detailed financial metrics, as implemented in the PayBackTime
class.
Using with Claude Desktop
With Claude Desktop configured, it can query the MCP server via http://127.0.0.1:8668/mcp
. For example, asking Claude to analyze ACB’s payback time would invoke /stocks/paybacktime
, returning the report to enhance Claude’s response. The exact interaction depends on Claude’s UI (check Anthropic’s docs).
Here are the available tools for MCP:
Example 1: ACB Stock Report
I asked Claude to generate a report for ACB stock using the MCP server to support its analysis.
And the result
Example 2: Payback Time Stocks Analysis
I requested Claude to identify and analyze all payback time stocks for today.
Conclusion
You’ve built an MCP server with fastapi-mcp, integrated stock analysis endpoints, and connected it to Claude Desktop on Windows. The server provides powerful stock analysis tools, like payback time and support/resistance, accessible via HTTP or MCP. Expand it with more endpoints from stock_apis.py
or explore the Stock Price for Fun repo for advanced features.