Featured image of post 仅需一步在Azure Functions上托管Node.js MCP服务器

仅需一步在Azure Functions上托管Node.js MCP服务器

本文详细介绍了如何将使用Node.js和Anthropic官方SDK构建的模型上下文协议(MCP)服务器,通过添加一个简单的配置文件,部署到具备自动扩展和按需付费优势的Azure Functions无服务器平台上。

TL;DR 关键要点

Azure Functions 现在支持使用官方的 Anthropic SDK 托管 Node.js MCP 服务器 只需一个简单的配置:添加 host.json 文件 当前支持使用 HTTP Streaming 协议的无状态服务器 无服务器托管意味着自动扩展和按用量付费的定价模式 使用基础设施即代码通过一个命令进行部署

您将在这里学到什么?

了解 MCP 服务器如何在 Azure Functions 上工作 为 Azure Functions 托管配置一个 Node.js MCP 服务器 在本地和真实的 AI 代理中测试您的 MCP 服务器 使用基础设施即代码和 AZD 部署您的 MCP 服务器

参考链接

模型上下文协议 – 官方 MCP 文档 Azure Functions – 无服务器计算平台 Anthropic MCP SDK – 官方 TypeScript SDK Azure Developer CLI – 单命令部署工具 完整示例项目 – 带有 MCP 的完整汉堡点餐系统 简单示例 – 最小的 MCP 服务器启动器 GitHub Copilot 提示助手 – Anthony Chu 的自动化设置工具

要求

Node.js 22 或更高版本 Azure 帐户(免费注册,学生可在此处获取免费额度) Azure Developer CLI(用于部署) GitHub 帐户(可选,用于使用 Codespaces)

什么是 MCP 以及它为何重要?

模型上下文协议是一个开放标准,使 AI 模型能够安全地与外部工具和数据源交互。无需硬编码工具集成,您可以构建一个 MCP 服务器,它将功能(如浏览菜单、下订单或查询数据库)暴露为任何兼容 MCP 的 AI 代理可以发现和使用的工具。MCP 是与模型无关的,这意味着它可以与任何支持该协议的 LLM 配合使用,包括来自 Anthropic、OpenAI 等的模型。值得注意的是,MCP 支持的不仅仅是工具调用,尽管这是其最常见的用例。

挑战在于?在生产环境中运行 MCP 服务器需要基础设施。您需要处理扩展、监控和成本。这就是 Azure Functions 的用武之地。

免费课程提醒! 如果您是 MCP 新手,请查看 MCP 初学者课程以快速上手。

为什么选择 Azure Functions 来托管 MCP 服务器?

Azure Functions 是无服务器计算平台,非常适合 MCP 服务器:

零基础设施管理:无需维护服务器 自动扩展:无缝处理流量高峰 经济高效:仅按实际执行时间付费(提供丰厚的免费额度) 内置监控:开箱即用的 Application Insights 集成 全球分发:可部署到世界各地的区域

新的 Azure Functions 支持意味着您可以对现有的 Node.js MCP 服务器进行最小的更改,将其部署到生产就绪的无服务器环境中。这为原生 Node.js MCP 托管提供了一个额外的选择,但您仍然可以使用之前可用的 Azure Functions MCP 绑定。

启用 Functions 托管的 1 个简单步骤

让我们分解一下您需要在现有的 Node.js MCP 服务器中添加什么才能使其在 Azure Functions 上运行。我将使用来自我们的汉堡点餐系统的真实示例。

如果您已经有一个正常工作的 Node.js MCP 服务器,只需按照以下步骤使其兼容 Azure Functions 托管。

步骤 1:添加 host.json 配置

在您的 Node.js 项目根目录创建一个 host.json 文件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
{
  "version": "2.0",
  "configurationProfile": "mcp-custom-handler",
  "customHandler": {
    "description": {
      "defaultExecutablePath": "node",
      "arguments": ["lib/server.js"]
    },
    "http": {
      "DefaultAuthorizationLevel": "anonymous"
    },
    "port": "3000"
  }
}

注意:根据您的构建设置,调整 arguments 数组以指向您编译后的服务器文件(例如 lib/server.jsdist/server.js)。如果需要,您还可以更改端口以匹配您的服务器配置。

hosts.json 文件保存着 Functions 运行时的元数据配置。这里最重要的部分是 customHandler 部分。它将 Azure Functions 运行时配置为将您的 Node.js MCP 服务器作为自定义处理程序运行,这允许您使用任何 HTTP 服务器框架(如 Express、Fastify 等)而无需修改(提示:它的功能不止于此!)。

没有步骤 2 或 3。就这么简单!

注意:我们这里不涉及 Azure Functions 的身份验证和授权方面,但您以后可以根据需要轻松添加这些功能。

使用 GitHub Copilot 进行自动化设置

虽然这个更改非常简单,但您可能希望自动化这个(无聊的)过程。这就是我们使用 AI 工具的目的,对吧?

我的朋友 Anthony Chu 创建了一个很棒的 GitHub Copilot 提示,可以自动化整个设置过程。只需让 Copilot 使用 create-functions-mcp-server 中的提示,它将:

添加必要的配置文件 设置基础设施即代码

如果您不使用 Copilot,也可以在您最喜欢的 AI 编码助手中从仓库复制提示指令。

真实示例:Burger MCP 服务器

让我们通过一个汉堡点餐 MCP 服务器来看看这在实践中是如何工作的。该服务器向 AI 代理公开了 9 个工具,用于与汉堡 API 交互:

get_burgers – 浏览菜单 get_burger_by_id – 获取汉堡详情 place_order – 下订单 get_orders – 查看订单历史 等等……

以下是使用 Express 和 MCP SDK 的完整服务器实现:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import express, { Request, Response } from 'express';
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
import { getMcpServer } from './mcp.js';

const app = express();
app.use(express.json());

// 处理所有 MCP Streamable HTTP 请求
app.all('/mcp', async (request: Request, response: Response) => {
  const transport = new StreamableHTTPServerTransport({
    sessionIdGenerator: undefined,
  });

  // 将传输连接到 MCP 服务器
  const server = getMcpServer();
  await server.connect(transport);

  // 使用传输处理请求
  await transport.handleRequest(request, response, request.body);

  // 当响应关闭时进行清理
  response.on('close', async () => {
    await transport.close();
    await server.close();
  });

  // 注意:为简洁起见,未显示错误处理
});

// 端口配置
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Burger MCP server listening on port ${PORT}`);
});

MCP 工具使用官方 SDK 定义:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { z } from 'zod';

export function getMcpServer() {
  const server = new McpServer({
    name: 'burger-mcp',
    version: '1.0.0',
  });

  server.registerTool(
    'get_burgers',
    { description: 'Get a list of all burgers in the menu' },
    async () => {
      const response = await fetch(`${burgerApiUrl}/burgers`);
      const burgers = await response.json();
      return {
        content: [{
          type: 'text',
          text: JSON.stringify(burgers, null, 2)
        }]
      };
    }
  );

  // ... 更多工具
  return server;
}

如您所见,该工具的实际实现是将 HTTP 请求转发给 burger API,并以 MCP 响应格式返回结果。这是企业上下文中 MCP 工具的常见模式,它们充当一个或多个现有 API 的包装器。

当前限制

请注意,目前此 Azure Functions MCP 托管有一些限制:它仅支持使用 HTTP Streaming 协议的无状态服务器。传统的 SSE 协议不受支持,因为它需要状态连接,因此您必须将客户端迁移到使用 HTTP Streaming,或者使用其他托管选项,例如使用容器。

对于大多数用例,HTTP Streaming 是推荐的方法,因为它更具可扩展性且不需要持久连接。有状态的 MCP 服务器会带来额外的复杂性挑战,并且如果您需要处理许多并发连接,可扩展性有限。

在本地测试 MCP 服务器

首先,让我们在本地运行 MCP 服务器并稍作尝试。

如果您不想设置本地环境,可以使用以下链接或在新标签页中打开它以启动 GitHub Codespace:

创建 Codespace

这将在浏览器中为您打开一个 VS Code 环境,其中仓库已克隆,所有工具都已安装并准备就绪。或者,您可以直接克隆该仓库。

准备好代码后,打开终端并运行:

1
2
3
4
5
# 安装依赖
npm install

# 启动 burger MCP 服务器和 API
npm start

这将启动本地多个服务,包括 Burger API 和 MCP 服务器,后者将在 http://localhost:3000/mcp 可用。这可能需要几秒钟,请等待终端中显示以下消息:

1
All services ready

我们现在只关注 MCP 服务器。

使用 MCP Inspector

测试 MCP 服务器最简单的方法是使用 MCP Inspector 工具:

1
npx -y @modelcontextprotocol/inspector

在浏览器中打开控制台中显示的 URL,然后:

将传输类型设置为 Streamable HTTP 输入您的本地服务器 URL: http://localhost:3000/mcp 点击 Connect

连接后,转到 Tools 选项卡以列出可用工具。然后您可以尝试 get_burgers 工具来查看汉堡菜单。

使用 GitHub Copilot(配合远程 MCP)

通过将此配置添加到项目的 .vscode/mcp.json 来配置 GitHub Copilot 以使用您部署的 MCP 服务器:

1
2
3
4
5
6
7
8
{
  "servers": {
    "burger-mcp": {
      "type": "http",
      "url": "http://localhost:3000/mcp"
    }
  }
}

点击 JSON 文件中将出现的“Start”按钮以激活 MCP 服务器连接。

现在,您可以在代理模式下使用 Copilot 并询问诸如:

“你们有什么辣汉堡?” “点两个芝士汉堡” “显示我最近的订单”

Copilot 将自动发现并使用 MCP 工具!

提示:如果 Copilot 没有调用 burger MCP 工具,请尝试检查它是否已启用:点击聊天输入框中的工具图标,确保选中了“burger-mcp”。您还可以通过在提示中添加 #burger-mcp 来强制使用工具。

(额外部分)使用基础设施即代码部署到 Azure

将应用程序部署到 Azure 通常不是一件有趣的事情,尤其是当它涉及多个资源和配置时。借助 Azure Developer CLI (AZD),您可以将整个应用程序基础设施和部署过程定义为代码,并使用单个命令部署所有内容。

如果您使用了 GitHub Copilot 的自动化设置,您应该已经拥有了必要的文件。我们的 burger 示例也预配置了这些文件。MCP 服务器在 azure.yaml 中被定义为一项服务,infra 文件夹下的文件定义了 Azure Functions 应用程序和相关资源。

以下是 azure.yaml 中定义 burger MCP 服务的相关部分:

1
2
3
4
5
6
7
name: mcp-agent-langchainjs

services:
  burger-mcp:
    project: ./packages/burger-mcp
    language: ts
    host: function

虽然基础设施文件乍一看可能令人望而生畏,但您无需理解所有细节即可开始。有大量的模板和示例可帮助您快速上手,重要的是所有内容都被定义为代码,因此您可以进行版本控制并重复使用。

现在让我们开始部署:

1
2
3
4
5
# 登录 Azure
azd auth login

# 预配资源并部署
azd up

出现提示时选择您首选的 Azure 区域(如果不确定,请选择 East US2),然后,瞧!几分钟后,您将拥有一个完全部署在 Azure Functions 上运行的 MCP 服务器。

部署完成后,CLI 将显示已部署资源的 URL,包括 MCP 服务器端点。

示例项目

Burger MCP 服务器实际上是一个更大示例项目的一部分,该项目演示了如何使用 LangChain.js 构建一个 AI 代理,该代理使用 burger MCP 服务器来下订单。如果您对在 MCP 之上构建 AI 代理的后续步骤感兴趣,这是一个很好的资源,因为它包括:

使用 LangChain.js 的 AI 代理 Web API 使用 Lit Web 组件构建的 Web 应用界面 Functions 上的 MCP 服务器(我们刚刚看到的那个) Burger 点餐 API(由 MCP 服务器使用) 实时订单可视化 完整的基础设施即代码,可通过一个命令部署所有内容

但是,如果您只对 MCP 服务器部分感兴趣,那么您可能想看看这个更简单的示例,您可以用作您自己的 MCP 服务器的起点:mcp-sdk-functions-hosting-node 是一个使用 TypeScript 和 MCP SDK 的 Node.js MCP 服务器模板。

成本如何?

Azure Functions Flex Consumption 定价对 MCP 服务器很有吸引力:

免费额度:每月 100 万次请求和 400,000 GB-s 执行时间 超出免费额度后:仅按实际执行时间付费 自动扩展:从零扩展到数百个实例

免费额度足够慷慨,可以运行一个具有中等使用量的典型 MCP 服务器,以及您可能需要的所有实验。很容易根据需要配置扩展限制来控制成本,并且可以选择在空闲时扩展到零。这种灵活性是 Functions 成为我个人在 Azure 上处理 TypeScript 项目的首选。

总结

在 Azure Functions 上托管 MCP 服务器可以让您两全其美:无服务器基础设施的简单性和官方 Anthropic SDK 的强大功能。只需一个简单的配置步骤,您就可以将现有的 Node.js MCP 服务器部署到生产就绪、自动扩展的平台。

MCP 的标准化协议与 Azure 的无服务器平台的结合意味着您可以专注于构建令人惊叹的 AI 体验,而不是管理基础设施。太棒了。

如果觉得有用,请给仓库点个星!尝试部署您自己的 MCP 服务器并在评论中分享您的经验。如果您遇到任何问题或有疑问,可以在 Azure AI 社区 Discord 上寻求帮助。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计