Azure Functionsを用いたPythonによる検索機能付きMCPサーバーを試してみた

Azure Functionsを用いて、PythonでMCPサーバーが構築できるという話を耳にしたので、実際に、検索ツールとして使用できるか試してみました。

構築環境の説明

今回は、以下のような環境でMCPサーバーを構築していきたいと思います。

構築環境概要

なお、Azure Functions、Azure AI Search等のAzure環境のリソースデプロイ、設定は割愛させていただきます。

ローカル環境で実行

Azure Functions上で動かす前に、まずはローカル環境で実行し、動作確認をします。

準備

Visual Studio Code(以下、VS Code)でAzure Functionsのプロジェクトを作成します。

このとき、MCP用のテンプレートはないので、一旦はHTTP triggerを選択してプロジェクトを作成しました。

テンプレートができたら、以下の4つのファイルに変更を加えます。

  • function_app.py
  • requirements.txt
  • host.json
  • local.settings.json
function_app.py

コードは以下の様に書きました。

import azure.functions as func
import os
import json
from azure.search.documents import SearchClient
from azure.core.credentials import AzureKeyCredential

# AI Search
AZURE_SEARCH_SERVICE = os.environ["AZURE_SEARCH_SERVICE"]
AZURE_SEARCH_API_KEY = os.environ['AZURE_SEARCH_API_KEY']
AZURE_SEARCH_INDEX_NAME = os.environ['AZURE_SEARCH_INDEX_NAME']

app = func.FunctionApp(http_auth_level=func.AuthLevel.FUNCTION)

tool_properties_json = json.dumps([{"propertyName": "search_query", "propertyType": "string", "description": "キーワード指定し、社内情報を検索し取得します。"}])

@app.generic_trigger(
    arg_name="context",
    type="mcpToolTrigger",
    toolName="search_mcp",
    description="キーワード指定し、社内情報から検索し情報を取得します。",
    toolProperties=tool_properties_json,
)
def search_mcp(context) -> list:
    context_json=json.loads(context)
    search_query = context_json['arguments'].get('search_query')

    # Initialize the SearchClient
    client = SearchClient(
        endpoint=f"https://{AZURE_SEARCH_SERVICE}.search.windows.net",
        index_name=AZURE_SEARCH_INDEX_NAME,
        credential=AzureKeyCredential(AZURE_SEARCH_API_KEY),
    )

    # Perform the search
    results = client.search(search_query)

    # Process and format the results
    formatted_results = []
    for result in results:
        formatted_results.append({
            "content":result.get('content')
        })

    return formatted_results

AI Searchのインデクスを作成する際に、ファイルの内容を登録するフィールド名をcontentとしました。

contentにはチャンク化したものが既に入っています。検索した結果のcontentをリスト形式で結果を返します。

今回、インデックスにJBSの決算短信を登録しました。

requirements.txt

以下の内容を記載します。

azure-functions==1.23.0
azure-search-documents==11.6.0b.11
host.json

以下の内容にします。

{
  "version": "2.0",
  "logging": {
    "applicationInsights": {
      "samplingSettings": {
        "isEnabled": true,
        "excludedTypes": "Request"
      }
    }
  },
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle.Experimental",
    "version": "[4.*, 5.0.0)"
  }
}

特に、以下の部分にExperimentalを付けます。

    "id": "Microsoft.Azure.Functions.ExtensionBundle.Experimental",
local.settings.json

VS Codeでローカル実行するため、環境変数を記載しておきます。

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "<blobの接続文字列>",
    "AZURE_SEARCH_SERVICE":"<AI Searchのサービス名>",
    "AZURE_SEARCH_INDEX_NAME": "<インデックス名>",
    "AZURE_SEARCH_API_KEY": "<AI SearchのAPIキー>",
    "FUNCTIONS_WORKER_RUNTIME": "python"
  }
}

ローカル実行

VS Codeからfunctionsを実行します。 ターミナルにURLが表示されます。

VS Codeローカル実行時のURL

Ctrl + Shift + P でコマンドパレットを開き、「MCP: Add Server...」を選択します。

コマンドパレット

「HTTP(server-sent events)」を選択します。

MCP type選択

ターミナルに表示されたURLを入力し、Enterを押下します。

URL入力

ここでは、mcpサーバーを識別する名前として「my-mcp-server-local」を入力します。

Server ID

「Workspace Settings」を選択します。

設定保存先の選択

.vscodeにmcp.jsonができます。

mcp.json

「Chat」から右上のアイコンをクリックします。

サーバースタート

「Select Tools...」アイコンをクリックし、作成したMCPサーバーを選択します。

アイコンクリック

ツール選択

チャットで社内情報から検索するように依頼します。

チャット入力

「Continue」をクリックします。

Continue

回答結果が表示されます。

回答結果

Azure環境で実行

デプロイ

まず、AzureポータルなどでAzure Functionsをデプロイします。ここではEast US にデプロイをしました。

続いて、Azure Functionsのコードをデプロイします。今回はVS Codeからデプロイを実行し、環境変数を設定しました。

デプロイ後、Azureポータルからシステムキーを取得します。

システムキー取得

ツール登録

ローカル実行した際と同様に、サーバーを登録します。

MCPサーバーのURL登録時にhttps://<funcappname>.azurewebsites.net/runtime/webhooks/mcp/sseを入力します。

<funcappname>の部分はAzureポータル画面に表示されている以下の部分を入力します。

funcappname

ローカル実行と同様に「Workspace Settings」を選択します。今回追加したサーバー情報がmcp.jsonに追記されます。

アクセスするためにはキーが必要なため、以下の様にシステムキーを入力することを求める設定を追記します。先程追記されたMCPサーバーの設定にheaders内にx-functions-keyを追記します。また、inputsの部分も追記します。

{
    "inputs": [
        {
            "type": "promptString",
            "id": "functions-mcp-extension-system-key",
            "description": "Azure Functions MCP Extension System Key",
            "password": true
        }
    ],
    "servers": {
        "my-mcp-server-Azure": {
            "type": "sse",
            "url": "https://<funcappname>.azurewebsites.net/runtime/webhooks/mcp/sse",
            "headers": {
                "x-functions-key": "${input:functions-mcp-extension-system-key}"
            }
        }
    }
}

再起動マークのアイコンをクリックします。

システムキーを求められるので入力し、Enterを押下します。

システムキー入力

ツールが選択されていることを確認します。

同様の質問をすることで、回答が得られました。

まとめ

Azure Functionsを用いて、PythonでMCPサーバーを実装しました。

今回は、決算短信の情報のみをAI Searchに登録していましたが、例えば、「社内情報として就業規則を登録しておき、任意のMCPクライアントから就業規則を参照する」といった、様々な応用ができます。

参考

執筆担当者プロフィール
齊藤 泰一

齊藤 泰一(日本ビジネスシステムズ株式会社)

機械学習系ソリューション開発、開発環境自動化などを担当。

担当記事一覧