此仓库包含了在Azure Functions上运行使用C# (.NET) MCP SDK构建的MCP服务器的说明和示例。该仓库使用天气样本服务器来演示如何实现这一点。您可以克隆并本地运行和测试服务器,然后通过azd up轻松部署到云端,几分钟内即可完成。
最近,Azure Functions发布了Functions MCP扩展,允许开发者使用Functions编程模型构建MCP服务器,这本质上是Function的事件驱动框架,并将其远程托管在无服务器平台上。
对于已经使用Anthropic的MCP SDKs构建了服务器的人来说,也可以通过运行它们作为轻量级Web服务器(接收来自Functions主机的事件)来将这些服务器托管在Azure Functions上。这种做法允许您无需更改代码即可托管已构建的MCP服务器,并且可以利用Function的突发扩展能力、无服务器定价模式以及安全特性。
本仓库专注于第二种托管场景:
<div align="center"> <img src="./media/function_hosting.png" alt="显示托管函数应用和自定义处理器应用的图表。" width="500"> </div>确保您拥有以下内容:
[!NOTE] 此示例需要您有权在使用的Azure订阅中创建Microsoft Entra应用程序。
[!IMPORTANT] 您的服务器必须是无状态的,并且使用streamable-http传输才能在今天的Azure Functions上远程托管。
以下说明将拉取本地服务器测试和部署所需的内容。最重要的是:host.json,local.settings.json,和infra。Azure Functions仅需前两个JSON文件。infra目录不是必需的,但用于提供Azure资源非常方便。
您的项目不太可能有相同名称的文件和目录,但如果确实存在,您需要重命名它们以避免被覆盖。
一旦完成了必要的重命名,请按照以下步骤操作:
azd init --template self-hosted-mcp-scaffold-dotnet。host.json中:
HelloWorld.dllport值与MCP服务器使用的相同有关模板的更多详细信息,请参阅模板。
克隆仓库并在Visual Studio Code中打开示例
git clone https://github.com/Azure-Samples/mcp-sdk-functions-hosting-dotnet.git
在根目录下,运行func start启动本地服务器
打开_mcp.json_(位于_.vscode_目录下)
通过选择local-mcp-server上方的_启动_按钮启动服务器
点击顶部的Copilot图标打开聊天(或Ctrl+Command+I / Ctrl+Alt+I),然后在问题窗口中切换到_Agent_模式。
点击工具图标,确保选中local-mcp-server供Copilot在聊天中使用:
<img src="./media/mcp-tools.png" width="200" alt="MCP工具列表截图">当服务器显示可用工具数量时,询问“使用#local-mcp-server返回纽约市的天气。”Copilot应调用其中一个天气工具来帮助回答这个问题。
在部署之前,您需要注册Microsoft.App资源提供程序:
az provider register --namespace 'Microsoft.App'
等待几秒钟直到注册完成。您可以通过以下方式检查状态:
az provider show -n Microsoft.App
此示例使用Visual Studio Code作为主要客户端。将其配置为允许的客户端应用程序:
azd env set PRE_AUTHORIZED_CLIENT_IDS aebc6443-996d-45c2-90f0-388ff96faa56
如果您的组织需要指定服务管理参考,请指定它。如果您不是微软员工且不确定是否需要设置此选项,可以跳过此步骤。但是,如果由于缺少服务管理参考而导致配置失败,您可能需要重新考虑此步骤。使用微软租户的微软员工必须提供服务管理参考(您的服务树ID)。没有这个,您将无法创建Entra应用程序注册,配置也会失败。
azd env set SERVICE_MANAGEMENT_REFERENCE <service-management-reference>
在根目录下运行azd up。然后选择要部署资源的Azure订阅并从可用区域中选择。
部署完成后,终端将显示类似以下的输出:
(✓) 完成: 资源组: rg-resource-group-name (12.061秒)
(✓) 完成: 应用服务计划: plan-random-guid (6.748秒)
(✓) 完成: 虚拟网络: vnet-random-guid (8.566秒)
(✓) 完成: 日志分析工作区: log-random-guid (29.422秒)
(✓) 完成: 存储帐户: strandomguid (34.527秒)
(✓) 完成: Application Insights: appi-random-guid (8.625秒)
(✓) 完成: 函数应用: func-mcp-random-guid (36.096秒)
(✓) 完成: 私有端点: blob-private-endpoint (30.67秒)
部署服务 (azd deploy)
(✓) 完成: 部署服务 api
- 终端: https://functionapp-name.azurewebsites.net/
[!TIP] 除了在_mcp.json_中启动MCP服务器外,您还可以通过点击_更多..._ -> _显示输出_查看服务器输出。输出提供了有用的信息,如为什么连接可能会失败。
您还可以点击齿轮图标将日志级别更改为“跟踪”,以获取客户端(Visual Studio Code)和服务器之间交互的更多细节。
<img src="./media/log-level.png" width="200" alt="日志级别截图">
UserInfoTools.cs展示了如何实现代为处理(OBO)流程,以便代表经过身份验证的用户调用Microsoft Graph API。当您的MCP工具需要访问下游服务时,这种模式很有用。
要测试此工具,向Copilot提问,如“使用#remote-mcp-server提供登录用户的详细信息”。Copilot会要求您提供访问用户信息的同意,给出一个链接。导航到同意URL并授予权限。然后再次向Copilot提问。
Authorization头OnBehalfOfCredential将承载令牌交换为Microsoft Graph访问令牌/me端点注意:此工具需要基础设施部署到Azure。在本地开发中,除非进行了额外配置,否则不会工作。
如果您想在更改后重新部署服务器,请运行azd deploy。(参见azd命令参考。)
服务器应用程序配置了内置服务器认证和授权功能,实现了MCP授权规范的要求,如发出401挑战和暴露受保护资源元数据(PRM)。
在Visual Studio Code的调试输出中,您可以看到MCP客户端和服务器交互的一系列请求和响应。当使用内置MCP服务器授权时,您应该看到以下事件序列:
除了Visual Studio Code之外,Azure AI Foundry中的代理也可以连接到配置了Easy Auth的托管在Function上的MCP服务器。文档即将推出。
当您不再使用服务器时,可以使用以下命令删除在Azure上创建的资源,以避免产生进一步的成本:
azd down
| 语言(堆栈) | 仓库位置 |
|---|---|
| Python | mcp-sdk-functions-hosting-python |
| Node | mcp-sdk-functions-hosting-node |
以下是可能出现的一些常见问题。
InternalServerError: 发生了意外的InternalServerError。请稍后再试。
检查是否已注册Microsoft.App资源提供程序:
az provider show -n Microsoft.App
如果显示为未注册,请注册它:
az provider register --namespace 'Microsoft.App'
成功注册应显示:
命名空间 注册策略 注册状态
------------- -------------------- -------------------
Microsoft.App 注册所需 已注册
然后再次运行azd up。
错误:执行步骤命令'deploy --all'时出错:获取目标资源:找不到资源:无法找到标记为'azd-server-name: api'的资源。请确保服务资源在您的基础架构配置中正确标记,并重新运行配置
这是一个已知的瞬态错误。尝试重新运行azd up。
确保安装了最新版本的Azure Functions核心工具。
您需要版本>=4.5.0。通过运行func --version检查。
.vscode/mcp.json必须位于根目录,以便VS Code检测MCP服务器注册
如果您看不到服务器注册上方的_启动_按钮,可能是因为.vscode/mcp.json不在您的工作区文件夹根目录中。