Building MCP Servers Like a Pro (With a Little Help from yfinance and LLMs)

If you've been in the AI space for a minute, you've likely noticed the growing interest in hooking Large Language Models (LLMs) up to real-world data and services. That's where the Model Context Protocol (MCP) steps in. Think of MCP as a standardized "plug" that lets AI models talk to APIs, file systems, and more—all without you having to do a ton of custom integration work each time. In this post, we'll walk through what MCP is and how to create a practical MCP server that integrates with the yfinance library for real-time stock data. Along the way, we'll also see how LLMs can speed up the development process.

Part 1: Getting Familiar with MCP

What Is MCP?

The Model Context Protocol (MCP) is a way for applications to reliably pass data, prompts, and tool instructions to LLMs. You can think of it as a universal interface for hooking an LLM into various data sources—like hooking up your phone to different devices via USB-C. It aims to:

MCP Basics

MCP servers expose three main asset types:

  1. Resources – These are read-only data sources such as file contents or API endpoints.
  2. Tools – These are callable functions you might want the LLM to execute (with user permission).
  3. Prompts – Pre-crafted text templates that the LLM can use for specific tasks or contexts.

Part 2: Spinning Up a yfinance MCP Server

Let's jump into a concrete example and build an MCP server that gives LLMs access to real-time financial data. We'll use yfinance to fetch market information, so an LLM can perform data-driven analysis on stocks.

Environment Setup

First, create a project folder and install dependencies:

# Initialize a new project and create a virtual environment
uv init yfinance-mcp
cd yfinance-mcp
uv venv
source .venv/bin/activate  # or .venv\Scripts\activate on Windows

# Install required packages
uv add "mcp[cli]" yfinance pandas

Core Server Code

Here's a straightforward MCP server using FastMCP. It defines two MCP tools to retrieve stock info and historical data, plus one prompt for a guided stock analysis. Drop this into server.py:

from mcp.server.fastmcp import FastMCP
import yfinance as yf
import pandas as pd
from typing import Optional, Dict, Any

# Initialize FastMCP server
mcp = FastMCP("yfinance-mcp")

@mcp.tool()
def get_stock_info(symbol: str) -> str:
    """Get detailed information about a stock.
    
    Args:
        symbol: Stock ticker symbol (e.g., AAPL, GOOGL)
    """
    try:
        ticker = yf.Ticker(symbol)
        info = ticker.info
        return {
            "name": info.get("longName"),
            "sector": info.get("sector"),
            "industry": info.get("industry"),
            "market_cap": info.get("marketCap"),
            "current_price": info.get("currentPrice"),
        }
    except Exception as e:
        return f"Error fetching stock info: {str(e)}"

@mcp.tool()
def get_historical_data(symbol: str, period: str = "1mo") -> str:
    """Get historical price data for a stock.
    
    Args:
        symbol: Stock ticker symbol
        period: Time period (1d, 5d, 1mo, 3mo, etc.)
    """
    try:
        ticker = yf.Ticker(symbol)
        hist = ticker.history(period=period)
        return hist.to_string()
    except Exception as e:
        return f"Error fetching historical data: {str(e)}"

@mcp.prompt()
def analyze_stock(symbol: str) -> str:
    """Create a comprehensive stock analysis prompt."""
    return f"""Please analyze this stock:

Symbol: {symbol}

1. Basic Information:
{{{{ get_stock_info(symbol="{symbol}") }}}}

2. Recent Performance:
{{{{ get_historical_data(symbol="{symbol}", period="1mo") }}}}

Please provide:
1. Key insights about the company
2. Recent performance analysis
3. Notable trends or patterns
"""

if __name__ == "__main__":
    mcp.run()

That's it! Fire up this server and your LLM can call it to retrieve stock data, or use the "Analyze Stock" prompt to generate a deeper analysis.

Part 3: Speeding Up Development with LLMs

Now, let's talk about one of the real superpowers here: letting LLMs help you build these servers. If you've used something like ChatGPT or Claude for coding, you know it can significantly speed up prototyping and testing.

1. Prep Work

Before you drag an LLM into your dev loop:

  1. Round up the right docs: MCP specs, your API references, your language SDK docs—whatever you'll need to answer the LLM's questions.
  2. Write a clear project spec: What capabilities do you need in your server? Which external services should it tap into? Any constraints or requirements?

2. Developing with an LLM

Here's a typical approach:

  1. Design Discussion
    • Provide the LLM with your specs and key documentation.
    • Ask for a proposed architecture or any caveats it might see.
  2. Implementation
    • Work in chunks. Have the LLM generate a piece of the code, then discuss or refine it.
    • Get the LLM to explain non-trivial parts or incorporate best practices.
    • Use the LLM to scaffold your testing strategy.
  3. Refinement
    • Ask for performance optimizations or design tweaks.
    • Consult it for security and error handling suggestions.

3. Best Practices

Part 4: Testing and Deploying

Testing with MCP Inspector

You can do interactive testing of your server using the MCP Inspector:

mcp dev server.py

Hooking into Claude Desktop

If you're using Claude Desktop, just add your MCP server configuration in its JSON setup:

{
  "mcpServers": {
    "yfinance": {
      "command": "python",
      "args": ["path/to/server.py"]
    }
  }
}

Security Pitfalls to Avoid

Wrapping Up

MCP servers are a powerful way to feed LLMs the data and tools they need—without reinventing the wheel for every new integration. By combining MCP's straightforward structure with LLM-assisted development, you can move faster and ship more reliable integrations.

Here are the key points to remember:

  1. MCP is a unifying protocol for hooking up LLMs to external data sources.
  2. LLMs can dramatically speed up building and testing your MCP servers.
  3. Security and robust error handling matter—especially when you're working with production systems.
  4. The MCP ecosystem is growing quickly, so keep an eye out for new best practices and prebuilt integrations.

Our yfinance-based server is just a small peek at what's possible. If you're looking to build out other functionalities—say hooking into custom databases or enterprise APIs—the same basic approach applies. Happy coding!

More Info and Links