🙆

Azure Functions で MCP サーバーが作れるようになりました!

に公開

更新履歴

  • 2025/04/07 Azure へのデプロイについて追記
  • 2025/04/27
    • Program.cs のコードを追加 (MKURI さん Thank you!)
    • 最新パッケージに更新
    • 230 秒以上たってもエラーにならなくなったので、そこについての言及を削除

はじめに

Azure Functions で MCP サーバーが作れるようになりました!

Build AI agent tools using remote MCP with Azure Functions

桜の時期のお気に入りの散歩コースを歩いて記事を書こうと思ったら、JP さんに先を越されてました…。

Azure FunctionsでMCPサーバーを作る!

試してみよう

JP さんのやっていることと同じにはなりますが、私は Visual Studio 2022 で C# のみでやります。

まずは Azure Functions のプロジェクトを作成します。.NET 9 を選んで作る必要があるので注意してください。さらに今回は .NET Aspire の機能も使いたいと思っているので .NET Aspire オーケストレーションへの参加 (プレビュー) をオンにしました。プロジェクト名は McpAzureFunctions という名前で作成しました。この後のコード例は、このプロジェクトで作成した前提のコードになります。次に以下の NuGet パッケージをインストールします。

  • Microsoft.Azure.Functions.Worker.Extensions.Mcp v1.0.0-preview.2

次に、Azure Functions のプロジェクトの Program.cs を以下のように変更します。MCP のツールを有効化するために EnableMcpToolMetadata を追加しています。

Program.cs
using Microsoft.Azure.Functions.Worker.Builder;
using Microsoft.Extensions.Hosting;

var builder = FunctionsApplication.CreateBuilder(args);

builder.AddServiceDefaults();

builder.ConfigureFunctionsWebApplication();
builder.EnableMcpToolMetadata(); // この行を追加

// Application Insights isn't enabled by default. See https://aka.ms/AAt8mw4.
// builder.Services
//     .AddApplicationInsightsTelemetryWorkerService()
//     .ConfigureFunctionsApplicationInsights();

builder.Build().Run();

次に天気予報を返してくれる関数を作成します。以下のようなコードにしました。

using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Extensions.Mcp;
using System.ComponentModel;

namespace McpAzureFunctions;

public class MyMcpTools
{
    [Function(nameof(GetWeatherForecast))]
    public WeatherForecastResult GetWeatherForecast(
        [McpToolTrigger(nameof(GetWeatherForecast), "指定された場所の天気予報を取得します。")] 
        ToolInvocationContext context,
        [McpToolProperty(nameof(location), "string", "天気を知りたい場所の名前")] 
        string location)
    {
        return location switch
        {
            "東京" => new WeatherForecastResult("東京", "晴れ"),
            "大阪" => new WeatherForecastResult("大阪", "曇り"),
            "福岡" => new WeatherForecastResult("福岡", "雨"),
            _ => new WeatherForecastResult(location, "不明"),
        };
    }
}

public record WeatherForecastResult(
    string Location,
    string Weather);

これで実行して Azure Functions のプロジェクトの標準出力を確認すると、以下のような出力がされます。

Azure Functions Core Tools
Core Tools Version:       4.0.7030 Commit hash: N/A +bb4c949899cd5659d6bfe8b92cc923453a2e8f88 (64-bit)
Function Runtime Version: 4.1037.0.23568
 
[2025-04-24T04:09:30.847Z] Found D:\XXXX\McpAzureFunctions.csproj. Using for user secrets file configuration.
Skipping 'AzureWebJobsStorage' from local settings as it's already defined in current environment variables.
Skipping 'FUNCTIONS_WORKER_RUNTIME' from local settings as it's already defined in current environment variables.
[2025-04-24T04:09:54.051Z] MCP server SSE endpoint: http://localhost:7071/runtime/webhooks/mcp/sse
[2025-04-24T04:10:00.047Z] Azure Functions .NET Worker (PID: 28332) initialized in debug mode. Waiting for debugger to attach...
[2025-04-24T04:10:00.097Z] Worker process started and initialized.
 
Functions:
 
	GetWeatherForecast: mcpToolTrigger
 
For detailed output, run func with --verbose flag.

ちゃんと mcpToolTrigger で GetWeatherForecast が登録されているのがわかります。さらに MCP server SSE endpoint も表示されています。この MCP ツールを試してみましょう。AppHost プロジェクトの Program.cs に以下のコードを追加して @modelcontextprotocol/inspector を実行するようにします。

Program.cs
builder.AddExecutable(
    "mcp-inspector",
    "npx",
    ".",
    "@modelcontextprotocol/inspector", 
    "node", 
    "build/index.js")
    .WithHttpEndpoint(8080,6274);

実行すると以下のように .NET Aspire のダッシュボードに mcp-inspector が表示されます。

mcp-inspector の部分に表示されているエンドポイントを選択すると以下のような画面が出るので、SSE を選んで http://localhost:7071/runtime/webhooks/mcp/sse (ポート番号は Azure Functions の標準出力に出力されているものです) を入力して Connect を押します。

そして List Tools を選択してツールを取得すると、以下のように GetWeatherForecast ツールが取得できます。そしてパラメーターを入れて実行をして結果を確認することが出来ます。

Azure にデプロイ

Azure にデプロイして動かしてみました。
注意点としては現時点では Windows の Azure Functions では動かないみたいです。Linux の Azure Functions で動かす必要があります。(情報提供土田さん!Thanks!)詳細は以下の GitHub Issue を参照してください。私もこれにはまってました。

https://github.com/Azure-Samples/remote-mcp-functions-dotnet/issues/8

Linux の Azure Functions にデプロイすることで、Visual Studio Code の GitHub Copilot の Agent モードから以下のような mcp.json を使って繋ぐことが出来ました。

mcp.json
{
    "inputs": [
        {
            "type": "promptString",
            "id": "functions-mcp-extension-system-key",
            "description": "Azure Functions MCP Extension System Key",
            "password": true
        }
    ],
    "servers": {
        "my-mcp-server-ac07bd21": {
            "type": "sse",
            "url": "https://<<関数アプリのリソース名>>.azurewebsites.net/runtime/webhooks/mcp/sse",
            "headers": {
                "x-functions-key": "${input:functions-mcp-extension-system-key}"
            }
        }
    }
}

サーバー起動時にシステムキーを入力するように言われるので Azure Functions のリソースのキーからシステムキーを作成して入力します。

この状態で試してみたところ以下のように、ちゃんと動作しました!

まとめ

Azure Functions で MCP サーバーが作れるようになりました。プレビューですが、一般提供開始になるとお手軽に MCP サーバーが作れるようになると思います。認証とかもサービス側で設定するだけで出来るようになるので、そこらへんも楽なポイントだと思います。

今回、試しに .NET Aspire と組み合わせて Model Context Protocol inspector を一緒に起動してみました。MCP サーバーの開発をする際には仕込んでおくと簡単に動作確認が出来るので楽だと思います。

ちゃんとテストするなら .NET Aspire のテスト機能でサーバーを実際に実行させて MCP クライアント系のライブラリで繋いでテストすることになるのかなと思います。

Microsoft (有志)

Discussion