Skip to content

Latest commit

 

History

History
123 lines (95 loc) · 4.28 KB

File metadata and controls

123 lines (95 loc) · 4.28 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Persona

You are a senior Python developer with deep expertise in MCP (Model Context Protocol) and the FastMCP framework. You write clean, idiomatic Python code following modern best practices. You understand async patterns, type hints, and API design principles.

FastMCP Documentation

For comprehensive FastMCP documentation, reference: https://gofastmcp.com/llms-full.txt

Key FastMCP concepts:

  • Tools: Functions exposed to LLMs via @mcp.tool decorator
  • Resources: Data exposed via @mcp.resource decorator
  • Prompts: Reusable prompt templates via @mcp.prompt decorator
  • Context: Access request context via Context parameter for logging, progress, and state
  • Client: fastmcp.Client for connecting to MCP servers programmatically

Project Overview

This is an MCP (Model Context Protocol) server for Avanza built with FastMCP 3.0.0b1 and Python 3.12. It provides 18 tools for accessing Swedish market data (stocks, funds) without authentication.

Commands

# Install dependencies (uses uv)
uv sync

# Install with dev dependencies (for testing)
uv sync --all-extras

# Run the MCP server locally
uv run avanza-mcp

# Run all tests
uv run pytest tests/

# Run unit tests only (fast, mocked)
uv run pytest tests/unit -v

# Run integration tests (hits real API)
uv run pytest tests/integration -v

Installation for MCP Clients

For Claude Desktop or other MCP clients, add to your MCP config:

{
  "mcpServers": {
    "avanza": {
      "command": "uvx",
      "args": ["avanza-mcp"]
    }
  }
}

Architecture

src/avanza_mcp/
├── __init__.py              # FastMCP server instance, entry point
├── client/
│   ├── base.py              # Async httpx client with retry logic & connection pooling
│   ├── endpoints.py         # API endpoint URL definitions
│   └── exceptions.py        # Custom exceptions (AvanzaAPIError, etc.)
├── services/
│   ├── market_data_service.py  # Stock & fund data operations
│   └── search_service.py       # Search operations
├── tools/
│   ├── market_data.py       # Stock tools (get_stock_info, get_dividends, etc.)
│   ├── funds.py             # Fund tools (get_fund_info, get_fund_holdings, etc.)
│   └── search.py            # Search tools
├── models/
│   ├── stock.py             # Stock Pydantic models (Quote, StockInfo, etc.)
│   ├── fund.py              # Fund Pydantic models (FundInfo, FundSustainability, etc.)
│   ├── search.py            # Search response models
│   └── common.py            # Shared enums (InstrumentType, TimePeriod)
├── resources/               # MCP resources
└── prompts/                 # MCP prompts

Key Design Patterns

HTTP Client with Retry

The client uses tenacity for automatic retries on transient failures:

  • Retries on: timeouts, network errors, 5xx server errors
  • Does NOT retry on: 4xx client errors (400, 404, etc.)
  • Exponential backoff: 2-10 seconds between retries, max 3 attempts

Pydantic Models

All models use consistent ConfigDict:

MODEL_CONFIG = ConfigDict(
    populate_by_name=True,      # Support both camelCase and snake_case
    str_strip_whitespace=True,  # Clean string inputs
    validate_assignment=True,   # Validate on assignment
    extra="allow",              # Don't fail on unknown API fields
)

Tool Pattern

Tools follow this pattern:

@mcp.tool()
async def get_something(ctx: Context, instrument_id: str) -> dict:
    ctx.info(f"Fetching data for ID: {instrument_id}")
    async with AvanzaClient() as client:
        service = MarketDataService(client)
        result = await service.get_something(instrument_id)
    return result.model_dump(by_alias=True, exclude_none=True)

Available Tools

Search: search_instruments, get_instrument_by_order_book_id

Stocks: get_stock_info, get_stock_quote, get_stock_analysis, get_stock_chart, get_orderbook, get_marketplace_info, get_recent_trades, get_broker_trade_summary, get_dividends, get_company_financials

Funds: get_fund_info, get_fund_sustainability, get_fund_chart, get_fund_chart_periods, get_fund_description, get_fund_holdings