CCCMKホールディングス TECH LABの Tech Blog

TECH LABのエンジニアが技術情報を発信しています

ブログタイトル

Databricks Apps でカスタム MCP サーバーを動かしてみる

はじめに

こんにちは、CCCMKホールディングスAIエンジニアの三浦です。

最近 OpenAI の Agentic Commerce Protocol (ACP) や Google の Universal Commerce Protocol(UCP) など、商品を探すだけでなく決済まで Agent で自動化するための Agent 間のプロトコルの標準化が進みつつあります。

developers.openai.com

ucp.dev

こうした流れを見ていると、今後のシステム開発では人だけでなく AI が利用することも想定して進める必要があると感じています。

AI が使うことを想定した仕組みの代表例として、 AI エージェントが利用するツールを提供する MCP サーバーが挙げられます。私自身も開発用途でいくつかの MCP サーバーを利用しており、最近は自作にも取り組んでみたいと考えていました。

本ブログでも時々取り上げてきたのですが、 Databricks にはアプリケーションを提供できる Databricks Apps という機能があります。実はこの Databricks Apps で独自の MCP サーバーを動かすことができます。

learn.microsoft.com

今回は商品情報を検索できるToolを提供するシンプルな MCP サーバーを開発し、 Databricks Apps で動かし、 Databricks の Playground から呼び出して試してみた内容をまとめます。

参考

Github に Databricks が公開しているカスタム MCP サーバーのテンプレートの実装を参考にしました。

github.com

必要なもの

事前に以下をインストールし、使用できる状態にしておきます。

  • uv: Python開発環境
  • Databricks CLI: Workspaceへのコードデプロイに使用

プロジェクト構成

まだテストコードは未作成ですが、 Databricks Apps へのデプロイ完了時点のプロジェクト構成は以下のとおりです。

.
├── .gitignore
├── .python-version
├── .vscode
│   └── settings.json
├── README.md
├── app.yml
├── databricks.yml
├── pyproject.toml
├── requirements.txt
├── resources
│   └── mcp-server.yml
├── server
│   ├── app.py
│   ├── main.py
│   └── tools.py
└── uv.lock

pyproject.tomlapp.ymlなどはテンプレートの内容をそのまま利用しています。それ以外で今回変更した箇所を紹介します。 MCP サーバーの実装にはテンプレートと同様に FastMCP というフレームワークを利用しました。

fastmcp.wiki

server/tools.py

ここではMCPサーバーで提供する Tool を定義します。今回は商品マスタから商品情報を検索できる Tool を実装しました。本来は DB から取得する構成にしたかったのですが、時間の都合で今回はモックの DB クライアントを用いて対応しています。

FastMCP では、 MCP サーバーインスタンス(mcp_server)を生成した後、関数に@mcp_server.toolデコレータを付与することで Tool として登録することが出来ます。

また商品マスタから取得したデータはそのまま返すと LLM が扱いづらいと考え、テキスト情報として整形する関数を適用するようにしました。

from typing import Optional

from pydantic import BaseModel

from server import utils


class Product(BaseModel):
    """商品情報のデータモデル"""

    id: int
    name: str
    price: float
    description: Optional[str] = None
    stock: int


class MockProductDBClient:
    """商品DBのモッククライアント"""

    def __init__(self):
        self.products = {
            1: Product(id=1, name="ノートPC", price=120000, description="15インチ", stock=5),
            2: Product(id=2, name="マウス", price=3000, description="ワイヤレス", stock=20),
            3: Product(id=3, name="キーボード", price=8000, description="機械式", stock=10),
        }

    def get_product(self, product_id: int) -> Optional[Product]:
        """商品IDから商品情報を取得"""
        return self.products.get(product_id)

    def get_all_products(self) -> list[Product]:
        """すべての商品情報を取得"""
        return list(self.products.values())

    def search_products(self, name: str) -> list[Product]:
        """商品名で検索"""
        return [p for p in self.products.values() if name.lower() in p.name.lower()]


_db_client = MockProductDBClient()


def format_product_response(products: list[Product]) -> str:
    """商品情報を人間が読みやすい形式で整形"""
    return "\n".join(
        [
            f"""{product.name} (ID: {product.id}) - ¥{product.price}
説明: {product.description}
在庫: {product.stock}個"""
            for product in products
        ]
    )


def load_tools(mcp_server):
    """
    すべての MCP ツールをサーバーに登録します。

    Args:
        mcp_server: ツールを登録する FastMCP サーバーインスタンス。
                   ツールの登録とルーティングを担うメインのサーバーオブジェクトです。
    """

    @mcp_server.tool
    def get_product_info(product_name: str) -> str:
        """商品名で商品情報を検索し、整形して返すツール

        Args:
            product_name (str): 検索する商品の名前
        """
        products = _db_client.search_products(product_name)
        if not products:
            return f"商品 '{product_name}' は見つかりませんでした。"
        return format_product_response(products)

databricks.yml

テンプレートでは採用されていませんが、今後MCPサーバーにさまざまな Databricks リソースを紐づける可能性を考慮し、プロジェクトは Databricks Asset Bundles で管理するようにしました。

Databricks Asset Bundlesについては以下の記事をご覧ください。

techblog.cccmkhd.co.jp

bundle:
  name: databricks-mcp-template

include:
  - resources/*.yml

sync:
  exclude:
    - "**/.ruff_cache"
    - "**/.venv"
    - "**/.vscode"
    - "**/docs"
    - ".gitignore"

# Define deployment targets
targets:
  dev:
    default: true
    workspace:
      host: "https://adb-xxxxxx.azuredatabricks.net/"
  prod:
    workspace:
      host: "https://adb-xxxxxx.azuredatabricks.net/"

resources/mcp-server.yml

MCP サーバーを Databricks Apps リソースとして Databricks Asset Bundles で管理するための YAML です。このファイルでは Databricks Apps として登録する際のMCP サーバー名を指定します。また名前の先頭に"mcp-"を付けておかないと、Databricks の Playground 上で MCP サーバーとして検出できないので、必ずつけるようにします。(私はつけ忘れて一回やり直しをしました)

resources:
  apps:
    mcp-product-info:
      name: "mcp-product-info"
      source_code_path: "."

デプロイして Playground で使ってみる

MCP サーバーを Databricks Apps としてデプロイした後、 Databricks のPlaygroundで MCP サーバーを利用出来ます。

Playgroundで"Add Tools"から"MCP Servers on Databricks Apps"で選ぶことが出来ます。

実際に Playground で問い合わせると、開発した MCP サーバーの Tool が呼び出され、情報検索を行ったうえで回答できていることを確認できました。

開発したMCPサーバーが提供しているToolを実行して回答出来ています。

まとめ

Databricks Apps を使って独自の MCP サーバーを動かせることを確認できました。今後は Model Serving や Unity Catalog などを組み合わせることで、より多機能なMCPサーバーを開発できそうです。引き続き活用していきたいと思います。