远程MCP服务器

使用Azure Functions和Python快速构建和部署安全的远程MCP服务器,支持OAuth和网络隔离。

  • by raorugan
  • Bicep
  • 本地部署
  • 3 星标
  • 更新于
在 GitHub 查看 raorugan/mcponfunconaca

使用说明

使用Azure函数(Python)开始使用远程MCP服务器

这是一个快速入门模板,可以使用Azure Functions和Python轻松构建自定义远程MCP服务器并将其部署到云端。MCP服务器通过使用密钥和HTTPS的设计进行安全保护,并允许使用内置身份验证和/或API管理以及使用VNET的网络隔离为OAuth提供更多选项。

备注

大型语言模型(LLM)是非确定性的,重要的是要意识到它们可能存在的不准确和实时变化。因此,建议在做出决定之前仔细检查信息并进行验证。

先决条件

注:我在这里用过 API快速市场 预订COM旅行API以拨打电话和处理旅行详细信息。API需要一个密钥,因此您需要订阅Booking COM API才能获得密钥并使用它。

准备好当地环境

此特定示例需要Azure存储模拟器,因为我们将从blob存储中保存和获取代码段。

  1. 开始Azurite

    docker run -p 10000:10000 -p 10001:10001 -p 10002:10002 \
        mcr.microsoft.com/azure-storage/azurite
    

备注 如果你使用来自VS Code扩展的Azurite,你需要运行 Azurite: Start 现在,否则你会看到错误。

从终端本地运行MCP服务器

  1. 在新的终端窗口中切换到src文件夹:

    cd src
    
  2. 安装Python依赖项:

    pip install -r requirements.txt
    
  3. 在本地启动Functions主机:

    func start
    

备注 默认情况下,这将使用webhooks路由: /runtime/webhooks/mcp/sse稍后,我们将在Azure中使用它来设置客户端/主机调用的密钥: /runtime/webhooks/mcp/sse?code=<system_key>

从客户端/主机内使用MCP服务器

VS代码-副本编辑

  1. 添加MCP服务器 从命令面板中,将URL添加到正在运行的Function应用程序的SSE端点:

    http://0.0.0.0:7071/runtime/webhooks/mcp/sse
    OR
     http://localhost:7071/runtime/webhooks/mcp/sse
    
  2. 列出MCP服务器 从命令面板启动服务器

  3. 在Copilot聊天代理模式下,输入提示以触发工具,例如,选择一些代码并输入此提示

    Hey what are the attractions in <place of your choice> 
    
    Please share reviews of the tour <tour_name>
    
  4. 当系统提示运行该工具时,点击同意 继续

  5. 完成后,在终端窗口中按Ctrl+C停止Functions主机进程。

MCP检查员

  1. 在一个 新终端窗口,安装并运行MCP检查器

    npx @modelcontextprotocol/inspector
    
  2. 按CTRL键单击可从应用程序显示的URL加载MCP Inspector web应用程序(例如。http://0.0.0.0:5173/#resources)

  3. 将运输类型设置为 SSE

  4. 将URL设置为正在运行的Function应用程序的SSE端点,然后 连接:

    http://0.0.0.0:7071/runtime/webhooks/mcp/sse
    
  5. 列出工具。单击工具,然后 运行工具.

部署到Azure以实现远程MCP

使用本文档中记录的说明 链接 使用Azure Functions的全新MCP扩展,在托管MCP Azure Functions服务器的Azure容器应用资源上配置Azure Functions

或

运行此azd命令为功能应用程序配置任何所需的Azure资源,并部署您的代码:

azd up

另外, API管理 可用于提高MCP服务器的安全性和策略,以及 App Service内置身份验证 可用于设置您最喜欢的OAuth提供程序,包括Entra。

从客户端连接到您的功能应用程序

您的客户端将需要一个密钥来调用新的托管SSE端点,其格式为 https://<function-name>.*****-****.<location>.azurecontainerapps.io默认情况下,托管函数需要一个系统密钥,可以从存储帐户->Blob容器->azure webjobs secrets->host.json->查看/编辑获取名为的系统密钥值 mcp_extension.

对于MCP检查器,您可以在URL中包含密钥:

`https://<function-name>.*****-****.<location>.azurecontainerapps.io/runtime/webhooks/mcp/sse?code=<your-mcp-extension-system-key>`.

对于VS Code中的GitHub Copilot,您应该将密钥设置为 x-functions-key 标题在 mcp.json,你只需使用 https://<function-name>.*****-****.<location>.azurecontainerapps.io/runtime/webhooks/mcp/sse 以下示例使用输入,当您从VS Code启动服务器时,将提示您提供密钥:

{
    "inputs": [
        {
            "type": "promptString",
            "id": "functions-mcp-extension-system-key",
            "description": "Azure Functions MCP Extension System Key",
            "password": true
        }
    ],
    "servers": {
        "my-mcp-server": {
            "type": "sse",
            "url": "<funcappname>.azurewebsites.net/runtime/webhooks/mcp/sse",
            "headers": {
                "x-functions-key": "${input:functions-mcp-extension-system-key}"
            }
        }
    }
}

源代码

的功能代码 get_attractions 和 get_attractions_reviews 端点在Python文件中定义 src 目录。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="get_attractions",
    description="Retrieve attractions at a search location.",
    toolProperties=tool_properties_get_attractions_json,
)
def get_attractions(context) -> str:
    """
    Retrieves attractions at a search location using the RapidAPI endpoint.

    Args:
        context: The trigger context containing the input arguments.

    Returns:
        str: A JSON string containing the attractions or an error message.
    """
    content = json.loads(context)
    query = content["arguments"].get("query", "").strip()
    language_code = content["arguments"].get("languagecode", "en-us").strip()

请注意 host.json 文件还包括对实验包的引用,这是使用此功能的应用程序所必需的:

"extensionBundle": {
  "id": "Microsoft.Azure.Functions.ExtensionBundle.Experimental",
  "version": "[4.*, 5.0.0)"
}

后续步骤

  • 添加 API管理 到您的MCP服务器
  • 添加 内置身份验证 到您的MCP服务器
  • 使用VNET_ENABLED=true标志启用VNET
  • 更多了解 微软的相关MCP工作