mcpField
M
mcp-sql-querystore

mcp-sql-querystore

ローカル
github.com/deepeshd87データベース04 週間前に更新

mcp-sql-querystore について

mcp-sql-querystoreは、Query Store、DMV、実行プランを使ってSQL Serverの性能を調べる読み取り専用MCPサーバーです。回帰や待機、プランの問題を調査する運用担当者やエージェント向けで、専用の読み取り専用SQLログインによってアクセスを制限します。

主な機能

  1. 01クエリ性能の回帰検出
  2. 02実行プランと警告の要約
  3. 03パラメータスニッフィングの検出
  4. 04欠落インデックス候補の影響度評価
  5. 05待機統計の集計
  6. 06複数データベースの回帰スキャン

活用シーン

  1. 01ベースラインと比べて遅くなったクエリの特定
  2. 02暗黙的変換や欠落インデックスをプランで確認
  3. 03CPU、ロック、I/O、メモリの遅延要因を判別
  4. 04Query Store有効データベース間の回帰状況を比較

MCP 対応

MCPクライアントに6種類の読み取り専用診断ツールを提供します。stdioサーバーとして登録でき、クエリはSQL本文や認証情報を記録せずに監査ログへ出力されます。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"deepeshd87-mcp-sql-querystore": {
"command": "uvx",
"args": [
"mcp-sql-querystore"
]
}
}
}
起動コマンドuvx mcp-sql-querystore

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
pypimcp-sql-querystore0.1.1

ツール

6

掲載時のツール一覧 · 2 週間前に更新

パラメーター型必須説明
top_nintegerいいえ返す行の最大数。
metricenumいいえ性能低下の評価に使用する指標。cpu_time | duration | logical_reads
recent_hoursintegerいいえ直近の期間の長さ(時間単位)。
database_namestringはい対象となる SQL Server データベース名。
baseline_hoursintegerいいえ直近の時間ウィンドウより前に設定するベースラインウィンドウの長さ(時間単位、デフォルトは 7 日間)。
min_executionsintegerいいえいずれかの期間で実行回数がこの値を下回るクエリを無視します(ノイズを除去)。
regression_thresholdnumberいいえフラグ付けする最小悪化率(0.5 = ベースラインより 50% 悪化)。

詳細

mcp-name: io.github.deepeshd87/mcp-sql-querystore

mcp-sql-querystore

LLM エージェントに SQL Server Query Store の診断機能を提供する、読み取り専用の MCP サーバーです。

Query Store、DMV、実行プランを対象とした、読み取り専用の診断ツールが 6 つあります。これらのツールは稼働中の SQL Server インスタンスで検証済みで、単体テストと統合テストでカバーされています。ただし、本番環境に接続する前に、必ずご自身の非本番環境で検証してください。特に、「注意事項」に記載されているバージョン以外の SQL Server を使用する場合はご注意ください。

クイックスタート

  1. 読み取り専用ログインをプロビジョニングします。 provisioning/create_readonly_login.sql をご自身のインスタンスに対して実行します(先に名前を編集してください)。このログインの権限によって読み取り専用が保証されます。詳しくは、以下のセキュリティモデルをご覧ください。

  2. インストールします。 仮想環境で pip install -e . を実行します。ホストに ODBC Driver 18 for SQL Server がインストールされている必要があります。

  3. パスワードをリポジトリの外に保管します。 リポジトリからアクセスできない場所(プロジェクトフォルダーの外)に、プレーンテキストファイルとして保存します。

    # Windows PowerShell、UTF-8、パスワードのみ、引用符や改行なし
    New-Item -ItemType Directory -Force C:\Users\you\secrets | Out-Null
    Set-Content -NoNewline -Encoding utf8 C:\Users\you\secrets\mcp_sql.pwd 'your-password'
    

    または、統合認証(MCP_SQL_TRUSTED=yes)を使えば、パスワードを完全に省略できます。CJIS/PCI ではこちらを推奨します。すべてのオプションについては、以下のシークレットの取り扱いをご覧ください。

  4. MCP クライアントを設定します。 claude_desktop_config.example.json の sql-querystore ブロックを実際の Claude Desktop 設定ファイル(Windows:%APPDATA%\Claude\claude_desktop_config.json)にコピーし、プレースホルダーのパス、サーバー名、MCP_SQL_PWD_FILE を置き換えます。自己署名証明書またはローカル証明書を使用する場合に限り、MCP_SQL_TRUST_CERT=yes を設定してください。適切な証明書を備えたインスタンスに対しては no のままにします。

  5. MCP クライアントを再起動し、サーバーが実行中として表示されることを確認します。

実際の設定ファイルやパスワードファイルは絶対にコミットしないでください。.gitignore では、すでに *.pwd、.env、claude_desktop_config.json が除外されています。

セキュリティモデル(最初にお読みください)

読み取り専用の保証は、リポジトリ内のコードではなく、SQL ログインの権限によって実現します。

  • VIEW DATABASE STATE(サーバースコープの DMV を使用する場合に限り VIEW SERVER STATE も)を付与した専用ログインをプロビジョニングし、それ以外の権限は一切付与しないでください。db_datareader やユーザーテーブルへの SELECT 権限も付与しないでください。provisioning/create_readonly_login.sql をご覧ください。
  • db.py のキーワードチェックと、固定された SELECT のみのクエリ文字列は、多層防御であり、主要な制御ではありません。
  • 接続文字列の ApplicationIntent=ReadOnly は、可用性グループ内の読み取り可能なセカンダリへのルーティングにのみ使用されます。スタンドアロンのインスタンスでは、セッションを読み取り専用にしません。安全性をこれに依存しないでください。
  • 認証情報をコードに含めないでください。最も簡単な設定は MCP_SQL_CONNECTION_STRING 環境変数を使う方法ですが、CJIS/PCI 環境では統合認証、またはファイルやシークレットストアから取得するパスワードを推奨します。詳しくは、以下のシークレットの取り扱いをご覧ください。
  • すべてのクエリは監査ロガーを通じて記録されます。詳しくは、以下の監査ログをご覧ください。規制対象の環境では、このロガーの出力先を永続ファイルまたは SIEM に設定してください。

セットアップ

ホストに ODBC Driver 18 for SQL Server がインストールされている必要があります。パッケージをインストールし、環境変数を使って接続を設定してください(すべてのオプションについては、シークレットの取り扱いをご覧ください)。推奨する方法は、パスワードをインラインではなくファイルに保存することです。

pip install -e .

# PowerShell — connection assembled from parts, password read from a file
$env:MCP_SQL_SERVER      = "yourhost\INSTANCE"
$env:MCP_SQL_DATABASE    = "master"
$env:MCP_SQL_UID         = "mcp_readonly"
$env:MCP_SQL_PWD_FILE    = "C:\path\to\your\secret.pwd"
$env:MCP_SQL_TRUST_CERT  = "no"   # "yes" only for a self-signed/local cert

python -m mcp_sql_querystore.server

または、保存済みのパスワードを一切使わずに、統合認証(MCP_SQL_TRUSTED=yes)を使用できます。シンプルなケースでは、完全な MCP_SQL_CONNECTION_STRING も使用できます。詳しくは、シークレットの取り扱いをご覧ください。

MCP クライアント(例:Claude Desktop)に、python -m mcp_sql_querystore.server を実行する stdio サーバーとして登録してください。claude_desktop_config.example.json をご覧ください。

ツール

すべてのツールは読み取り専用で、database_name を受け取ります(すべてのデータベースを対象にできる sweep_regressions を除きます)。各ツールは JSON を返します。失敗した場合は例外を発生させず、構造化されたエラー辞書を返します。

  • get_regressed_queries — クエリごとに、直近の期間とそれより前のベースライン期間を比較し、regression_threshold 以上悪化したものを検出します。CPU 使用率の高いクエリ一覧ではなく、実際にベースラインと直近の結果を比較します。
  • get_query_execution_plan — query_id のコンパイル済みプランを、簡潔な JSON サマリー(不足しているインデックス、警告(暗黙的な型変換を含む)、キー検索)と、オプションの生の XML とともに返します。
  • analyze_parameter_sniffing — コンパイル済みプランが複数あるクエリを検出し、最も遅いプランの平均実行時間と最も速いプランの平均実行時間の比率でランク付けします。これは典型的なパラメーター スニッフィングの特徴です。
  • get_missing_index_impact — 不足インデックスの推奨事項を含む直近のプランをスキャンし、プラン XML から影響スコアを解析します。重複する推奨事項をクエリ間で集計し、影響度、次いで発生頻度の順にランク付けします。
  • get_wait_stats — 一定期間のクエリ待機時間を待機カテゴリ別に集計し、クエリが遅い理由(CPU、ブロッキング/ロック、IO、メモリ)を示します。遅いクエリがどれかを示すものではありません。Microsoft のガイダンスに従い、フラッシュ済みの行とメモリ内の行の重複を除外します。
  • sweep_regressions — Query Store が有効なすべてのオンラインデータベース、または明示的に指定した database_names のリストを対象に回帰検出を実行し、データベースごとに最も深刻なものをランク付けして返します。データベースでエラーが発生しても全体のスキャンは中断されず、そのエラーは収集されて報告されます。

プロンプトの例

サーバーを MCP クライアントに接続したら、自然言語でツールを操作できます。プロンプトには対象のデータベース名を指定してください(すべてのデータベースをスキャンできる sweep_regressions を除きます)。YourDB をデータベース名に置き換えてください。

待機統計 — クエリが遅い理由

  • 「過去 1 週間の YourDB で、待機カテゴリの上位を教えてください。」
  • 「YourDB は CPU、メモリ、IO のどれを待っていますか?」
  • 「YourDB の過去 24 時間の待機統計を表示してください。」

実行プラン

  • 「YourDB の query_id 10 の実行プランを取得して、要約してください。」
  • 「YourDB の query_id 13 に不足インデックスの推奨事項はありますか?」
  • 「YourDB の query 12 のプランに暗黙的な型変換の警告はありますか?」

回帰分析

  • 「過去 24 時間の YourDB の CPU 回帰を確認してください。」
  • 「YourDB で 30% を超えて回帰したクエリを教えてください。」
  • 「実行回数が 10 回未満のものを除外して、YourDB の実行時間の回帰を見つけてください。」

パラメーター スニッフィング

  • 「YourDB でパラメーター スニッフィングを確認してください。」
  • 「YourDB でプランが不安定なクエリを教えてください。」

不足インデックス

  • 「YourDB で最も必要とされている不足インデックスを教えてください。」
  • 「YourDB のインデックス推奨事項を、影響度の高い順に上位 10 件表示してください。」

複数データベースのスキャン(データベース名は不要)

  • 「すべてのデータベースで CPU 回帰をスキャンしてください。」
  • 「今週、最も深刻な回帰が発生したデータベースを教えてください。」

組み合わせ — 1 回のやり取りでツールを連続実行

  • 「YourDB で最も大きな CPU 回帰を見つけ、そのプランを取得して、回帰した可能性のある理由を教えてください。」
  • 「YourDB の動作が遅いようです。原因を診断してください。」(待機統計 → 回帰 → プラン)
  • 「YourDB のパフォーマンスを総合的にトリアージしてください。待機統計、回帰の上位項目、不足インデックスを確認してください。」

既知の注意点/TODO

  • バージョンの違い。 Query Store の列名は SQL Server 2019+/2022 および Azure SQL MI を想定しています。それらを対象とする場合は、2016/2017 でも確認してください。
  • 回帰の意味づけ。 現在のロジックでは実行回数で加重した平均を使用します。パーセンタイルに基づく比較のほうが適している場合もあります(Query Store はパーセンタイルを直接保存しないため、*_stdev 列と前提条件が必要です)。
  • 期間指定なし: analyze_parameter_sniffing は Query Store の全履歴を集計します。負荷の高いデータベースでは、他のツールと同様に recent_hours フィルターを追加することを検討してください。
  • 残っている堅牢化の課題: バックオフ付きの接続再試行、および 2016/2017/2019/2022 が混在する環境に対応するバージョン別の列処理。

シークレットの取り扱い

接続文字列は次の順序で解決されるため、パスワードを設定ファイルに 平文で記載する必要はありません。

  1. MCP_SQL_CONNECTION_STRING — 接続文字列全体(最も簡単。後方互換性あり)。
  2. MCP_SQL_CONNECTION_STRING_FILE — 接続文字列全体を含むファイルへのパス (Docker/K8s のシークレットマウント方式)。
  3. パーツから組み立てる場合:MCP_SQL_SERVER(および MCP_SQL_DATABASE、MCP_SQL_DRIVER、 MCP_SQL_ENCRYPT、MCP_SQL_TRUST_CERT、MCP_SQL_EXTRA)。認証方式は次のいずれかです。
    • 統合認証(CJIS/PCI 向けに推奨。パスワードを保存しません):MCP_SQL_TRUSTED=yes。
    • SQL 認証:MCP_SQL_UID と、MCP_SQL_PWD_FILE(Vault でマウントされたファイル)、 MCP_SQL_PWD_ENV(別の環境変数の名前)、または MCP_SQL_PWD(直接指定。最も非推奨) から取得するパスワードを使用します。

タイムアウト:MCP_SQL_CONNECT_TIMEOUT(デフォルトは 10s)と MCP_SQL_QUERY_TIMEOUT (デフォルトは 30s。0 を指定すると無効になります)。

監査ログ

すべてのクエリ試行は mcp_sql_querystore.audit ロガーを通じて記録されます。記録内容は、ツール、 データベース、SQL の 12 文字のハッシュ(SQL 本文ではありません)、行数、経過時間(ミリ秒)、 結果です。接続文字列、SQL 本文、パラメーター値は一切ログに記録されません。 このロガーにハンドラーを設定すると、監査ログをファイルまたは SIEM に出力できます。

テスト

ユニットテスト(データベース不要。CI でも安全に実行できます):

pip install -e ".[test]"
pytest

統合テスト(実際のインスタンスが必要。オプトイン方式):

# 上記のいずれかの方法で有効な接続を設定してから、次を実行します。
$env:MCP_SQL_TEST_DATABASE = "RAG"
$env:MCP_SQL_RUN_INTEGRATION = "1"
pytest tests/test_integration.py -v

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。