In this practical guide, you’ll learn how to create a Model Context Protocol (MCP) server enabling Claude Desktop to access stock news sentiment and daily market data using the AlphaVantage API. Given the limitation of most Large Language Models (LLMs) in accessing real-time financial data directly, this MCP approach offers a way to provide up-to-date information.
The server will offer two key features:
- get_news_sentiment
- get_top_movers
Here鈥檚 a step-by-step guide to building the server.
Step 1: Setting Up the Environment
Begin by setting up your environment, starting with the installation of the uv package manager. For Mac or Linux users:
“`bash
curl -LsSf https://astral.sh/uv/install.sh | sh
“`
For Windows users (using PowerShell):
“`powershell
powershell -ExecutionPolicy ByPass -c “irm https://astral.sh/uv/install.ps1 | iex”
“`
Create a new project directory and initialize it with uv:
“`bash
uv init stockNews
cd stockNews
“`
Next, create and activate a virtual environment. For Mac or Linux users:
“`bash
uv venv
source .venv/bin/activate
“`
For Windows users:
“`bash
uv venv
.venvScriptsactivate
“`
Install the required dependencies:
“`bash
uv add mcp httpx python-dotenv
“`
Step 3: Setting Up the Environment Variables
Create a .env file to store your AlphaVantage API key. Obtain a free API key as described earlier.
Add it to a .env file as follows:
“`plaintext
ALPHA_VANTAGE_API_KEY=your_api_key
“`
Step 4: Implementing the MCP Server and Integrating AlphaVantage
Create a stockNews.py file in your project directory and begin by adding the following code:
Import necessary packages and configure the API instance:
“`python
from typing import Any
import os
import httpx
from mcp.server.fastmcp import FastMCP
from dotenv import load_dotenv
# Load .env variables
load_dotenv()
API_KEY = os.getenv(“ALPHA_VANTAGE_API_KEY”)
# Initialize FastMCP server
mcp = FastMCP(“alpha-finance”)
# Constants
BASE_URL = “https://www.alphavantage.co/query”
“`
Helper Functions
Add functions to interact with the AlphaVantage service:
“`python
async def call_alpha_vantage(endpoint: str, params: dict[str, Any]) -> dict[str, Any] | None:
“””Generic async caller to Alpha Vantage.”””
params[“apikey”] = API_KEY
params[“function”] = endpoint
async with httpx.AsyncClient() as client:
try:
response = await client.get(BASE_URL, params=params, timeout=30.0)
response.raise_for_status()
return response.json()
except Exception:
return None
“`
Implementing Tool Execution
Add the execution logic for each command:
“`python
@mcp.tool()
async def get_news_sentiment(ticker: str) -> str:
“””Get news sentiment data for a stock ticker.
Args:
ticker: Stock ticker symbol (e.g., MSFT, AAPL)
“””
data = await call_alpha_vantage(“NEWS_SENTIMENT”, {“tickers”: ticker.upper()})
if not data or “feed” not in data:
return “Couldn’t retrieve news sentiment.”
articles = data[“feed”][:3]
result = []
for item in articles:
result.append(f”””
馃摪 {item[‘title’]}
Summary: {item[‘summary’]}
Source: {item[‘source’]} | Published: {item[‘time_published’]}
“””)
return “n—n”.join(result)
@mcp.tool()
async def get_top_movers() -> str:
“””Get top gainers and losers from the stock market.
No arguments required.
“””
data = await call_alpha_vantage(“TOP_GAINERS_LOSERS”, {})
if not data:
return “Couldn’t retrieve top movers.”
gainers = data.get(“top_gainers”, [])[:3]
losers = data.get(“top_losers”, [])[:3]
result = “**