使用说明
代理服务和远程MCP服务器入门(Python)
这是一个快速入门模板,可以轻松运行 Azure AI Foundry代理服务 客户端,然后使用以下命令将自定义远程MCP服务器添加到云中 Azure功能远程MCP。您可以通过调试在本地计算机上克隆/还原/运行,以及 azd up 几分钟后就可以把它放在云端了。MCP服务器通过使用密钥和HTTPS进行设计来保护,并允许使用内置身份验证和/或 API管理 以及使用VNET进行网络隔离。
如果您正在寻找更多语言的此示例,请查看 .NET/C# 和 Node.js/TypeScript 版本。
下面是使用Azure Functions和Foundry代理服务的远程MCP服务器的架构图:
先决条件
- python 3.11或更高版本
- Azure功能核心工具 >=
4.0.7030 - Azure开发者命令行界面
- 要使用Visual Studio代码在本地运行和调试,请执行以下操作:
将远程MCP服务器部署到Azure
运行这个 azd 命令为功能应用程序配置任何所需的Azure资源,包括AI Foundry代理服务,并部署您的代码:
azd up
备注:系统将提示您指定
agentLocation在部署期间。这必须是AI Foundry支持的区域之一:westus,westus2,uaenorth,southindia,或switzerlandnorth。此位置专门用于AI资源(AI服务、搜索、Cosmos DB),可能与您的主要部署位置不同。
另外, API管理 可用于提高MCP服务器的安全性和策略,以及 App Service内置身份验证 可用于设置您最喜欢的OAuth提供程序,包括Entra。
连接到您的 远程 来自客户端的MCP服务器功能应用程序
您的客户端将需要一个密钥来调用新的托管SSE端点,其格式为 https://<funcappname>.azurewebsites.net/runtime/webhooks/mcp/sse默认情况下,托管功能需要一个系统密钥,可以从 门户 或CLI(az functionapp keys list --resource-group <resource_group> --name <function_app_name>).获取名为的系统密钥 mcp_extension.
铸造代理服务客户
-
在新的终端窗口中切换到代理文件夹:
cd agent -
创建一个
.env基于所提供示例的文件。复制.env.example文件:copy .env.example .env -
编辑
.env包含已部署功能应用程序详细信息的文件:# Azure AI Project Configuration PROJECT_ENDPOINT=https://your-agent-service-resource.services.ai.azure.com/api/projects/your-project-name MODEL_DEPLOYMENT_NAME=gpt-4.1-mini MCP_SERVER_LABEL=Azure_Functions_MCP_Server MCP_SERVER_URL=https://<your-funcappname>.azurewebsites.net/runtime/webhooks/mcp/sse USER_MESSAGE=Create a snippet called snippet1 that prints 'Hello, World!' in Python. # Required: Azure Functions extension key for MCP server authentication MCP_EXTENSION_KEY=your_mcp_extension_system_key_here备注:将以下值替换为您的输出
azd up部署:PROJECT_ENDPOINT:您的Azure AI项目端点(来自azd部署输出)<your-funcappname>:您的功能应用程序名称(来自azd部署输出)your_mcp_extension_system_key_here:Themcp_extension从Azure门户或CLI获取的系统密钥
-
为代理安装Python依赖项:
pip install -r requirements.txt -
运行代理服务:
python main.py代理将连接到您的远程MCP服务器并执行
USER_MESSAGE环境变量,演示Azure AI Foundry和部署的MCP服务器之间的集成。
在MCP Inspector中连接到远程MCP服务器
对于MCP检查器,您可以在URL中包含密钥:
https://<funcappname>.azurewebsites.net/runtime/webhooks/mcp/sse?code=<your-mcp-extension-system-key>
重新部署代码
你可以运行 azd up 根据需要多次执行命令,以配置Azure资源并将代码更新部署到功能应用程序。
[!注意] 部署的代码文件总是被最新的部署包覆盖。
清理资源
使用完功能应用程序和相关资源后,您可以使用此命令从Azure中删除功能应用程序及其相关资源,从而避免产生任何进一步的成本:
azd down
有用的Azure命令
部署应用程序后,您可以使用以下命令来管理和监视应用程序:
# Get your function app name from the environment file
FUNCTION_APP_NAME=$(cat .azure/$(cat .azure/config.json | jq -r '.defaultEnvironment')/env.json | jq -r '.FUNCTION_APP_NAME')
echo $FUNCTION_APP_NAME
# Get resource group
RESOURCE_GROUP=$(cat .azure/$(cat .azure/config.json | jq -r '.defaultEnvironment')/env.json | jq -r '.AZURE_RESOURCE_GROUP')
echo $RESOURCE_GROUP
# View function app logs
az webapp log tail --name $FUNCTION_APP_NAME --resource-group $RESOURCE_GROUP
# Redeploy the application without provisioning new resources
azd deploy
在本地调试MCP服务器功能
此特定示例需要Azure存储模拟器,因为我们将从blob存储中保存和获取代码段。
-
开始Azurite
docker run -p 10000:10000 -p 10001:10001 -p 10002:10002 \ mcr.microsoft.com/azure-storage/azurite
备注 如果你使用来自VS Code扩展的Azurite,你需要运行
Azurite: Start现在,否则你会看到错误。
从终端本地运行MCP服务器
-
在新的终端窗口中更改为src/mcp_server文件夹:
cd src/mcp_server -
安装Python依赖项:
pip install -r requirements.txt
备注 在执行以下操作之前创建虚拟环境是一种最佳做法
pip install以避免依赖关系问题/冲突,或者如果您在CodeSpaces中运行。看 VS代码中的Python环境 了解更多信息。
-
在本地启动Functions主机:
func start
备注 默认情况下,这将使用webhooks路由:
/runtime/webhooks/mcp/sse稍后,我们将在Azure中使用它来设置客户端/主机调用的密钥:/runtime/webhooks/mcp/sse?code=<system_key>
连接到 本地 来自客户端/主机的MCP服务器
铸造代理服务客户
Foundry代理服务是一种云服务,它期望MCP工具也在云中(例如相同的VNET或公共互联网上)。继续执行部署Azure for Remote MCP的步骤。
MCP检查员
-
在一个 新终端窗口,安装并运行MCP检查器
npx @modelcontextprotocol/inspector -
按CTRL键单击可从应用程序显示的URL加载MCP Inspector web应用程序(例如。http://0.0.0.0:5173/#resources)
-
将运输类型设置为
SSE -
将URL设置为正在运行的Function应用程序的SSE端点,然后 连接:
http://0.0.0.0:7071/runtime/webhooks/mcp/sse
备注 此步骤在CodeSpaces中不起作用。请继续部署到远程MCP。
源代码
的功能代码 get_snippet 和 save_snippet 端点在Python文件中定义 src/mcp_server 目录。MCP函数注释将这些函数作为MCP服务器工具公开。
以下是function_app.py文件中的实际代码:
@app.generic_trigger(arg_name="context", type="mcpToolTrigger", toolName="hello",
description="Hello world.",
toolProperties="[]")
def hello_mcp(context) -> None:
"""
A simple function that returns a greeting message.
Args:
context: The trigger context (not used in this function).
Returns:
str: A greeting message.
"""
return "Hello I am MCPTool!"
@app.generic_trigger(
arg_name="context",
type="mcpToolTrigger",
toolName="getsnippet",
description="Retrieve a snippet by name.",
toolProperties=tool_properties_get_snippets_json
)
@app.generic_input_binding(
arg_name="file",
type="blob",
connection="AzureWebJobsStorage",
path=_BLOB_PATH
)
def get_snippet(file: func.InputStream, context) -> str:
"""
Retrieves a snippet by name from Azure Blob Storage.
Args:
file (func.InputStream): The input binding to read the snippet from Azure Blob Storage.
context: The trigger context containing the input arguments.
Returns:
str: The content of the snippet or an error message.
"""
snippet_content = file.read().decode("utf-8")
logging.info(f"Retrieved snippet: {snippet_content}")
return snippet_content
@app.generic_trigger(
arg_name="context",
type="mcpToolTrigger",
toolName="savesnippet",
description="Save a snippet with a name.",
toolProperties=tool_properties_save_snippets_json
)
@app.generic_output_binding(
arg_name="file",
type="blob",
connection="AzureWebJobsStorage",
path=_BLOB_PATH
)
def save_snippet(file: func.Out[str], context) -> str:
content = json.loads(context)
snippet_name_from_args = content["arguments"][_SNIPPET_NAME_PROPERTY_NAME]
snippet_content_from_args = content["arguments"][_SNIPPET_PROPERTY_NAME]
if not snippet_name_from_args:
return "No snippet name provided"
if not snippet_content_from_args:
return "No snippet content provided"
file.set(snippet_content_from_args)
logging.info(f"Saved snippet: {snippet_content_from_args}")
return f"Snippet '{snippet_content_from_args}' saved successfully"
请注意 host.json 文件还包括对实验包的引用,这是使用此功能的应用程序所必需的:
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle.Experimental",
"version": "[4.*, 5.0.0)"
}
后续步骤
- 添加 API管理 到您的MCP服务器(身份验证、网关、策略等!)
- 添加 内置身份验证 到您的MCP服务器
- 使用VNET_ENABLED=true标志启用VNET
- 更多了解 微软的相关MCP工作
