Skip to main content
Glama
uirooong

yahoo-finance-mcp

by uirooong

yahoo-finance-mcp

Yahoo!ファイナンス日本版の株価を提供する Streamable HTTP 型 MCP サーバー。 Bun で動き、Docker コンテナとして起動する(npm は使わない)。

利用条件を先に読むこと。 このサーバーが取得するデータは再配布・商用利用が 規約で禁止されています。詳しくは 利用条件 を参照。


できること

ツール

内容

get_quote

現在値・前日比・騰落率・始値・高値・安値・出来高・売買代金・PER・PBR・配当利回り・時価総額・年初来高安など。最大 50 銘柄

get_price_history

日足 OHLCV(最大 3000 本)/分足(当日・直近5営業日)

get_pts_quote

PTS(夜間取引)の四本値・出来高

search_symbols

会社名から銘柄コードを検索

国内株式・ETF・REIT・国内指数・米国株に対応。 リソース yahoo-finance://usage-notes にデータの鮮度と制約をまとめてある。

Related MCP server: StockQuotes MCP

動かす

bun install
bun run up        # .env を生成 → イメージをビルド → 起動

bun run up.env が無ければ作り、MCP_BEARER_TOKEN を 32 バイトの乱数から生成する。 既にトークンがあれば黙って上書きしない。

bun run setup            # .env を用意(トークンが無ければ生成、あればそのまま)
bun run setup --rotate   # トークンを差し替える
bun run setup --quiet    # トークンを画面に出さない

bun run setup は MCP クライアントに貼る設定 JSON をそのまま出力する:

{
  "mcpServers": {
    "yahoo-finance": {
      "type": "http",
      "url": "http://127.0.0.1:3000/mcp",
      "headers": { "Authorization": "Bearer 62a5e0…(生成された値)" }
    }
  }
}

確認と停止:

curl -s localhost:3000/healthz
MCP_BEARER_TOKEN=$(grep -oP '(?<=MCP_BEARER_TOKEN=).*' .env) bun run smoke
bun run logs
bun run down

compose.yaml127.0.0.1 にのみ公開する。公開ネットワークに出さないこと。

.env を変えたあと

docker compose restart では反映されない。 環境変数はコンテナ生成時に焼き込まれるため、 作り直しが要る。

docker compose up -d      # コンテナを作り直して .env を反映(bun run up でも可)

実測(.env にトークンを入れて認証を有効化した直後):

操作

認証なしアクセス

docker compose restart

200 ← 反映されていない

docker compose up -d

401 ← 反映された

反映されたかは起動ログで確認できる。

docker compose logs --tail=5 | grep -E 'auth|warning'
# "auth":"bearer"   -> 認証あり
# "auth":"disabled" -> 認証なし

認証を無効化する

信頼できる環境だけで使うこと。MCP_BEARER_TOKEN を空にして MCP_ALLOW_NO_AUTH=1 を立てる。

sed -i 's/^MCP_BEARER_TOKEN=.*/MCP_BEARER_TOKEN=/;s/^MCP_ALLOW_NO_AUTH=.*/MCP_ALLOW_NO_AUTH=1/' .env
docker compose up -d

無効化しても 127.0.0.1 バインドと Origin 検証は残るので、ブラウザのページからは届かない (Origin 付きのリクエストは 403)。一方で同じマシンで動く任意のプロセスからは素通しになる。 読み取り専用とはいえ、あなたの上流セッションと IP で Yahoo を叩けてしまう点に注意。

戻すとき:

bun run setup --rotate    # トークンを生成(トークンがあれば認証が有効になる)
docker compose up -d

MCP_ALLOW_NO_AUTH=1 が立っていても、MCP_BEARER_TOKEN に値があれば認証は有効になる。 フラグが効くのはトークンが空のときだけ。bun run setup は無効化中の .env に黙って トークンを生やさない(--rotate を明示したときだけ生成する)。

.env とコンテナの関係

bun run setup が生成する .env.env.example を土台にしており、全設定項目がコメント付きで入る。 MCP_PORT / MCP_ALLOWED_ORIGINS / YF_MAX_CONCURRENCY / YF_MIN_INTERVAL_MS / LOG_LEVEL / TZ.env の値がそのままコンテナに渡る。MCP_HOSTYF_SESSION_FILE だけはコンテナ固有の値 (0.0.0.0/data/session.json)に固定され、.env では変えられない。

.env.gitignore 済み。コミットされるのは値が空の .env.example だけ。

ローカル開発(Docker なし)

bun run dev           # .env を用意して --hot で起動
bun test              # 単体テスト (48 件)
bun run test:live     # 実ネットワークを叩く統合テスト (6 件)
bun run typecheck

設定

環境変数

既定

説明

MCP_HOST / MCP_PORT

127.0.0.1 / 3000

待ち受け(コンテナ内は 0.0.0.0

MCP_BEARER_TOKEN

必須。未設定だと起動を拒否する

MCP_ALLOW_NO_AUTH

1 で認証を無効化(非推奨)

MCP_ALLOWED_ORIGINS

許可する Origin。空 = Origin 付きリクエストを全て拒否

MCP_MAX_BODY_BYTES

1048576

リクエストボディ上限

YF_MAX_CONCURRENCY

5

上流への同時接続数(上限 10 でクランプ

YF_MIN_INTERVAL_MS

50

上流リクエストの最小間隔(下限 20ms

YF_SESSION_FILE

Cookie B の保存先。空なら永続化しない

LOG_LEVEL

info

debug / info / warn / error

仕組み

MCP Client ──POST /mcp──▶ Origin検証 → Bearer認証
                          └▶ StreamableHTTPServerTransport (ステートレス)
                             └▶ tools → TtlCache(single-flight) → Limiter(5並列)
                                        └▶ YahooClient ─┬─ x-jwt-token
                                           YahooSession ─┴─ Cookie B
                                                             │
                                                    finance.yahoo.co.jp

要点は 3 つ。

1. WebSocket も SSE も無い。 本家は 60 秒間隔のポーリングだけで動いている (JS チャンク全 24 本を全文検索して WebSocket / EventSource / text/event-stream の 出現数が 0、refreshInterval:6e4 が 3 件)。サーバー発の push が要らないので ステートレス Streamable HTTPsessionIdGenerator: undefined)で構成している。

2. 認証は Cookie B にバインドされた JWT。 上流の JWT はクレームが exp のみで ユーザー識別情報を持たない。したがって Yahoo セッションはプロセスに 1 つで足り、 MCP クライアントが何本つながっても上流から見たセッションは 1 つになる。 Cookie B は volume に永続化し、コンテナ再起動後も同じセッションを引き継ぐ。

3. single-flight が生命線。 同一銘柄への同時リクエストは 1 本に畳まれる。 実測(Docker 上で同一銘柄を 20 並列):

上流リクエスト: 2 本 (合流 38)      ← priceBoard + detailData の 2 本だけ
bootstrap 回数: 1

データの鮮度(重要)

項目

実態

取引値

東証・福証・札証はリアルタイムdelayMinutes: 0)。日経平均・米国株は 15 分遅れ

出来高・売買代金

全市場で最低 15 分遅れvolume.realtime: false として返る

日足

当日分を含まない(引け後に追加される)

分足

ほぼ遅延なし。ただし国内株式・ETF のみ

出力の volume.realtime / volume.asOf / delayMinutes / quoteAsOf を必ず見ること。 取引値が 14:57 の時に出来高が 14:41 ということが普通に起きる。

数値が null のときは **0 ではなく「算出不能・未提供」**を意味する (上流が "---" を返している。赤字予想銘柄の PER など)。

取得できないもの

  • 板情報(気配値) — 無料枠では全て 999 のダミー値が返るため、意図的にツール化していない

  • 国内指数・米国株の分足 — 上流が 0 件を返す(日足は取得できる)

  • ポートフォリオ — ログインが必要

セキュリティ

Streamable HTTP はブラウザから到達しうる HTTP エンドポイントなので、stdio と違い明示的な防御が要る。

  • Origin 検証(DNS リバインディング対策、MCP 仕様の MUST)

  • Bearer 認証(timingSafeEqual で比較)

  • 127.0.0.1 バインド、ボディサイズ上限

  • コンテナは read_only / cap_drop: ALL / 非 root(USER bun)/ no-new-privileges

  • ログは Cookie B と JWT を必ずマスクする(424a...q6(len=58) の形)

壊れたときに見る場所

症状

ログ

原因と対処

全ツールが失敗

yahoo.jwt_not_found

上流のページ構造変更。src/yahoo/session.tsJWT_PATTERNS を更新

全ツールが失敗

yahoo.session_rejected_retrying が連続

Cookie B と JWT のバインド方式が変わった。FINDINGS.md の切り分け手順で再調査

一部の項目だけ null

yahoo.schema_mismatch

上流のレスポンス形式変更。research/samples/ の固定入力テストで差分を特定

get_price_history だけ 404

/chart/ex/v1/... の二重パスが廃止された。最も壊れやすい箇所

突然の 403 / 429 連発

upstream.errors が急増

WAF による遮断。YF_MAX_CONCURRENCY を下げる

/healthz が運用メトリクスを返す。session.bootstrapCount が跳ねたら single-flight が壊れている (正常なら 1 日十数回に収まる)。

{
  "status": "ok",
  "session": { "present": true, "expiresInSec": 7180, "bootstrapCount": 1 },
  "upstream": { "requests": 42, "errors": 0, "sessionRetries": 0 },
  "cache": { "entries": 12, "inflight": 0, "hits": 30, "misses": 12, "coalesced": 38 },
  "limiter": { "active": 0, "queued": 0 }
}

利用条件

取得元の Yahoo!ファイナンスには以下の定めがある。

  • 注記事項株式情報の転用、販売は固く禁じます。」 「当社は、この情報を用いて行う判断の一切について責任を負うものではありません。」

  • LINEヤフー共通利用規約 第14条(当社サービス等の再利用の禁止) 「お客様は…当社サービスやそれらを構成するデータを、その提供目的を超えて利用することができません。 この場合、当社は、それらの行為を差し止める権利ならびにそれらの行為によってお客様が得た利益相当額を請求する権利を有します。」

  • 同 第15条(5) 「当社のサーバーまたはネットワークの機能を破壊したり、妨害したりする行為、BOT…を利用して 当社サービスを不正に操作する行為」を禁止

したがって本サーバーは:

  1. 127.0.0.1 にのみバインドし、公開ネットワークに出さない構成にしてある

  2. 同時実行数を環境変数では緩められない(上限 10 でクランプ)

  3. 全ツールの出力に出典と免責を付ける

  4. データを再配布・販売・第三者提供しないこと

商用利用・再配布が必要な場合は、この方法を使わないこと。 J-Quants API(JPX 公式、遅延データの無料枠あり)、 QUICK、LSEG 等の正規のデータベンダー契約を利用する。

データ提供元は東京証券取引所・大阪取引所・名古屋証券取引所・野村総合研究所・東洋経済新報社・ ウエルスアドバイザー・リフィニティブ・ジャパン・LINE FX。日経平均株価の著作権は日本経済新聞社に帰属する。

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides comprehensive financial data from Yahoo Finance, enabling retrieval of stock prices, company information, financial statements, options data, analyst recommendations, and market news through natural language queries.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Provides real-time stock quotes, historical data, and stock search via Yahoo Finance, enabling AI assistants to access and analyze financial market data.
    11 npm
    19
    MIT
  • A
    license
    B
    quality
    C
    maintenance
    Enables AI assistants to access real-time Japanese and global stock market data, including quotes, charts, technical analysis, and market screening.
    7
    9 npm
    MIT