C#でAzure AI Foundry Agent ServicesのMCPツールを使う

Azure AI Foundry Agent Servicesは、エージェント開発を強力に支援する最新のプラットフォームです。現段階ではプレビューですが、Model Context Protocol(MCP)ツールも利用可能です。

公式ドキュメントを調べたところ、英語版ページにはひっそりとC#のサンプルコードが掲載されていることを発見し、今回はそのコードを基に実際に動作確認を行います。

使用した環境

  • Azure.AI.Agents.Persistent 1.2.0-beta.2
  • C# コンソールアプリ(.NET 8)

前提

Azure AI Foundry Agent Servicesの以下のような基本的な知識を理解していること

  • 認証方法
  • データの処理の流れ

記事執筆時点(2025/8/15)のC# SDKのMCPツールの対応状況

OverviewのページのUsage Supportの表ではC#はまだ未対応であると記載されています。

learn.microsoft.com

しかし、以下のページのサンプルコードではC#が掲載されていました。
(※日本語にするとC#のタブが無くなるので、英語のままご覧ください)

learn.microsoft.com

今回はこのサンプルを基に実行・検証します

Microsoft Learn MCP Serverについて

本記事では「Microsoft Learn MCP Server」をツールとして利用します。

learn.microsoft.com

これは、Microsoftが提供しているMCPサーバーで、Azureやその他Microsoft技術の最新情報などを取得することができます。

パッケージのインストール

以下の2つをインストールします。

dotnet add package Azure.AI.Agents.Persistent --version 1.2.0-beta.2
dotnet add package Azure.Identity

ソースコード

サンプルコードを基に、Microsoft Learn MCPサーバーをツールとして利用するエージェントを作ってみました。

using Azure;
using Azure.AI.Agents.Persistent;
using Azure.Identity;


// 環境変数の取得
var projectEndpoint = "<Azure AI Foundryのプロジェクトエンドポイント>";
var modelDeploymentName = "<作成済みのモデル名>";

// MCPサーバーのURLとラベル(Microsoft Learn MCP Server)
var mcpServerUrl = "https://learn.microsoft.com/api/mcp";
var mcpServerLabel = "Microsoft_Docs_MCP_Server";

// エージェントの作成
PersistentAgentsClient agentClient = new(projectEndpoint, new DefaultAzureCredential());

// MCP tool definitionの作成
MCPToolDefinition mcpTool = new(mcpServerLabel, mcpServerUrl);

PersistentAgent agent = agentClient.Administration.CreateAgent(
   model: modelDeploymentName,
   name: "ms-docs-mcp-agent",
   instructions: "\"あなたは親切なアシスタントです。提供されたツールを使って、ユーザーの質問に答えてください。ツールを利用した場合、必ず出典を引用してください。",
   tools: [mcpTool]
);

// スレッドの作成
PersistentAgentThread thread = agentClient.Threads.CreateThread();

// 対話式でユーザーメッセージを取得
string defaultMessage = "Azure AI Foundryの2025年の最新のアップデート情報を教えてください。";
Console.WriteLine($"ユーザーメッセージを入力してください(デフォルト: {defaultMessage}:");
string? userInput = Console.ReadLine();
string userMessage = string.IsNullOrEmpty(userInput) ? defaultMessage : userInput;

// スレッドにユーザーメッセージを追加
PersistentThreadMessage message = agentClient.Messages.CreateMessage(
    thread.Id,
    MessageRole.User,
    userMessage);

// MCPツールを使用するためのリソースを作成
MCPToolResource mcpToolResource = new(mcpServerLabel);
ToolResources toolResources = mcpToolResource.ToToolResources();

// Agentを使用してスレッドを実行
ThreadRun run = agentClient.Runs.CreateRun(thread, agent, toolResources);

// エージェントの実行を待機
while (run.Status == RunStatus.Queued || run.Status == RunStatus.InProgress || run.Status == RunStatus.RequiresAction)
{
    Thread.Sleep(TimeSpan.FromMilliseconds(1000));
    run = agentClient.Runs.GetRun(thread.Id, run.Id);

    if (run.Status == RunStatus.RequiresAction && run.RequiredAction is SubmitToolApprovalAction toolApprovalAction)
    {
        var toolApprovals = new List<ToolApproval>();
        foreach (var toolCall in toolApprovalAction.SubmitToolApproval.ToolCalls)
        {
            if (toolCall is RequiredMcpToolCall mcpToolCall)
            {
                // ツール利用ログに記録
                Console.WriteLine($"Tool used: {mcpToolCall.Name}, Arguments: {mcpToolCall.Arguments}");
                toolApprovals.Add(new ToolApproval(mcpToolCall.Id.ToString(), approve: true));
            }
        }

        if (toolApprovals.Count > 0)
        {
            run = agentClient.Runs.SubmitToolOutputsToRun(thread.Id, run.Id, toolApprovals: toolApprovals);
        }
    }
}

// エージェントの実行結果を取得
Pageable<PersistentThreadMessage> messages = agentClient.Messages.GetMessages(
    threadId: thread.Id,
    order: ListSortOrder.Ascending
);

// メッセージの出力
foreach (PersistentThreadMessage threadMessage in messages)
{
    Console.Write($"{threadMessage.CreatedAt:yyyy-MM-dd HH:mm:ss} - {threadMessage.Role,10}: ");
    foreach (MessageContent contentItem in threadMessage.ContentItems)
    {
        if (contentItem is MessageTextContent textItem)
        {
            Console.Write(textItem.Text);
        }
        else if (contentItem is MessageImageFileContent imageFileItem)
        {
            Console.Write($"<image from ID: {imageFileItem.FileId}>");
        }
        Console.WriteLine();
    }
}

// 後処理 スレッドとエージェントを削除
agentClient.Threads.DeleteThread(threadId: thread.Id);
agentClient.Administration.DeleteAgent(agentId: agent.Id);

動作確認

アプリを実行すると以下のようなメッセージが表示されます。

ユーザーメッセージを入力してください(デフォルト: Azure AI Foundryの2025年の最新のアップデート情報を教えてください。:

今回はデフォルトメッセージにするので、何も入力せずにEnterを押します。

少し待つと、以下のように質問の回答がマークダウン形式で表示されます。最新の情報を取得して回答してくれています。

Tool used: microsoft_docs_search, Arguments: {"query":"Azure AI Foundry 2025 update"}
2025-08-15 02:51:46 -       user: Azure AI Foundryの2025年の最新のアップデート情報を教えてください。
2025-08-15 02:51:57 -  assistant: Azure AI Foundryの2025年の最新アップデートについて、以下の情報が公開されています:

### 主な新機能と更新内容
1. **新しいツールとモデル**
   - 最新のビデオ生成AIモデル「Sora」がリリースされました(プレビュー)。テキスト指示に基づいてリアルな映像を生成できます。
   - 新しい画像生成モデル「GPT-image-1」がプレビューとしてリリースされ、画像編集や部分的なストリーミングの機能を提供します。
   - リアルタイムAPIがWebRTCをサポートし、リアルタイムオーディオストリーミングや低遅延インタラクションが可能です。

2. **エージェントサービスの進化**
   - Azure AI Foundry Agent Serviceが一般提供 (GA) され、新しい機能として以下が追加されました:
      - Visual Studio Codeエクステンションを使用したエージェントのネイティブ構築機能。
      - **Connected Agents**を利用することで、タスク特化型のエージェントを簡単に構成可能。
      - Azure Logic Appsを用いてイベントをトリガーし、エージェントを自動的に起動。
      - MorningstarやBingカスタム検索ツールなど、新しいデータソースツール。

3. **新しいAIモデル**
   - Reasoningモデル「codex-mini」や「o3-pro」が利用可能に。
   - GPT-4.5 プレビュー版の公開。画像およびテキストタスクに優れた能力が特徴。
   - GPT-4o音声モデルの追加で、音声・テキスト・リアルタイム音声ベースの強力な対話が可能に。

4. **その他の拡張と実用例**
   - AI Foundryのエージェントをクラウド外のサポート環境で評価するためのSDKや、生成AI評価向けのシミュレーションツールが提供されました。
   - Azure Monitorとの統合で、エージェントの利用状況の可視化や計測。

詳細な情報は、以下の公式リンクをご参照ください(英語):

- [Azure AI Foundry 最新情報](https://learn.microsoft.com/en-us/azure/ai-foundry/whats-new-azure-ai-foundry)
- [Azure OpenAIモデル更新内容 (2025)](https://learn.microsoft.com/en-us/azure/ai-foundry/openai/whats-new)

追加確認が必要な場合は教えてください!

補足

提示したコードはAzure.AI.Agents.Persistentのバージョンが1.2.0-beta.1だと以下の部分で例外が発生します。

run = agentClient.Runs.SubmitToolOutputsToRun(thread.Id, run.Id, toolApprovals: toolApprovals);

原因は分からなかったのですが、8/14にリリースされた1.2.0-beta.2にアップデートしたところ、このエラーは発生しなくなりました。SDK側の不具合だった可能性があります。

おわりに

Microsoft Learnから情報を取得して回答してくれるのはかなり助かりますね。

C#でもMCPツールを利用してみたいという方は、今回の記事をぜひ参考にしてみてください。

参考リンク

qiita.com

blog.jbs.co.jp

執筆担当者プロフィール
古川 貴浩

古川 貴浩(日本ビジネスシステムズ株式会社)

アプリケーション開発をしています。.NETやAI関連が好きです。

担当記事一覧