Skip to main content

mdd-stock-mcp

An MCP server for Maximum Drawdown (MDD) analytics across US stocks, Korean stocks (KOSPI/KOSDAQ), and cryptocurrencies. Plug it into Claude Desktop and ask questions like "What was SPY's worst drawdown during COVID?" or "비트코인 2022년 MDD 알려줘" — Claude will fetch the data and discuss it conversationally.

License: MIT Python >=3.11 MCP Compatible

Disclaimer: This project uses yfinance, an unofficial Yahoo Finance scraper. Not affiliated with Yahoo, not for production trading systems, not for financial advice. Data may be inaccurate, delayed, or unavailable. Use at your own risk.


What it does

  • Calculates Maximum Drawdown for any supported asset over a date range
  • Returns OHLCV price history for plotting
  • Returns a daily drawdown (underwater) series
  • Compares MDD across multiple tickers side-by-side

Supported markets (via the market parameter):

market Examples Notes
us (default) AAPL, SPY, QQQ NYSE / NASDAQ
kr 005930 → 005930.KS (Samsung), 035720.KQ (KOSDAQ) 6-digit codes auto-append .KS (KOSPI). Use explicit .KQ for KOSDAQ.
crypto BTC → BTC-USD, ETH-USD, BTC-KRW Bare symbols auto-append -USD.

Quickstart (Claude Desktop)

1. Clone the repo:

git clone https://github.com/librarywon/mdd-stock-mcp.git
cd mdd-stock-mcp

2. Add to ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "mdd-stock-mcp": {
      "command": "uvx",
      "args": ["--from", "/absolute/path/to/mdd-stock-mcp", "mdd-stock-mcp"]
    }
  }
}

Replace /absolute/path/to/mdd-stock-mcp with the actual path where you cloned the repo (e.g. /Users/yourname/Documents/mdd-stock-mcp).

3. Restart Claude Desktop.

Ask: "Using mdd-stock-mcp, what was AAPL's MDD between 2020-01-01 and 2020-12-31?"


Alternative install (after PyPI publishing)

uvx mdd-stock-mcp

(Placeholder — not yet published to PyPI.)


Tools

Tool Description Example
calculate_mdd Single-ticker MDD calculate_mdd("SPY", "2020-01-01", "2020-12-31")
get_price_history OHLCV time series get_price_history("005930", "2024-01-01", "2024-06-30", market="kr")
get_drawdown_series Daily drawdown % series get_drawdown_series("BTC", "2022-01-01", "2022-12-31", market="crypto")
compare_mdd Multi-ticker MDD comparison compare_mdd(["SPY","QQQ","DIA"], "2020-01-01", "2020-12-31")

Each tool accepts:

  • price: "adj_close" (default, dividend/split adjusted) or "close" (raw closing price)
  • market: "us" (default), "kr", or "crypto" — see the supported markets table

Output schemas

calculate_mdd — success response
{
  "ticker": "SPY",
  "mdd_pct": -0.338915,
  "peak_date": "2020-02-19",
  "trough_date": "2020-03-23",
  "drawdown_duration_days": 33,
  "recovered": false,
  "recovery_date": null,
  "market": "us",
  "currency": "USD"
}
calculate_mdd — error response
{
  "error": true,
  "error_type": "InvalidTickerError",
  "message": "InvalidTickerError: Ticker 'XYZFAKE' not found or returned no data from Yahoo Finance."
}
get_price_history — success response
{
  "ticker": "AAPL",
  "price_basis": "adj_close",
  "count": 62,
  "data": [
    {
      "date": "2020-01-02",
      "open": 296.239990,
      "high": 300.600006,
      "low": 295.190002,
      "close": 298.829956,
      "volume": 33870100
    }
  ]
}
get_drawdown_series — success response
{
  "ticker": "SPY",
  "price_basis": "adj_close",
  "count": 125,
  "data": [
    {"date": "2020-01-02", "drawdown_pct": 0.0},
    {"date": "2020-01-03", "drawdown_pct": -0.007054},
    {"date": "2020-03-23", "drawdown_pct": -0.338915}
  ]
}
compare_mdd — success response (partial failure shown)
{
  "price_basis": "adj_close",
  "start": "2020-01-01",
  "end": "2020-06-30",
  "results": [
    {
      "ticker": "SPY",
      "mdd_pct": -0.338915,
      "peak_date": "2020-02-19",
      "trough_date": "2020-03-23",
      "drawdown_duration_days": 33,
      "recovered": false,
      "recovery_date": null,
      "error": null
    },
    {
      "ticker": "XYZFAKE",
      "mdd_pct": null,
      "peak_date": null,
      "trough_date": null,
      "drawdown_duration_days": null,
      "recovered": null,
      "recovery_date": null,
      "error": "InvalidTickerError: Ticker 'XYZFAKE' not found or returned no data from Yahoo Finance."
    }
  ]
}

How MDD is calculated

  • Formula: drawdown_t = price_t / max(price_{0..t}) - 1
  • MDD = min(drawdown) over the date range (most negative value)
  • Peak: argmax of price up to and including the trough date
  • Recovery: first date after trough where price >= peak_price
  • Note: recovered=false means "did not recover within the queried window", not "never recovered historically"

All price values use dividend/split-adjusted close by default (price="adj_close"). Pass price="close" for raw unadjusted closing prices.


Example Claude conversation

User: mdd-stock-mcp으로 SPY의 2020년 코로나 폭락 분석해줘

Claude: [calls calculate_mdd] SPY는 2020-02-19 최고점에서 2020-03-23 최저점까지 약 -33.9%의 MDD를 기록했습니다. 회복은 2020-08-18에 완료됐어요. 그래프 그려드릴까요?

User: 응

Claude: [calls get_price_history + get_drawdown_series, draws chart in artifact]


Limitations

  • US stocks, Korean stocks (KOSPI/KOSDAQ), and major cryptocurrencies — limited to what Yahoo Finance exposes. Other international exchanges (Tokyo, London, etc.) aren't wired up.
  • Daily resolution — No intraday (1m, 5m, etc.) data.
  • yfinance is unofficial — Yahoo Finance may rate-limit or change their API without notice. For production use, swap data.py for a paid provider like Polygon.io, Alpha Vantage, or Tiingo.
  • In-memory cache only — Price data is cached for 5 minutes per process. Cache is lost on server restart.
  • No real-time data — All data is end-of-day historical prices.

Development

# Install with dev dependencies
uv pip install -e ".[dev]"

# Run tests
pytest tests/

# Open MCP inspector (interactive tool tester)
fastmcp dev src/stock_mcp/server.py

Project structure:

src/stock_mcp/
  server.py   — FastMCP app + 4 tool definitions
  data.py     — yfinance wrapper + TTL cache + price-column selector
  mdd.py      — Pure MDD math functions
  models.py   — Pydantic input/output models
  errors.py   — Custom error types
tests/
  test_mdd.py — Offline math tests (no network required)

Claude Desktop config reference

{
  "mcpServers": {
    "mdd-stock-mcp": {
      "command": "uvx",
      "args": ["--from", "/Users/jaewon/Documents/mdd-stock-mcp", "mdd-stock-mcp"]
    }
  }
}

After publishing to PyPI, simplify to:

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

Deployment

Local (stdio) — default

The default transport is stdio, which is what Claude Desktop expects. Use the uvx config from the Quickstart section above.

Docker

# Build the image
docker build -t mdd-stock-mcp .

# Run with HTTP transport (e.g. for testing or a hosted setup)
docker run -p 8000:8000 mdd-stock-mcp --transport http

Replace 8000 with any port you prefer. The --transport http flag enables the HTTP/SSE transport mode; omit it for the default stdio mode.

Smithery / hosted

Smithery can host MCP servers so you don't need to run them locally. Once the smithery.yaml configuration is present in the repo root, you can register the server through the Smithery dashboard. See the Smithery documentation for registration instructions.


Roadmap

Planned additions (not yet scheduled — PRs welcome):

  • Sharpe / Sortino / CAGR tools — additional risk/return metrics as new MCP tools, following the same patterns as the existing four.
  • Optional Polygon.io / Alpha Vantage providers — drop-in replacements for the yfinance backend in data.py, configurable via environment variable.
  • Shorter date ranges / intraday support — hourly or intraday resolution for ranges under ~7 days, contingent on a stable data provider.

Contributing

This is a small focused project. PRs are welcome — especially for:

  • Additional data providers (Polygon, Alpha Vantage, Tiingo) in data.py
  • Additional metrics (Sharpe ratio, CAGR, Sortino) as new tools
  • Better error messages and edge-case handling

Please open an issue first for significant changes.


License

MIT — see LICENSE

Metadata

Release files for mdd-stock-mcp 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mdd-stock-mcp 0.1.0
File Size Uploaded Provenance Actions
mdd_stock_mcp-0.1.0.tar.gz 112.5 kB With provenance Details for mdd_stock_mcp-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for mdd-stock-mcp 0.1.0
File Interpreter ABI Platform Actions
mdd_stock_mcp-0.1.0-py3-none-any.whl Python 3 none any Details for mdd_stock_mcp-0.1.0-py3-none-any.whl

Total release size: 126.5 kB

Release files / mdd_stock_mcp-0.1.0.tar.gz

Download URL mdd_stock_mcp-0.1.0.tar.gz
Size 112.5 kB
Tags Source
SHA-256 checksum
How to use checksums
e0efcb5d2c67e45f35030a03ae13274050d830807f7d174e856d12519112e2b4
BLAKE2b-256 checksum
How to use checksums
aea0d674acc4521ec28742ba963b0cc78c7fab50e75a260886d506bc83db0d83
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 30, 2026.

Transparency log

Release files / mdd_stock_mcp-0.1.0-py3-none-any.whl

Download URL mdd_stock_mcp-0.1.0-py3-none-any.whl
Size 14.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
621c29ef87d1931ab570aaf6807d580675d93b966c5332d69ca9a79bb59bf478
BLAKE2b-256 checksum
How to use checksums
f6fc7d5238c29edc16a4d365cd5d51d7c80c577fa841ef8c63dd2024ce539fa0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 30, 2026.

Transparency log

Security for mdd-stock-mcp 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for mdd_stock_mcp-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 30, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page