5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

BIツールの進化先?! DBを業務分析用のMCPサーバにしてBIを次世代にする

5
Last updated at Posted at 2026-03-17

はじめに

AI時代におけるBIツールとは何かを考えていく中で、「AIにDBを繋げば、ダッシュボードを作り込まなくても誰でも手軽にデータ分析ができるのでは?」 と思い立ち、 DBに直接接続するMCPサーバを構築してみました。

DB+MCPといえば、ローカルで起動するMCPサーバのDBHubが既にありますが、今回はWeb上で認証などきちんと行うようなDBと繋がっているMCPサーバを作りました。

実際に試験運用してみると、MCPのURL一つSQLを書かなくても自然言語で「去年の使用状況を分析したものをパワポにして」と聞けばAIが即座にクエリを組み立てプレゼン資料に起こしてくれたのでかなり便利だなという手触りです。(もちろんセキュリティは考慮済みです。)

昨今、MCP不要論が多いですが、こういったWeb上に認証付きのMCPサーバを用意し、すぐに繋げられる安全性や利便性はCLIツールでは難しいでしょう。1

AIエージェントにBIツールを兼ねさせることで、BIツール専用のサブスクリプション費用を削減できるほか、調査や文書作成なども1つのツールとワークフローで兼ねられるのも大きなメリットです。

以下はプロンプト一発で出してもらったパワポです。プロンプト → DB調査(MCP) → 分析 → パワポ出力(スキル) と一連の動作が連続して動いています。

image.png

本記事では、Python (FastMCP) で DB接続MCPサーバを構築する方法を、OIDC認証やセキュリティ面の考慮も含めて解説します。

本記事はデータ分析の一手法を紹介するものであって、実装結果の安全性は保証しません。各自で気をつけて実装してください。

主な構成とユースケース

本記事で想定するMCPサーバの構成を以下に示します。URL一つで認証を行い、即使えるMCPサーバが生えます。(エンジニア以外に展開する際に重要です)

構成のポイントとして、業務DBに直接つなぐのではなく、MCPから接続する用のETL済みの解析用DBを用意し、MCPサーバで認証をします。

このMCPサーバについて、以下のようなユースケースが考えられます。

  • データ分析・KPI測定: AIが状況や自然言語から即席でSQLクエリを組み立てるので、BIツールのようにクエリを自分で書く必要がありません
  • 定型レポート生成: よく使うクエリをコマンドやスキルとして登録しておけば、「月次レポート出して」の一言で済みます。
    • MCPに繋いだ人全員が使えるようにしたい場合はMCP上にそういった手順を用意しておけばいいでしょう。
  • アドホック調査: 「去年と比べて○○はどう変化した?」のような探索的な分析も、AIが対話的に深堀りしてくれます
  • 他のMCPサーバとの連携: Slack MCPと組み合わせれば分析結果を自動投稿、ファイルシステムMCPと組み合わせればCSVエクスポートなど

MCPサーバソースコード〜接続イメージ (Python / FastMCP)

以下がMCPサーバのコードのイメージです。(実際は細かい点を色々考慮する必要があります)

db_mcp.py
#!/usr/bin/env -S uv run
# /// script
# requires-python = ">=3.13"
# dependencies = ["mcp[cli]>=1.26.0", "aiomysql>=0.3.2"]
# ///
import os, time
from typing import Any
import aiomysql
from mcp.server.fastmcp import FastMCP

# !!!注意点!!!
# 掲載の都合上省略したが、自社IdP(EntraID等)に認証を委譲する
# OIDCProviderクラスを用意してコンストラクタに渡すこと
mcp = FastMCP("my-db-mcp", host="0.0.0.0")

DB = dict(host=os.environ.get("MYSQL_HOST", "127.0.0.1"),
          port=int(os.environ.get("MYSQL_PORT", "3306")),
          user=os.environ.get("MYSQL_USER", "root"),
          password=os.environ.get("MYSQL_PASSWORD", ""),
          db=os.environ.get("MYSQL_DATABASE", "analytics"),
          charset="utf8mb4", autocommit=True)

@mcp.tool()
async def execute_query(query: str, timeout: int = 30, max_rows: int = 1000) -> dict[str, Any]:
    """SQLクエリを実行して結果を返します。"""
    timeout, max_rows = max(1, min(timeout, 120)), max(1, min(max_rows, 10000))
    start = time.monotonic()
    async with aiomysql.connect(**DB) as conn, conn.cursor() as cur:
        await cur.execute(f"SET SESSION max_execution_time = {timeout * 1000}")
        await cur.execute(query)
        if cur.description is None:
            return {"message": f"Query OK, {cur.rowcount} row(s) affected"}
        columns = [d[0] for d in cur.description]
        rows = list(await cur.fetchmany(max_rows + 1))
        truncated = len(rows) > max_rows
        return {"columns": columns, "rows": rows[:max_rows],
                "row_count": min(len(rows), max_rows), "truncated": truncated,
                "execution_time_ms": int((time.monotonic() - start) * 1000)}

@mcp.tool()
async def get_schema(table_name: str = "") -> dict[str, Any]:
    """テーブル一覧またはカラム定義を返します。"""
    async with aiomysql.connect(**DB) as conn, conn.cursor() as cur:
        if not table_name:
            await cur.execute(
                "SELECT table_name, table_rows, table_comment FROM information_schema.tables "
                "WHERE table_schema = %s ORDER BY table_name", (DB["db"],))
            return {"tables": [{"name": r[0], "rows": r[1], "comment": r[2]}
                               for r in await cur.fetchall()]}
        await cur.execute("DESCRIBE `{}`".format(table_name.replace("`", "``")))
        return {"table": table_name,
                "columns": [{"field": r[0], "type": r[1], "key": r[3]} for r in await cur.fetchall()]}

if __name__ == "__main__":
    mcp.run(transport="streamable-http")

# !!!注意点!!!
# 細かい機能などは考慮していないので、作り込みは必要です (記事に後述)

上記をWebサーバ上に起動し、以下のようにMCPサーバにAIエージェントツールから接続します。

Claude CodeでのMCPサーバ接続
claude mcp add --transport http my-db-mcp https://mcp-hosted.example.com/mcp

# Claudeデスクトップであれば、 `カスタマイズ > コネクタ > カスタムコネクタを追加` で追加し、 `連携` で接続

接続時に認証が必要(Authenticate needed)と言われるので、接続を行います。認証を行うとブラウザが自動的に立ち上がりIdPに認可を受け取りにいくと思います。(ログイン画面が出ると思います)

Claude Codeでの認証表示
Claude.ai my-db-mcp Server 

Status: △ needs authentication
URL:  https://mcp-hosted.example.com/mcp
Config location: ...

> 1. Authenticate
2. Disable

MCPツールのURL追加とブラウザでの操作だけで、AIが自然言語からSQLを組み立ててDBに問い合わせられるようになります。

実際に接続したMCPサーバを活用してみる

実際にパワポ作成を依頼してみましょう。

image.png

image.png

パワポ資料を一発で作ってくれました!便利!

(かなり無茶苦茶なSQLクエリでも即時発行できるのは驚きです)

設置に際して考慮すべき点

基本的にBIツールと変わらない点も多いですが、以下の点にくれぐれも気をつけてください。

  • MCP自体の認証
    • MCPであればツールレベルでの認証(MCPツール自体の接続APIキーや今回紹介したOAuth2認証など)を行ってください
      • AIのコンテキストに認証などのシークレットが行かないように配慮してください。MCPの接続方法がOAuthだったり、ヘッダにAPIキーを付けるタイプであればこの懸念はありません。
      • 逆にAI自体に接続方法(認証キーの指定など)を指示する場合はシークレットがコンテキストに載ってしまうので気をつけてください
        • MCP以外の場合になりがちです。AIにAPIキーを指定させるのはやめよう!
    • 利用者が退職した場合など、認証認可が自動的に消滅する手法 を使いましょう
    • できればWebサーバ自体 接続元IPを絞りましょう (自社のみなど)
    • OAuth2認証でやりがちですが IdPを全面的に信用しないでください (IdPに繋がったからといって認証がそこで終わりと思わないでください)
      • IdP側でアプリケーションの認証を特定ユーザに絞れない場合、 アプリ側で認証されたユーザの属性で特定のユーザのみに認可するようにしましょう
        • email など詐称可能なクレームで絞るのは危険です(きちんと管理されたIdPからのみ接続可能など、詐称不可能な条件が揃っているなら問題はありません)
  • 顧客データ保護
    • ETLツールなどで個人情報や位置情報など機微情報は抹消してください
      • AIをコントロールして読み取りをセキュアにするような手法はとらないでください
    • DBから読み取ったデータについてはAIのコンテキストに載り、条件次第ではモデル学習やログに残ります
      • 利用者側がコンプライアンス基準が不十分なAIモデルやエージェンシーに欠ける知性の低いモデルを接続しないように十分に確認してください
      • 機微情報を消してもエージェントが第三者ネットワークなどにデータをアップロードするようなことがあれば問題です。その点も気をつけてください。
  • DBの特性
    • AIが無茶なクエリを投げても現実のシステムに影響を与えないようにきちんと分析用のDBは分離してください
    • AIが件数過多・実行時間が長過ぎるといった迷惑なクエリを投げることは想定してください
      • デフォルトタイムアウトや最大件数の設定は有効です(途中でリザルトセットが途切れたことは応答で教えてあげましょう)
    • 多くの場合、DBに書き込む必要はないので、MCP用に読み込み専用のDBユーザを作成し、読み込めるテーブルや行える操作を制限してください
    • ユーザ側からシステム上の備考欄などにAIに向けた悪意あるプロンプトが記入されるケースは十分考慮してください
    • AIが一発で読み解けない特殊なテーブル(汎用コードテーブルなどが典型例)やコード値の解釈等、業務ルールはMCP側にガイドを注入してください
      • ガイドが大きすぎる場合は、段階的にMCPからロードできるようにツールに分けるといいでしょう
      • 典型的なクエリなどはMCP側にロードする口をつけてもいいでしょう
  • 監査
    • MCP認証で「誰が」繋いだか明確にし、「いつ」「何をした(今回の場合であればクエリSQL)」のか分かるようにログを記録・保管・解析してください
      • JSONLで保管しておき、解析ツールフレンドリーにしておくといいでしょう
  • その他
    • なるべくMCP内に秘密やセンシティブデータが残らないように構成しましょう

案外考慮すべきことが多いので、設置に際しては必ず構成も含めてレビューを行ってください。

まとめ

BIツールの代替や補完2として、DB接続MCPサーバは十分に実用的だと思います。

従来のBIツールが「ダッシュボードを事前に作り込む」のに対し、 DB MCPは「AIが都度最適なクエリを生成する」アプローチです。 定型レポートもアドホック分析もこれ1つで対応でき、ダッシュボードのメンテナンスコストから解放されます。また、特に対BIツールという枠で考えなくともシステム運用全般に重宝するのは間違いないでしょう。

DBそのまま露出させるとAIが業務ルールを理解できないこともよくあるので、MCP上にテーブルコメントや定型クエリなど 業務知識を充実させることで、AIの分析精度・速度が向上します。

作成方法としては、ETLで構築されたリードオンリーDBに加えて、Python + FastMCP など既存ツールチェインでそこまで苦労せずにStreamable HTTP + OIDC認証付きのサーバが構築できます。また、DBサーバに限らず様々なデータレイクに繋いだMCPを複数種類用意することでシナジーもあるでしょう。

手軽な一方で、セキュリティ事項は十分に考慮することが何よりも大事です。 ETLで安全なデータを用意し、DBの権限やMCPの認証で何重にもガードレールを敷くようにしてください。監査ログも記録してください。

セキュリティに気をつけて良いAIライフを送りましょう!

  1. 逆にローカルでMCPサーバを立てるようなケースだとCLIツールで十分という感想は間違っていないと思いますが、要するに使い分けなのです。

  2. インタラクティブ・リアルタイムなダッシュボードなどはAIツール単体では厳しいです。またデータ解釈のブレの無さは業務ルールのガードレールを敷いて確保する必要があるでしょう。

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?