ADR-0006: Tool-Architektur & MCP-Integration

Status
Proposed
Datum
2026-05-15
Decider
Malte (mit Claude)
Verwandt
ADR-0003 (Architektur), ADR-0004 (Framework), ADR-0009 (Marktdaten), ADR-0010 (Backtesting)
Tags
tools, mcp, agents

Kontext

Die Sub-Agents aus ADR-0003 brauchen Werkzeuge: Web-Search (News, Recherche), Aufruf externer Daten-APIs (Marktdaten, Filings), Berechnungs-Tools (Indikatoren, Backtests, Risiko), Dokument-Extraktion (PDFs). Ohne Tools sind LLMs auf ihr Trainingswissen begrenzt — was im Investment-Kontext nutzlos und gefährlich ist.

Tools können auf zwei Arten an Agents angebunden werden: als Python-Funktionen (Code-Tools, tightly coupled) oder als MCP-Server (Model Context Protocol, standardisierte externe Schnittstelle).

Entscheidungstreiber

Entscheidung

Wir setzen auf einen Hybrid-Ansatz:

Tool-Inventar (v1)

MCP-Server

ToolZweckQuelle / Wartung
Tavily Search AI-optimierte Web-Suche mit Relevanz-Scoring. News-Recherche, Sentiment-Quellen. Offizielles Tavily MCP, Key in .env (gesetzt).
Tavily Extract Volltext aus URL extrahieren, Markdown-konvertiert. Geschäftsberichte, Press Releases. Selbes Tavily MCP.
SEC EDGAR 10-K, 10-Q, 8-K-Filings (Volltext + Metadaten). Für US-Aktien. Community-MCP (z. B. sec-edgar-mcp). Backup: SEC EDGAR REST-API direkt.
Fetch Allgemeines URL-Fetching mit Markdown-Konvertierung, für Quellen außerhalb der speziellen Tools. Offizielles mcp-server-fetch.
Jina Reader (Fallback) Free-Tier-Fallback für URL-Extraktion (https://r.jina.ai/<url>). Eigener dünner MCP-Wrapper oder direkter Code-Aufruf (s. u.).
Time Timezone-aware Zeitabfragen, Market-Hours-Checks. Offizielles mcp-server-time.

Code-Tools (Python)

ToolZweckImplementierung
get_eod_prices EOD-Preise für Ticker + Zeitraum. Provider-Adapter (yfinance v1, später Tiingo/Polygon — siehe ADR-0009). Lokaler SQLite-Cache.
get_fundamentals Fundamentaldaten (PE, P/B, EPS-History, Margins). yfinance v1, später Provider-Switch.
compute_indicators Technische Indikatoren (RSI, MACD, Bollinger, MA). pandas-ta oder eigene Funktionen über pandas.
run_backtest Strategie-Backtest auf historischen Daten. vectorbt oder backtesting.py (Entscheidung in ADR-0010).
compute_risk_metrics Drawdown, Vola, Sharpe, Korrelation zu Watchlist-Items. numpy/pandas direkt.
parse_pdf Geschäftsberichte als PDF lesen, in strukturierten Text umwandeln. pdfplumber oder pymupdf.
get_watchlist / get_run_history Lesezugriff auf interne State-DB (Watchlists, vergangene Runs, Decisions). Direktes SQLite-Repository-Pattern.

Tool-Permissions pro Agent

Jeder Sub-Agent erhält explizit nur die Tools, die er braucht. Least-Privilege wird im Code durchgesetzt (Tools werden in der Agent-Konstruktion registriert; was nicht registriert ist, kann der Agent nicht aufrufen).

AgentMCP-ToolsCode-Tools
Screener get_eod_prices, compute_indicators (limitiert auf simple Filter), get_watchlist
Research Tavily Search/Extract, SEC EDGAR, Fetch, Jina, Time parse_pdf
Analyst get_eod_prices, get_fundamentals, compute_indicators
Strategy run_backtest, Read-Access auf Research-/Analyst-Outputs
Critic Tavily Search (Counter-Research) Read-Access auf Strategy-Output, get_eod_prices (Spot-Checks)
Risk-Assessment get_eod_prices, compute_risk_metrics, get_run_history
Coordinator (kein Agent, kein LLM — orchestriert nur)

MCP-Integration mit Pydantic AI

Pydantic AI unterstützt MCP-Server-Clients nativ. MCP-Server werden beim App-Start als Sub-Prozesse oder über HTTP-Endpunkte aufgebaut und ihre Tools dem jeweiligen Agent zugewiesen. Konfiguration in config/mcp.yaml:

mcp_servers:
  tavily:
    transport: stdio
    command: ["npx", "-y", "@tavily/mcp-server"]
    env:
      TAVILY_API_KEY: ${TAVILY_API_KEY}

  sec_edgar:
    transport: stdio
    command: ["uvx", "sec-edgar-mcp"]

  fetch:
    transport: stdio
    command: ["uvx", "mcp-server-fetch"]

  time:
    transport: stdio
    command: ["uvx", "mcp-server-time"]

Tool-Aufrufe im Decision-Log

Jeder Tool-Call (MCP oder Code) wird ins Decision-Log geschrieben (ADR-0012): Tool-Name, Argumente, Result-Hash (nicht der volle Result, kann groß sein — voller Result separat als Blob referenziert), Latenz, ggf. Fehler. Damit ist jede Empfehlung im Nachhinein bis auf den letzten Tool-Call rekonstruierbar.

Nicht in v1

Konsequenzen

Positiv

Negativ / Trade-offs