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 自动完成。

javascript 复制代码
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】。

javascript 复制代码
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,便于问题定位和追踪。

ini 复制代码
# 对代码工程进行构建
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 🚀

日志示例:

plaintext 复制代码
console.error("这是一行需要记录的日志")

集成测试

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

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

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

集成到 Cursor IDE

配置示例:

plaintext 复制代码
{
  "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,并部署到函数计算。

plaintext 复制代码
# 角色  
你是一位专业的阿里云函数计算(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,将代码包下载到本地后,完成后续的部署操作。

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

javascript 复制代码
// 通过环境变量,区分本地模式与远程模式
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 带来的安全风险:

plaintext 复制代码
{
  "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 协议

modelcontextprotocol.io/introductio...

【2】Cursor IDE

www.cursor.com/cn

【3】官方文档

modelcontextprotocol.io/docs/concep...

【4】Custom Runtime

help.aliyun.com/zh/function...

【5】工具的示例代码

github.com/aliyun/alib...

【6】官方文档

modelcontextprotocol.io/docs/tools/...

【7】完整的改造代码

github.com/aliyun/alib...

【8】Function AI

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 站:服务鉴权体系解密

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

相关推荐
五更琉璃016 小时前
十分钟完全理解MCP
mcp
围巾哥萧尘17 小时前
「MCP系列」轻松上手:三步快速完成 MCP 运行环境搭建指南🧣
mcp
AI大模型1 天前
COZE实战部署(一)—— 扣子任务空间调配和实现
agent·coze·mcp
堆栈future1 天前
揭秘 Google A2A 协议:赋能智能体协作的未来
llm·agent·mcp
小雷FansUnion3 天前
深入理解MCP架构:智能服务编排、上下文管理与动态路由实战
人工智能·架构·大模型·mcp
CoderLiu3 天前
用这个MCP,只给大模型一个figma链接就能直接导出图片,还能自动压缩上传?
前端·llm·mcp
吴佳浩3 天前
Python入门指南-AI番外-MCP完整教程:从零开始学会Model Context Protocol
人工智能·python·mcp
聚客AI4 天前
🚀拒绝试错成本!企业接入MCP协议的避坑清单
人工智能·掘金·日新计划·mcp
ZNineSun4 天前
MCP+Cursor入门
ai·cursor·mcp
大模型真好玩4 天前
准确率飙升!Graph RAG如何利用知识图谱提升RAG答案质量(四)——微软GraphRAG代码实战
人工智能·python·mcp