0
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?

【MCPサーバー作成】ローカル実行を諦め、Azure Functions上のMCPサーバー作成になった話

0
Last updated at Posted at 2026-07-12

概要

Azure FunctionsでカスタムMCPツールを作り、それが実際に外部から呼び出せるかを検証したい。そう思って動き始めたのですが、ローカル実行のための下準備(Azure Functions Core Tools)のインストールで何度も足止めを食らいました。

そこで発想を変えました。

「そもそもローカルで動かす必要、ある? Azureに直接デプロイして、リモートで動いているのを確認すればよくない?」

この記事は、その発想の転換にたどり着くまでの顛末と、実際にAzure上のMCPツールをVS CodeのGitHub Copilotから呼び出せるようになるまでの記録です。

前提

  • Azure Portal上でリソースグループ・Azure Functionは作成済み
    • リソースグループ:{作成したリソースグループ名}
    • Azure Function:{作成したfunction名}(Flex Consumption・Python・Application Insights同時作成)
    • ※実はここに至るまでにも一悶着あったので、詳しくは「秘話」で
  • Azureサブスクリプションは従量課金制(Pay-As-You-Go)
    • 私の場合、無料期間のクレジットが残っている状態ですぐ登録したので、実質無料という認識で進めています(※※※ 間違っていたら教えてください ※※※)
  • ローカル環境(Mac)
    • OS:macOS Tahoe version 26.3.1
    • Python 3.11.15
    • Homebrew導入済み
    • Azure CLI導入・az login済み
    • uv:結局出番なし(後述)
  • VS Code拡張機能
    • Azure Functions(ms-azuretools.vscode-azurefunctions
    • Azure Developer CLI (azd)(ms-azuretools.azure-dev
    • Azurite(ローカルストレージエミュレーター。※これも結果的に未使用)
    • GitHub Copilot Chat(Agentモードでの呼び出し確認に必須)

目標

とりあえず、Azure Function上にあるカスタムMCPサーバーを呼び出したい!!!

課題

まずはデプロイする前に、ローカル構築して確認するぞ!!!

と思いきや・・・

Azure Functions拡張機能でMCPツールのプロジェクトを作成し、いざローカルでF5デバッグしようとしたところ、以下のエラーで止まり・・・

You must have the Azure Functions Core Tools installed to debug your local functions.

「じゃあCore Tools更新するか〜」と試みたのですが、ここから泥沼が始まりました(詳細は「躓いたこと」で)。

最終的にはディスクの空き容量不足という物理的な壁にぶつかり、ローカル実行の下準備を整えること自体を諦めることにしました・・・

容量足りない・・・.png

そこで!!!

funcコマンドは、そもそもローカルで関数を実行・デバッグするためだけのツール。
そこで・・・

ローカル実行を経由せず、直接Azureにデプロイして、リモートで動作確認すればいい。

というわけで、Azure CLIでのzipデプロイ(az functionapp deployment source config-zip)に切り替えました。


ゴールイメージ

起動方法と成功画面

  1. .vscode/mcp.jsonに登録したリモートサーバー(remote-mcp-server)の「起動」を押下
  2. GitHub Copilot ChatをAgentモードにして、#remote-mcp-serverでツール呼び出しをチャットで指示
  3. 以下のように、Azure Functions上で実行された結果が返ってきた
リモートからの呼び出しに成功したぞ〜!!!!!!!

成功画面.png

全体図

ローカルとAzureの間で、デプロイ・呼び出し・応答がどう流れているかをまとめると以下の通りです。

Qiita投稿用.png


試したこと

成功例

ざっくり

  • Azure Functions上にMCPサーバーを構築→VS CodeのGitHub Copilot Chatから実際に呼び出せることを検証しました。
  • ローカルのデバッグ環境(Azure Functions Core Tools)は用意せず、VS Codeのテンプレート機能で生成したコードを最小限だけ編集し、Azure CLIで直接デプロイする方法を取っています。
  • 結果として、Core Toolsなし・ローカル実行なしでも、Azure上のMCPツールが正しく呼び出せることを確認できました。

(できたときは本当に感動しました・・・)

詳細

下準備(テンプレを作成する)

まず、VS Codeのコマンドパレット(Cmd+Shift+P)で以下を実行します。

Azure Functions: Create New Project...

出てくるプロンプトには、以下のように答えました。

プロンプト 選択内容
プロジェクトの種類 Python
Pythonインタープリター 使いたいものを選択
最初の関数のテンプレート MCP Tool trigger
関数名 mcp_trigger
認可レベル FUNCTION(リモート接続時にアクセスキーが必要になる設定)
プロジェクトの開き方 現在のウィンドウで開く

これだけで、host.jsonrequirements.txtfunction_app.pyなど、必要な材料一式が自動生成されます。ゼロから書く必要はありません。

実際に自分で編集したのは、生成されたコードのうちPythonの中身、しかもMCPツールに関する部分だけです。具体的には以下の状態にしました。
ダミーの挨拶を返すだけの、最小構成のMCPツールです。

import azure.functions as func
import logging

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

@app.mcp_tool_trigger(
    arg_name="context",
    type="mcpToolTrigger",
    tool_name="hello_mcp",
    description="リモートからの呼び出しに成功したぞ〜!!!!!!!を返したい",
    toolProperties="[]",
)
def mcp_trigger(context) -> None:
    return "リモートからの呼び出しに成功したぞ〜!!!!!!!"

hello worldだと、Copilotが雰囲気読んで返している可能性があったため、めちゃくちゃわかりやすいものにしています。
あと、呼び出された時に出てくるものって達成感あるものにしたいじゃないですか・・・(気持ちわかりません?)

Azure Portalへデプロイしよう!

これをAzureにデプロイして、動作確認するまでの流れです。

  1. zip化する。

    zip -r ../deploy.zip . -x "local.settings.json" -x ".venv/*" -x "__pycache__/*" -x ".vscode/*" -x "*.git*"
    
  2. Azure CLIでデプロイする。

    az functionapp deployment source config-zip \
      --resource-group {作成したリソースグループ名} \
      --name {作成したfunction名} \
      --src ../deploy.zip
    
  3. アクセスキー(functions-key)を取得する。Azure Portalで対象のFunction App({作成したfunction名})を開き、左メニュー「関数」→「アプリ キー」→「システム キー」の中にある mcp_extension という名前のキーの値をコピーする。

    作成した関数名.png

  4. .vscode/mcp.jsonにリモートのMCPエンドポイントを登録する。

    {
        "servers": {
            "remote-mcp-server": {
                "type": "http",
                "url": "https://<Function Appの実際のホスト名>/runtime/webhooks/mcp",
                "headers": {
                    "x-functions-key": "${input:functions-key}"
                }
            }
        },
        "inputs": [
            {
                "type": "promptString",
                "id": "functions-key",
                "description": "Functions App Key",
                "password": true
            }
        ]
    }
    

    サーバーを起動するとfunctions-keyの入力欄が表示されるので、3で取得したmcp_extensionの値を貼り付ける。

  5. GitHub Copilot ChatをAgentモードにして、remote-mcp-serverのツールを呼び出す。

    #remote-mcp-server で挨拶して
    

Core Toolsなし・ローカル実行なしのまま、Azure上のMCPツールが呼び出せることを確認できました。

躓いたこと

Azure Functions Core Toolsインストール地獄

F5デバッグのために言われるがままCore Toolsを入れようとしたら、次々に別の壁が出てきました。

  1. brew install azure-functions-core-tools@4 を実行しても func --versioncommand not found

  2. brew doctorで原因判明。タップが信頼されていない という警告が出ていた

    Warning: The following taps are not trusted:
      azure/functions
    

    brew trust azure/functions で信頼させて解決

  3. 気を取り直して再度インストールすると、今度は

    Error: Your Command Line Tools are too outdated.
    

    → Command Line Toolsの更新が必要と判明

  4. ところがPCの空き容量が足りず、更新できない

ここで「そもそもfuncはローカル実行専用では?」と気づき、ローカルデバッグを諦めてAzure CLIでの直接デプロイに切り替えた、というのが今回の一番の転換点でした。

Flexプラン特有のホスト名

デプロイ後、.vscode/mcp.json

https://{作成したfunction名}.azurewebsites.net/runtime/webhooks/mcp

と決め打ちで書いたところ、以下のエラーで接続できませんでした。

Error sending message to https://{作成したfunction名}.azurewebsites.net/runtime/webhooks/mcp: TypeError: fetch failed: getaddrinfo ENOTFOUND {作成したfunction名}.azurewebsites.net

原因は単純で、Flex Consumptionプランのアプリは名前衝突を避けるため、実際のホスト名にユニークな名前が自動で付く仕様でした。
正式なホスト名を確認した手順は以下の通りです。

クエリを絞らずに、リソースの詳細をまるごと取得する。

az functionapp show --name {作成したfunction名} --resource-group {作成したリソースグループ名}

返ってきたJSONの中からhostnamedefaultHostName)の項目を探す。すると、実際は

{作成したfunction名}-xxxxxxxxxxxxxxxx.eastus-01.azurewebsites.net

という、決め打ちしていた形とは違うユニークな名前でした。

見つかった正式なホスト名で.vscode/mcp.jsonのURLを書き換える。すでにAzure上にはデプロイ済みだったので、VS Code側でremote-mcp-serverを再起動し、GitHub Copilot Chatから呼び出したところ成功しました。
決め打ちせずに、必ずaz functionapp showで正式なホスト名を確認するのが安全そうです。


まとめ

  • Azure FunctionsでMCPサーバーを検証したいだけなら、ローカル実行環境(Core Tools・F5デバッグ)を整える必要は必ずしもない
  • az functionapp deployment source config-zip を使えば、Flex Consumptionプランでもリモートビルド・zipデプロイでコードを反映できる
  • 動作確認は、VS Codeのmcp.jsonにリモートのMCPエンドポイントを登録し、GitHub Copilot ChatのAgentモードから呼び出すだけで十分できる
  • Flex Consumptionのホスト名は<名前>.azurewebsites.netという単純な形にならないことがあるので、az functionapp showで必ず確認する

「ローカル環境を完璧に整えてから動かす」のではなく「とりあえずクラウドに上げて動くか見る」という進め方の方が早いこともある、という学びでした。(←あまりあてにはならないと思うけど・・・)

秘話

実はここに至るまでにも一悶着ありました。当初、無料試用版のサブスクリプションでリソース作成を進めていたのですが、Function AppをFlex Consumptionプランで作ろうとすると、こう出ました。

無料試用版サブスクリプションは、Flex 従量課金 ではサポートされていません。別のサブスクリプションを選択してください。

「じゃあApp Serviceでいいか」と別プランを試したら、今度はこうです。

無料試用版サブスクリプションは、App Service ではサポートされていません。別のサブスクリプションを選択してください。

無料試用版は一部SKUがそもそも対象外という仕様だったため、結局サブスクリプションを従量課金制(Pay-As-You-Go)へアップグレードしました。なお公式ドキュメントによると、アップグレードしても元のサインアップから30日間は残っているクレジットがそのまま使え、アップグレード後12ヶ月間は無料サービス枠も継続するとのことなので、検証目的であれば実質無料の感覚で進められています。

追記・更新・発見情報

【Flexプラン特有のホスト名】の箇所について

Azure Portal > 概要 > 既定のドメイン にドメイン名が記載されていました。
そっちの方が早い・・・

0
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
0
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?