Azure MCP ServerとStreamlitでAzureを対話的に操作するWebアプリ

この記事では、AzureMCPServerとStreamlitを組み合わせて、Azureリソースを対話的に操作するWebアプリケーションを構築する方法について説明します。

つまり以下のように「Azureのコレコレのリソースの情報取得して」とか「Azure Blob Storageのコンテナ作って」みたいにWebブラウザから対話的に指示すると、そのとおりにAzureリソースが出来上がるWebアプリをサクッと作ってしまおうという感じです。

説明はいいからサクッと動かしたいよーという方はソースコードと起動方法を以下のGitリポジトリで公開しているので、そちらを参照してください。

https://github.com/noriyukitakei/azure-mcp-server-webif

Azure MCP Serverとは?

Azure MCP Serverとは、Azureが提供しているMCPサーバーであり、Azureリソースの管理や操作を行うための機能を提供します。

https://learn.microsoft.com/ja-jp/azure/developer/azure-mcp-server/tools/

MCP(Model Context Protocl)に準拠しているので、MCPに対応しているクライアントであれば、Visual Studio CodeやCursor、Eclipse、IntelliJなど、様々な開発環境からAzureリソースを操作することができます。

今回構築するWebアプリケーションについて

Visual Studio Code などから Azure MCP Server と連携する例は多く紹介されていますが、本記事では Streamlit を使って Web インターフェースを構築し、Azure MCP Server と連携する方法 を紹介します。これにより、ブラウザ上から Azure リソースを対話的に操作できるようになり、より多くのユーザーにとって使いやすいインターフェースを提供できます。

ただし、適切な権限管理を行わないと、意図しない Azure リソースの変更が発生する可能性があるため注意してください。

今回構築するアプリのソースコードは以下のGitHubリポジトリで公開しています。

https://github.com/noriyukitakei/azure-mcp-server-webif.git

構成

今回構築するシステムの構成は以下の通りです。

UIを提供するStreamlit、LLMによる思考を担うAIエージェント、MCPクライアント、Azure MCP Serverの4つのコンポーネントで構成されます。UI、AIエージェント、MCPクライアントは同一のWebアプリケーション(プロセス)内で動作し、Azure MCP Serverとの通信方式はSTDIO(標準入出力)を使用します。

UI

Webアプリケーションのユーザーインターフェース部分です。Streamlitを使用して構築します。ユーザーからの入力を受け取り、結果を表示します。

Streamlitは、Pythonを使って簡単にインタラクティブなWebアプリケーションを作成できるオープンソースのフレームワークです。プログラミングの経験が少なくても、Pythonコードを書くだけで、データビジュアライゼーションやインターフェースを持つアプリをすぐに作ることができるのが特徴です。

従来、Webアプリケーションを作成するには、フロントエンド(HTML、CSS、JavaScript)とバックエンド(Python、Django、Flaskなど)の両方の技術を理解する必要がありました。しかし、Streamlitを使えば、Pythonだけでフロントエンドとバックエンドを同時に構築できるため、非常に手軽にアプリ開発に取り組めます。

たとえば、データサイエンティストがモデルの結果を共有したり、エンジニアがプロトタイプを素早く作成したりする場面でよく利用されています。

AIエージェント

ユーザーからの指示を受け取り、適切なアクションを判断し、必要に応じてMCPサーバーにリクエストを送信します。

Function Callingを活用し、AIエージェントの思考と行動を実現します。Function Callingに対応したLLMを使用する必要があるため、今回は Azure OpenAI Serviceを利用しますが、他の対応LLMに置き換えることも可能です。

なお、AIエージェントは LangChainのようなAIエージェントフレームワークを用いて実装することもできます。しかし今回は学習を目的として、できるだけシンプルな独自実装で進めます。そのため、コードはやや冗長であり、実際のアプリケーションで使用するには最適化が必要な部分もありますが、基本的な仕組みを理解するには十分な内容になっています。

MCPクライアント

MCPクライアントは、FastMCPを用いて実装しています。FastMCP は、MCPサーバーとMCPクライアントの両方の機能を提供するライブラリであり、ここではMCPクライアントとして使用します。

MCPサーバー

Azure MCP Server本体になります。Azureリソースの管理や操作を行うための機能を提供します。npxやnpm、Dockerで起動する方法がありますが、今回はDockerで起動し、通信方式はSTDIO(標準入出力)を使用します。

処理の流れ

今回構築するWebアプリケーションの処理の流れは以下の通りです。

[ステップ1] ユーザーが指示を入力

ユーザーはWebアプリケーションのUIを通じて、Azureリソースに対する操作指示を入力します。例えば「ストレージ アカウント ‘ntakeiassets’ のコンテナー ‘images’ の ‘log4j.png’ の詳細を教えて」と入力するとします。

その指示は、StreamlitによるUIを通じてAIエージェントに送信されます。

[ステップ2] MCPサーバーへの初期化要求

MCPクライアントは、initializeというメソッドで初期化メッセージを最初に送ります。これは、MCPクライアントがMCPサーバーに対して「自分の機能・情報・バージョンなどを伝えて、接続を初期化したい」とリクエストしているメッセージです。

[ステップ3] MCPサーバーからの初期化応答

MCPサーバーはinitializeリクエストを受け取り、初期化応答を返して、自身のプロトコルのバージョンなどをMCPクライアントに伝えます。

[ステップ4] 初期化完了通知の送信

MCPクライアントは、MCPサーバーからの初期化応答を受け取り、初期化が完了したことをMCPサーバーに通知します。

[ステップ5] ツールの一覧取得

MCPクライアントは、tools/listというメソッドでツールの一覧(そのMCPサーバーが持っている機能の一覧)をMCPサーバーにリクエストします。これにより、MCPサーバーが提供するツールの情報を取得します。

[ステップ6] ツール一覧の応答受信

MCPサーバーは、tools/listリクエストを受け取り、提供するツールの一覧をMCPクライアントに返します。ここではAzure MCP Serverが提供するツールの一覧(Azure Blob StorageやAzure AI Searchなどのリソースを操作するコマンド一覧)が返されます。

[ステップ7] LLMへのFunction Calling指示

AIエージェントは、MCPクライアントから渡されたツール一覧をもとに、LLMに対してFunction Callingを行うよう指示します。具体的には、ユーザーからのプロンプトを解析してどのツールを呼び出すべきかを判断し、そのツールを使うようLLMに指示します。

ここでは、ユーザーの質問である「ストレージ アカウント ‘ntakeiassets’ のコンテナー ‘images’ の ‘log4j.png’ の詳細を教えて」とともに、tools/listで取得したツール一覧をLLMに渡します。

[ステップ8] LLMからの関数呼び出し応答

LLMは、AIエージェントからのFunction Calling指示を受け取り、適切な関数呼び出し応答を生成します。この応答には、呼び出す関数名とそのパラメータが含まれます。

ここでは、sotorageというツールをLLMが選択したことがわかります。これはAzure Blob Storageの情報を取得するためのツールであり、ユーザーの質問に対して適切な選択となります。

[ステップ9] MCPサーバーへの関数呼び出しリクエスト

AIエージェントはLLMからの関数呼び出し応答を受け取り、MCPクライアントを介してMCPサーバーに関数呼び出しリクエストを送信します。これにより、MCPサーバーに対して指定された関数を実行させます。

[ステップ10] MCPサーバーからの関数呼び出し応答

MCPサーバーは、MCPクライアントからの関数呼び出しリクエストを受け取り、指定された関数を実行します。その結果をMCPクライアントに返します。

今回は、Azure Blob Storageのさらに細かいコマンド一覧が返されています。

つまり、1回目のツール一覧取得では大まかなツール一覧が返され、2回目の関数呼び出し応答では、さらに詳細なコマンド一覧が返される形となっています。

[ステップ11] LLMへの追加Function Calling指示

ステップ11で取得した詳細なコマンド一覧をもとに、AIエージェントはLLMに対して追加のFunction Callingを行うよう指示します。これにより、ユーザーの質問に対してさらに具体的な回答を生成するための情報を提供します。

[ステップ12] LLMからの関数呼び出し応答

LLMは、AIエージェントからの追加Function Calling指示を受け取り、適切な関数呼び出し応答を生成します。この応答には、呼び出す関数名とそのパラメータが含まれます。

以下のような応答が返され、Azure Blob Storageの特定のコンテナ内にあるファイルの詳細情報を取得するための関数呼び出しが示されています。
"function_call": {
  "name": ”storage_blob_get",
  "arguments": "{'account': 'ntakeiassets', 'container': 'images', 'blob': 'log4j.png'}"
}
つまりこれは、storage_blob_getというコマンドを用いて、ストレージアカウント ‘ntakeiassets’ のコンテナ ‘images’ 内の ‘log4j.png’ というファイルの詳細情報を取得するための関数呼び出しを意味しています。

[ステップ13] MCPサーバーへの関数呼び出しリクエスト

AIエージェントはLLMからの関数呼び出し応答を受け取り、MCPクライアントを介してMCPサーバーに関数呼び出しリクエストを送信します。これにより、MCPサーバーに対して指定された関数を実行させます。

[ステップ14] Azure Resource ManagerへのAPIリクエスト

MCPサーバーは、MCPクライアントからの関数呼び出しリクエストを受け取り、そのコマンドをAzure Resource Manager (ARM) へのAPIリクエストに変換して実行します。これにより、Azureリソースに対する操作が行われます。

[ステップ15] MCPサーバーからの関数呼び出し応答

MCPサーバーは、Azure Resource ManagerからのAPIレスポンスを受け取り、その結果をMCPクライアントに返します。

今回は、指定されたストレージアカウント、コンテナ、ファイルに関する詳細情報が返されます。これには、ファイルのサイズ、作成日時、更新日時、コンテンツタイプなどのメタデータが含まれています。

[ステップ16] LLMへの最終Function Calling指示

AIエージェントはMCPクライアントからの関数呼び出し応答を受け取り、LLMに対して最終的なFunction Callingを行うよう指示します。これにより、ユーザーの質問に対する最終的な回答を生成するための情報を提供します。

[ステップ17] LLMからの最終応答

LLMは、AIエージェントからの最終Function Calling指示を受け取り、ユーザーの質問に対する最終的な応答を生成します。この応答には、Azureリソースに関する詳細情報が含まれています。

そして、AIエージェントはこの最終応答をWebアプリケーションのUIに返します。

起動方法

処理の流れをご理解いただけたところで、実際にアプリケーションを起動して動作させてみましょう。以下の手順で進めてください。

[ステップ1] リポジトリのクローン

まず、GitHubリポジトリをクローンします。ターミナルを開き、以下のコマンドを実行してください。

$ git clone https://github.com/your-repository-url.git
$ cd your-repository-directory

[ステップ2] 環境変数の設定

次に、必要な環境変数を設定します。`.env.example`ファイルをコピーして`.env`ファイルを作成し、必要な値を設定してください。
$ cp .env.example .env
.envファイル内で設定する主な環境変数は以下の通りです。

  • AZURE_OPENAI_ENDPOINT: Azure OpenAI ServiceのエンドポイントURL
  • AZURE_OPENAI_API_KEY: Azure OpenAI ServiceのAPIキー
  • AZURE_OPENAI_API_VERSION: 使用するAPIバージョン (例: 2024-06-01)
  • AZURE_OPENAI_CHAT_DEPLOYMENT: 使用するチャットモデルのデプロイメント名 (例: gpt-4)`
  • MAX_STEPS: AIエージェントが実行する最大ステップ数 (例: 5)
  • AZURE_TENANT_ID: AzureテナントID
  • AZURE_SUBSCRIPTION_ID: AzureサブスクリプションID
  • AZURE_CLIENT_ID: AzureクライアントID
  • AZURE_CLIENT_SECRET: Azureクライアントシークレット

AZURE_OPENAI_ENDPOINTAZURE_OPENAI_API_KEYAZURE_OPENAI_CHAT_DEPLOYMENTは、Azure OpenAI Serviceに接続するための情報となります。これはLLMにFunction Callingを実行させるために必要です。

AZURE_TENANT_IDAZURE_SUBSCRIPTION_IDAZURE_CLIENT_IDAZURE_CLIENT_SECRETは、Azure MCP ServerがAzureリソースにアクセスするための情報となります。これらの値はAzureポータルでアプリケーション登録を行い、サービスプリンシパルを作成することで取得できます。そして、そのサービスプリンシパルに対して必要なAzureリソースへのアクセス権限を付与してください。例えば、ストレージアカウントの情報を取得する場合は、「ストレージ アカウント閲覧者」ロールを付与します。

MAX_STEPSは、AIエージェントが実行する最大ステップ数を指定します。これにより、無限ループを防止できます。もしこれを設定しないと、AIエージェントが過剰に多くのステップを実行し、Azure OpenAI Serviceにすごいい数のリクエストを送ってしまう可能性があります。結果、コストが高額になる恐れがあるため、適切な値を設定してください。

[ステップ3] 依存関係のインストール

次に、必要なPythonパッケージをインストールします。以下のコマンドを実行してください。

$ pip install -r requirements.txt

[ステップ4] アプリケーションの起動

ブラウザでhttp://localhost:8501にアクセスし、Azureリソースに対する操作指示を入力してみてください。例えば、「ストレージ アカウント ‘ntakeiassets’ のコンテナー ‘images’ の ‘log4j.png’ の詳細を教えて」と入力すると、アプリケーションがAzure MCP Serverと連携して情報を取得し、結果を表示します。

まとめ

いかがでしょうか。Webブラウザから対話的にAzureリソースを操作できるのは非常に便利です。Azure MCP ServerとStreamlitを組み合わせることで、ユーザーにとって使いやすいインターフェースを提供できます。こんな感じで今後も、Azureの様々なサービスと連携したWebアプリケーションを構築していきたいと思います。ぜひ皆さんも試してみてください。
ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です