返回市场
mcp-sdk功能托管节点认证

mcp-sdk功能托管节点认证

作者:anthonychu2 星标更新:2025-10-28

项目介绍

示例:使用Azure Functions自托管MCP服务器授权

此示例展示了如何使用App Service身份验证和授权进行模型上下文协议(MCP)服务器授权。MCP服务器使用Azure Functions MCP扩展和TypeScript/Node.js实现。该示例还展示了如何代表已登录用户调用Microsoft Graph。

示例使用一个TypeScript项目。有两种方式开始:

您可以在本地运行它,也可以使用Azure开发者CLI(azd)快速将其部署到Azure。

先决条件

您还需要一个Entra客户端ID,可以由您的MCP客户端使用。对于基本测试,您可以使用Visual Studio Code,它有一个已知的客户端ID,将在设置说明中解释。

快速入门(使用azd部署到Azure)

  1. 克隆此仓库。

  2. 登录Azure并初始化azd:

    az login
    azd auth login
    
  3. 创建一个新的azd项目环境,指定位置(建议使用westus2),您要使用的订阅ID以及环境名称:

    azd env new <environment-name> --location westus2 --subscription <subscription-id>
    
  4. 此示例使用Visual Studio Code作为主要客户端。配置它为允许的客户端应用:

    azd env set PRE_AUTHORIZED_CLIENT_IDS aebc6443-996d-45c2-90f0-388ff96faa56
    

    如果您有其他MCP客户端将调用您的服务器,请提供所有客户端ID作为逗号分隔的列表:

    azd env set PRE_AUTHORIZED_CLIENT_IDS <comma-separated-list-of-client-ids>
    
  5. 如果您的组织需要服务管理引用,请指定它。**如果您不是微软员工且不知道是否需要设置此引用,可以跳过这一步。**然而,如果由于缺少服务管理引用而导致配置失败,您可能需要重新访问这一步。使用微软租户的微软员工必须提供服务管理引用(您的服务树ID)。没有这个,您将无法创建Entra应用注册,配置也会失败。

    azd env set SERVICE_MANAGEMENT_REFERENCE <service-management-reference>
    

    如果您不确定应该设置什么,请咨询您的组织租户管理员。

  6. (可选)如果您正在部署到主权云,请设置用于该云的令牌交换受众。

    对于Entra ID美国政府版:

    azd env set TOKEN_EXCHANGE_AUDIENCE api://AzureADTokenExchangeUSGov
    

    对于由中国21Vianet运营的Entra ID中国版:

    azd env set TOKEN_EXCHANGE_AUDIENCE api://AzureADTokenExchangeChina
    
  7. 创建Azure资源并部署应用程序:

    azd up
    

    确保所有资源都显示为“成功”状态后再继续。

  8. 同意应用程序,以便您的MCP客户端能够成功登录。为了测试,您只需通过浏览器登录应用程序来为自己授权。有关生产场景下的授权编写,请参阅授权编写

    1. 导航到您部署的功能应用的/.auth/login/aad端点。例如,如果您的功能应用位于https://my-mcp-function-app.azurewebsites.net,则导航到https://my-mcp-function-app.azurewebsites.net/.auth/login/aad

      您的功能应用基础URL应在azd up命令的输出中显示。如果您错过了部署输出中的URL,可以通过以下命令检索:

      azd env get-value SERVICE_MCP_DEFAULT_HOSTNAME
      

      或者,在Azure门户中找到您的功能应用资源。

    2. 您应被重定向到登录提示。使用您将用于测试的MCP客户端的账户登录。

    3. 登录后,您将被提示同意应用程序。查看请求的权限并点击“接受”以授予同意。

    4. 您应被重定向回一个页面,该页面位于功能应用URL上,显示“您已成功登录”。此时您可以关闭页面。

  9. 获取您的功能应用的MCP扩展系统密钥,以便连接MCP客户端。您的客户端除了需要与Entra ID进行服务器授权外,还需要此密钥来调用您的MCP服务器。

    您可以使用Azure CLI获取名为mcp_extension的系统密钥。首先,从您的azd部署中获取资源组和功能应用名称:

    # 获取资源组名称
    azd env get-value AZURE_RESOURCE_GROUP_NAME
    
    # 获取功能应用名称  
    azd env get-value SERVICE_MCP_NAME
    

    然后使用这些值来检索系统密钥:

    az functionapp keys list --resource-group <resource_group> --name <function_app_name> --query "systemKeys.mcp_extension" -o tsv
    

    或者,您可以从Azure门户中检索它:

    1. 在Azure门户中导航到您的功能应用
    2. 转到函数应用密钥
    3. 复制mcp_extension系统密钥的值
  10. 根据下面的测试您的MCP服务器部分中的说明测试您的MCP服务器。您需要功能应用URL和上一步中的mcp_extension系统密钥。

快速入门(本地运行)

[!注意] 当本地运行时,MCP服务器将使用您的开发者凭据(来自Azure CLI或Visual Studio Code)对外部调用Microsoft Graph,而不是授权用户的标识。

  1. 克隆此仓库。

  2. (可选)更新src/mcp-server文件夹中的local.settings.json文件,以包含您的Microsoft Entra租户ID。这有助于应用程序正确访问您的开发者身份,即使您可以登录多个租户。

    1. 使用Azure CLI获取租户ID:

      az account show --query tenantId -o tsv
      
    2. 更新local.settings.json以包含租户ID:

      {
        "IsEncrypted": false,
        "Values": {
          "AzureWebJobsStorage": "UseDevelopmentStorage=true",
          "FUNCTIONS_WORKER_RUNTIME": "node",
          "AZURE_TENANT_ID": "<your-tenant-id>"
        }
      }
      
  3. 启动Azurite。如果您使用CLI启动它,例如使用azuritedocker run命令,请在单独的后台终端中执行。

  4. 将主终端移动到src/mcp-server文件夹。

  5. 安装依赖项:

    npm install
    
  6. 启动项目:

    npm start
    
  7. 根据下面的测试您的MCP服务器部分中的说明测试您的MCP服务器。

测试您的MCP服务器

完成上述任一“快速入门”选项后,您可以连接到MCP客户端来测试结果MCP服务器。

以下说明是针对使用Visual Studio Code中的GitHub Copilot进行测试的,它支持MCP协议和Entra ID身份验证。此设置还提供了日志,使客户端和服务器之间的交互易于观察,从而了解服务器授权过程。

  1. 在VS Code中创建一个新的工作区,并安装MCP扩展

  2. 创建或更新您的MCP配置在VS Code中。将以下内容添加到您的mcp.json文件中(或创建一个):

    {
        "inputs": [
            {
                "type": "promptString",
                "id": "functions-mcp-extension-system-key",
                "description": "Azure Functions MCP Extension System Key",
                "password": true
            },
            {
                "type": "promptString",
                "id": "functionapp-host",
                "description": "The host domain of the function app."
            }
        ],
        "servers": {
            "remote-mcp-function": {
                "type": "http",
                "url": "https://${input:functionapp-host}/runtime/webhooks/mcp",
                "headers": {
                    "x-functions-key": "${input:functions-mcp-extension-system-key}"
                }
            },
            "local-mcp-function": {
                "type": "http",
                "url": "http://localhost:7071/runtime/webhooks/mcp"
            }
        }
    }
    

    这创建了两个服务器配置,分别对应上述两种“快速入门”选项。在后续步骤中,请选择与您设置MCP服务器的方式相匹配的服务器,无论是本地还是远程。

  3. (可选)显示输出日志

    • 在VS Code中打开命令面板:
      • 在Windows/Linux中:按Ctrl+Shift+P
      • 在Mac中:按Cmd+Shift+P
    • 输入"MCP: 列出服务器"并按Enter
    • 选择您要启动的服务器(remote-mcp-functionlocal-mcp-function
    • 选择"显示输出" - 这将打开输出面板。
    • 在输出面板中选择齿轮图标并选择"调试"或更高级别。"跟踪"提供最详细的日志,但可能会包含额外的噪音。
  4. 启动MCP服务器

    • 在VS Code中打开命令面板:
      • 在Windows/Linux中:按Ctrl+Shift+P
      • 在Mac中:按Cmd+Shif-P
    • 输入"MCP: 列出服务器"并按Enter
    • 选择您要启动的服务器(remote-mcp-functionlocal-mcp-function
    • 选择"启动服务器"。
    • 如果选择了remote-mcp-function,您将被提示:
      • 您的功能应用URL
      • 您的mcp_extension系统密钥
  5. 如果您连接到受App Service身份验证和授权保护的应用程序,VS Code将提示您允许GitHub Copilot访问您的Microsoft帐户。按照提示登录。

    如果您配置了调试输出日志,您应该能看到MCP客户端和服务器在登录过程中是如何交互的。有关更多细节,请参阅服务器授权协议

  6. 打开GitHub Copilot聊天面板(Ctrl+Alt+I)并输入提示以使用工具。确保调用工具的最简单方法是发送消息#HelloTool

  7. GitHub Copilot应提示您允许其调用工具。确认它将调用正确的服务器,然后允许其继续。

  8. 您应在聊天面板中看到来自工具的响应。它应该以您的名字问候您,并显示您的电子邮件。这些信息来自MCP服务器调用的Microsoft Graph。

概念概述

代码结构

MCP服务器的代码位于src/mcp-server项目文件夹中。这是一个使用TypeScript和Node.js的Azure Functions项目,使用Azure Functions的MCP扩展和自定义处理器。MCP处理器定义在mcp-handler/function.json中,并在index.ts中实现了一个工具。此函数的目标是调用Microsoft Graph并返回简单的问候语。当托管在Azure中时,它会代表已登录用户调用Graph。当本地运行时,它将使用您的开发者凭据。

为了满足这些需求,处理器使用@azure/identity包来获取正确的用户令牌。index.ts文件根据上下文配置适当的TokenCredential实例。在本地上下文中,这是一个简单的ChainedTokenCredential。然而,当托管在Azure中并使用App Service身份验证和授权时,处理器使用MCP工具触发器的ToolInvocationContext来访问底层HTTP传输的标头。它使用这些标头来构建自定义令牌凭证实现。此实现使用OnBehalfOfCredential,作为联合身份凭证认证为应用程序注册,该注册是在配置期间设置的托管身份。

使用带有@azure/identity包的自定义处理器的方法保持了工具实现的简洁性和核心目的,而不引入不必要的复杂性。这也允许在需要的情况下跨多个工具使用相同的设置。

授权编写

在上述示例步骤中,您通过浏览器登录应用程序来同意它。这允许应用程序请求对Microsoft Graph的委托权限。处理授权主要有两种方式:

  • 用户授权 - 这是上述示例中使用的方法。每个用户登录应用程序并同意请求的权限。他们只能为自己这样做,除非他们是具有代表他人同意能力的租户管理员。在此示例中,用户授权是合适的,因为它允许您快速测试而不影响其他用户。然而,此样本中用户授权的编写方式并不反映通常在生产场景中的做法。这将在下面进一步描述。
  • 管理员授权 - 租户管理员可以在用户登录并审查权限时代表所有用户同意应用程序。一旦完成,单个用户可以登录而无需自己同意。这种方法更具可扩展性,并确保所有用户都可以访问应用程序而不遇到授权问题。对于示例而言,管理员授权不合适,但在生产场景中是一个很好的选择。

此示例中的用户授权是一个单独的登录,因为示例使用Visual Studio Code作为客户端。尽管Visual Studio Code预先授权给我们的应用程序,但这仅创建了用户调用MCP服务器的授权。它不会创建MCP服务器代表用户调用Microsoft Graph的授权。当我们直接登录应用程序时,我们会在组合授权体验中请求Microsoft Graph权限。

主要区别在于,由于Visual Studio Code使用单一登录流,因此它只会请求MCP服务器的令牌。它不会提供机会让用户交互式地同意MCP服务器所需的任何权限。如果您构建了一个使用某种交互式登录的客户端,它可以完全由该客户端处理。在这种情况下,不需要单独的浏览器登录。

有关Entra ID如何处理授权的更多信息,请参阅Microsoft身份平台中的权限和授权概述

服务器授权协议

在VS Code的调试输出中,您将看到一系列请求和响应,这是MCP客户端和服务器交互的结果。当使用MCP服务器授权时,您应该看到以下事件序列:

  1. 编辑器向MCP服务器发送初始化请求。
  2. MCP服务器响应错误,指示需要授权。响应包括指向应用程序受保护资源元数据(PRM)的指针。App Service身份验证和授权功能为此示例生成的应用生成PRM。
  3. 编辑器获取PRM并使用它来识别授权服务器。
  4. 编辑器尝试从授权服务器上的知名端点获取授权服务器元数据(ASM)。
  5. Microsoft Entra ID不支持知名端点上的ASM,因此编辑器退回到使用OpenID Connect元数据端点来获取ASM。它通过在任何其他路径信息之前插入知名端点来尝试发现这一点。
  6. OpenID Connect规范实际上将知名端点定义为在路径信息之后,这就是Microsoft Entra ID托管它的位置。因此,编辑器再次尝试使用这种格式。
  7. 编辑器成功获取ASM。然后,它可以结合其自身的客户端ID来执行登录。此时,编辑器提示您登录并同意应用程序。
  8. 假设您成功登录并同意,编辑器完成登录。它重复向MCP服务器的初始化请求,这次在请求中包含授权令牌。此重新尝试在调试输出级别不可见,但在跟踪输出级别可见。
  9. MCP服务器验证令牌并对初始化请求作出成功的响应。标准的MCP流程从此处继续,最终导致发现此示例中定义的MCP工具。

有关完整协议的更多信息,请参阅MCP规范