MCP Server 之旅第 6 站:FC MCP Server 研发实战

系列文章已详细介绍了 MCP 协议的基本概念及其在函数计算(FC)托管 MCP Server 场景下的应用。相信读者已经对 MCP 协议的原理和应用场景有了初步了解。但对于 AI 应用开发者来说,如何开发一个高效的 MCP Server?有哪些最佳实践?本文将结合实际案例,深入剖析 FC MCP Server 的设计与实现。

背景与设计目标

MCP(Model Context Protocol)协议【1】为 AI 应用开发者提供了标准化的上下文交互能力。MCP Client 负责“思考”,而 MCP Server 则为其赋能“行动”——即操作外部系统,实现自动化的业务流程。

在实际应用中,MCP Server 通常与 MCP Client(如 Cursor IDE【2】)配合,完成代码生成、构建、部署等一系列自动化操作。本文以“引导 MCP Client 生成网页应用代码工程,并自动构建、部署到函数计算”为例,详细剖析 FC MCP Server 的设计与实现。

MCP Server 的核心能力

MCP Server 主要提供三大核心能力:

  • 资源:以 URI 形式暴露给 MCP Client 文件或数据,支持资源读写和批量查找。资源是文本或二进制类型的数据,需要支持读写以及批量查找的方法。通过资源访问协议访问,并返回资源的类型以及内容。

  • 工具:封装对外部系统的操作,供 LLM 调用(需用户批准),返回操作结果。MCP Client 通过工具调用协议访问,并返回调用的结果。

  • 提示词:面对不同的参数化的业务场景,引导 MCP Client 完成具体任务的提示词。通过提示词获取协议访问,并返回目标业务场景对应的提示词。

MCP Server 的“资源”和“提示词”能力目前并非所有 MCP Client 都支持,实际开发时应以“工具”为核心。

从 MCP 协议来看,工具侧设计需要如下能力:

  • 工具发现:提供tools/list方法,返回可用工具列表以及调用方式。

  • 工具调用:提供tools/call能力,返回工具执行的结果。
    借助 MCP SDK,开发者只需关注工具参数设计和实现逻辑,协议适配由 SDK 自动完成。

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";

const server = new McpServer({
    name: "alibabacloud-fc-mcp-server",
    version: "0.0.1",
});

// 此处添加工具实现
server.tool(
    "toolName",
    "toolDescription",
    {
        arg1:  z.string().describe("参数说明,例如:这是一个参数")
    },
    async (args) => {
        const { arg1 } = args;
        return { 
          isError: false, 
          content: [
            { 
              type: "text", 
              text: `成功,得到参数:${arg1}` 
            }
          ] 
        }
    }
)


async function main() {
    const transport = new StdioServerTransport();
    await server.connect(transport);
}

main().catch((error) => {
    process.stderr.write(JSON.stringify(error));
    process.exit(1);
});

FC MCP Server 工具的设计与最佳实践

参考官方文档【3】,工具设计应遵循以下原则:

  • 名称与描述清晰:工具名称和描述应准确反映其功能和使用场景,便于 LLM 理解。

  • 参数定义规范:使用详细的 JSON Schema 定义参数,包括类型、描述、默认值、枚举等。

  • 包含使用示例:在描述中给出调用示例,帮助 LLM 正确使用工具。

  • 完善错误处理:实现合理的错误校验和提示,提升健壮性。

  • 操作专注原子:每个工具只做一件事,保持原子性,避免副作用。

为满足将 MCP Client 生成的网页类型代码工程部署到函数计算,我们至少需要设计一个工具,实现将代码工程以 Custom Runtime【4】的形式,部署到函数计算。

下面是工具的示例代码,完整的源代码可以参考这里【5】。

server.tool(
        // 提供与工具实际作用相符的名称与描述信息,说明工具的具体使用场景以及需要注意的事项,便于MCP Client理解
        "put-custom-runtime-function",
        "将构建完成的匹配阿里云自定义运行时的工程,部署到函数计算。代码工程不需要手动打包,会自动处理。如果函数已存在,则尝试覆盖并更新目标函数。",
        {
            // 提供完整的参数定义,包括参数的类型、描述、默认值、枚举值等,便于MCP Client理解
            location: locationSchema,
            functionName: functionNameSchema,
            region: regionSchema,
            // ...其他部署参数,根据实际需求添加
            // TODO
        },
        async (args) => {
            // args的数据结构与上述schema定义一致
            const { location } = args;
            if (!fs.existsSync(location)) {
                return { isError: true, content: [{ type: "text", text: `执行失败,需要指定本地代码工程根路径` }] };
            }
            return await createCustomRuntimeFunction(args);
        }
    );

FC MCP Server 的测试最佳实践

开发测试

  • 使用 MCP Inspector 工具查看 MCP Server 的工具列表及调用方式,详见官方文档【6】。

  • 推荐日志输出到文件或 stderr,便于问题定位和追踪。


# 对代码工程进行构建
npm install && npm run build

# 使用MCP Inspector工具,启动MCP Server
npx @modelcontextprotocol/inspector -e ALIBABA_CLOUD_ACCESS_KEY_ID=${ALIBABA_CLOUD_ACCESS_KEY_ID} -e ALIBABA_CLOUD_ACCESS_KEY_SECRET=${ALIBABA_CLOUD_ACCESS_KEY_SECRET} node build/index.js

# 根据输出的地址,打开调试页面
# MCP Inspector is up and running at http://127.0.0.1:6274 🚀

日志示例:

console.error("这是一行需要记录的日志")

集成测试

  • 工具测试需关注返回结构的语义正确性,而非仅仅是数据结构本身。

  • 工具名称、Schema 描述等会直接影响业务效果。

  • 工具与提示词需同步维护,确保整体体验一致。

集成到 Cursor IDE

配置示例:

{
  "mcpServers": {
    "alibabacloud-fc-mcp-server": {
      "command": "node",
      "args": ["${absolute-path-to-your-project}/build/index.js"],
      "env": {
          "ALIBABA_CLOUD_ACCESS_KEY_ID": "${your-access-key-id}",
          "ALIBABA_CLOUD_ACCESS_KEY_SECRET": "${your-access-key-secret}"
      }
    }
  }
}

配置方式如下所示:

完成配置后,检查工具列表是否符合预期。

使用提示词,测试代码生成、构建并部署的能力

在 Cursor IDE 新建空项目,打开 Agent 模式。输入下方 Prompts ,然后要求智能 IDE 生成一个网页小游戏 2048,并部署到函数计算。


# 角色  
你是一位专业的阿里云函数计算(FC) Copilot,专注于为客户提供关于构建、部署代码到函数计算的建议。


## 函数计算构建约束

- 工程必须构建以后,才能部署在函数计算。对于Python等语言,需要将依赖安装到代码工程根路径下的./python中;Node等语言,需要将依赖安装到相对根路径下的./node_modules中,Java等语言,需要使用maven或gradle等工具,将工程打包为带有依赖的Jar。这样运行时依赖才能被读取到。
- 工程构建必须满足函数计算运行时约束。
- 不需要将工程打包,构建完成后可以直接调用MCP Server的工具进行部署。

## 函数计算运行时约束

- 用户必须在运行时暴露一个端口提供http服务。
- 运行环境是debian10,并预先安装了Python3.10版本、Node20版本、OpenJDK JRE21版本。
- 函数计算运行时中,提供了Python、Node、Java、Golang四种语言的某个具体版本的运行环境。 Python3.10的安装路径是/opt/python3.10,已默认将/opt/python3.10/bin以及代码包中的/code/python添加到PATH环境变量中。Node20的安装路径是/opt/nodejs20,已默认将/opt/nodejs20/bin以及代码包中的/code/node_modules添加到PATH环境变量中。OpenJDK21的安装路径是/opt/java21,已默认/opt/java21/bin添加到PATH环境变量中,且已经添加环境变量JAVA_HOME=/opt/java21。如果要修改环境变量中的PATH,应该将上述的PATH内容包含。Golang语言不需要运行环境支持。

## 技能  

### 技能一:问题拆解与分析  
- 能够对用户提出的问题进行深入拆解,明确问题的核心需求及可能涉及的步骤或指令。
- 提供清晰的任务分解步骤,确保每一步都能指向最终解决方案。
- 回答结果中尽量以表格的形式进行整理。

### 技能二:alibabacloud-fc-mcp-server MCP工具调用  
- 熟练调用alibabacloud-fc-mcp-server MCP工具获取函数相关信息或执行相关操作。
- 工具调用前必须先完成任务拆解,并确保调用逻辑清晰且符合客户需求。
- 根据用户的具体问题,选择合适的MCP功能模块进行操作,如创建自定义运行时函数、更新自定义运行时函数等。

## 限制条件  
- **任务拆解优先**:必须先给出详细的任务拆解步骤。
- **工具依赖明确**:所有需要调用MCP工具的操作,都应基于清晰的任务需求和逻辑推理。 
- **代码生成与构建**:代码必须在本地完成构建,然后部署运行在函数计算上。代码的生成与构建必须满足函数计算构建与运行时约束。

等待 agent 生成项目并部署到阿里云函数计算。

访问测试地址,获取 2048 小游戏页面,确认符合预期。

FC MCP Server 的云上部署改造

云上部署 MCP Server 时需注意:

  • 协议适配:云端无法通过 stdio 协议通信,需切换为 sse 协议。

  • 代码包传递:云端无法直接访问本地路径。代码包需要通过其他方式传递给 FC MCP Server。

如下图所示:

对于第一个问题,参考前文,Function AI 通过 MCP Proxy 组件,已经解决了协议转换的问题。推荐通过 Function AI 的 MCP 部署,实现协议转换,无需手动适配。

对于第二个问题,我们可以考虑如下方案。将代码工程构建后,通过 OSS MCP Server(待开发)上传到云端,获取下载地址 codeuri,然后将 codeuri 作为工具调用参数传递至 FC MCP Server。FC MCP Server 可以通过 OSS 的 OpenAPI,将代码包下载到本地后,完成后续的部署操作。

对应的改造代码如下所示:

// 通过环境变量,区分本地模式与远程模式
const remoteMode = process.env.REMOTE_MODE === 'true';

//...省略其他代码
if (remoteMode) {
  server.tool(
        "put-custom-runtime-function",
        "提供构建完成的匹配阿里云自定义运行时的zip格式的代码包的可下载链接以及其他函数部署配置,创建函数并部署代码到该函数。如果函数已存在,则尝试覆盖并更新目标函数。建议使用该方法前先确认函数是否存在,如果存在需要确认更新目标函数",
        {
            codeUri: codeUriSchema,
            functionName: functionNameSchema,
            region: regionSchema,
            //...省略其他代码
        },
        async (args) => {
            // 添加适配代码,将codeuri下载到本地location
            const { codeUri } = args;
            if (!codeUri) {
                return { isError: true, content: [{ type: "text", text: `执行失败,需要指定codeUri参数` }] };
            }
            const location = path.join(os.tmpdir(), `code-${Date.now()}.zip`);
            // 下载代码到本地location位置
            await downloadFile(codeUri, location);

            if (!fs.existsSync(location)) {
                return { isError: true, content: [{ type: "text", text: `执行失败,需要指定本地代码工程根路径` }] };
            }
            const nextArgs = {
                ...args,
                location,
            }
            return await createCustomRuntimeFunction(nextArgs);
        }
    );
} else {
  server.tool(
        "put-custom-runtime-function",
        "将构建完成的匹配阿里云自定义运行时的工程,部署到函数计算。代码工程不需要手动打包,会自动处理。如果函数已存在,则尝试覆盖并更新目标函数。建议使用该方法前先确认函数是否存在",
        {
            location: locationSchema,
            functionName: functionNameSchema,
            region: regionSchema,
            //...省略其他代码
        },
        async (args) => {
            const { location } = args;
            if (!fs.existsSync(location)) {
                return { isError: true, content: [{ type: "text", text: `执行失败,需要指定本地代码工程根路径` }] };
            }
            return await createCustomRuntimeFunction(args);
        }
    );
}

完整的改造代码可以参考这里【7】 。改造完毕后的 FC MCP Server 可以通过 Function AI【8】 一键部署到函数计算上。

部署到函数计算后,可以通过如下配置集成,有效解决配置需要 AK/SK 带来的安全风险:

{
  "mcpServers": {
    "aliyun-fc-mcp-server": {
      "url": "https://xxx.cn-hangzhou.fcapp.run/sse",
      "headers": {
        "Authorization": "Bearer Token"
      }
    }
  }
}

部分客户端,例如 Cursor IDE,暂时不支持此种鉴权方案。

总结

本文通过演示 FC MCP Server 的设计、研发、测试、上云的实战过程,为 MCP Server 应用开发者展示了研发 MCP Server,并部署到函数计算的便捷性。

将 MCP Server 部署到函数计算,可以有效解决本地部署 MCP Server 带来的安全问题,避免敏感信息(例如 AK/SK)的外泄,此外还能充分利用函数计算的弹性和按需计费优势,极大降低运维和部署成本

【1】MCP 协议

https://modelcontextprotocol.io/introduction

【2】Cursor IDE

https://www.cursor.com/cn

【3】官方文档

https://modelcontextprotocol.io/docs/concepts/tools

【4】Custom Runtime

https://help.aliyun.com/zh/functioncompute/fc-3-0/user-guide/custom-runtime/

【5】工具的示例代码

https://github.com/aliyun/alibabacloud-fc-mcp-server/blob/9d52188fdf8e856327a5d9a3a655883b4a0e5486/src/index.ts

【6】官方文档

https://modelcontextprotocol.io/docs/tools/debugging

【7】完整的改造代码

https://github.com/aliyun/alibabacloud-fc-mcp-server/blob/9d52188fdf8e856327a5d9a3a655883b4a0e5486/src/index.ts

【8】Function AI

https://functionai.console.aliyun.com/mcp/275

相关文章

MCP Server 实践之旅第 1 站:MCP 协议解析与云上适配

MCP Server On FC 之旅 2:从 0 到 1-MCP Server 市场构建与存量 OpenAPI 转 MCP Server

MCP Server 实践之旅第 3 站:MCP 协议亲和性的技术内幕

MCP Server On FC 之旅第 4 站:长连接闲置计费最高降低 87% 成本的技术内幕

MCP Server 之旅第 5 站:服务鉴权体系解密

点击 https://www.aliyun.com/product/fc?utm_content=se_1009653172,了解函数计算 FC 更多详情

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值