推荐语
自主构建MCP服务,云端部署轻松实现,阿里云百炼工作流封装技巧全解析。核心内容:1. 编写代码封装MCP服务的详细步骤2. 发布服务到npm平台的操作流程3. 在阿里云百炼平台创建自定义MCP服务的方法4. 智能体中引用自定义MCP服务的实现方式
杨芳贤
53A创始人/腾讯云(TVP)最具价值专家
本文以阿里云百炼上的工作流为例,将其封装成MCP服务并部署到阿里云百炼,随后引入智能体中,从而可以在智能体内使用自定义的MCP服务。今天我们先介绍其中一种方式。
1. 编写代码封装MCP服务。
2. 将封装后的服务发布到npm官方平台。
3. 在阿里云百炼平台中创建自定义的MCP服务。
4. 在智能体中引用自定义的MCP服务。

一、搭建MCP服务
通过Nodejs+TypeScript实现
在创建Node.js项目之前,请确保你已安装Node.js,如果尚未安装,可以访问以下链接进行下载:https://nodejs.org
在电脑上创建一个文件夹,名称可自定义。例如,我将其命名为 bailian-mcp-workflow-server。
你可以使用VSCode打开该文件夹,或者直接通过命令行进入此文件夹进行操作。
1.1、在命令行当中运行
初始化Nodejs项目
执行成功后自动创建package.json,修改package.json当中的内容:
package.json
{
"name": "bailian-mcp-workflow-server",
"version": "0.0.1",
"description": "Bailian MCP server",
"license": "MIT",
"author": "Anthropic, PBC (https://anthropic.com)",
"homepage": "https://modelcontextprotocol.io",
"bugs": "https://github.com/modelcontextprotocol/servers/issues",
"type": "module",
"bin": {
"mcp-server-brave-search": "dist/index.js"
},
"files": [
"dist"
],
"scripts": {
"build": "tsc && shx chmod +x dist/*.js",
"prepare": "npm run build",
"watch": "tsc --watch"
},
"dependencies": {
"@modelcontextprotocol/sdk": "1.0.1"
},
"devDependencies": {
"@types/node": "^22",
"shx": "^0.3.4",
"typescript": "^5.6.2"
}
}
1.2、在package.json的同级下创建tsconfig.json
{
"compilerOptions": {
"target": "ES2022",
"module": "Node16",
"moduleResolution": "Node16",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"outDir": "./dist",
"rootDir": "."
},
"include": [
"./**/*.ts"
],
"exclude": [
"node_modules"
]
}
1.3、同级目录下创建 index.ts,内容为空就行。
1.4、设置好上述内容之后我们安装一下对应的依赖。
1.1、在官方文档中,查看应用调用的API
查看应用调用API参考文档:https://bailian.console.aliyun.com/?tab=api#/api/?type=app,官方API实现对百炼应用的调用如下:
curl -X POST https:
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"input": {
"prompt": "你是谁?"
},
"parameters": {},
"debug": {}
}'
我们只需要将上述的API封装为MCP即可。
1.2、将应用的API封装为MCP应用,参考如下代码
在index.ts当中写入如下内容
#!/usr/bin/env node
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
const MARKET_RESEARCH_ASSISTANT = {
name: "market_research_tool",
description: "This is an intelligent market research report generation assistant, specifically designed to efficiently and professionally build research plans.",
inputSchema: {
type: "object",
properties: {
query: {
type: "string",
description: "Search query (max 400 chars, 50 words)"
}
},
required: ["query"],
},
};
const server = new Server(
{
name: "bailian-mcp-workflow-server",
version: "0.1.0",
},
{
capabilities: {
tools: {},
},
}
);
const DASHSCOPE_API_KEY = process.env.DASHSCOPE_API_KEY!;
if (!DASHSCOPE_API_KEY) {
console.error("Error: DASHSCOPE_API_KEY environment variable is required");
process.exit(1);
}
const APP_ID = process.env.APP_ID!;
if (!APP_ID) {
console.error("Error: APP_ID environment variable is required");
process.exit(1);
}
async function performWebMarketResearch(query: any){
const url = 'https://dashscope.aliyuncs.com/api/v1/apps/'+APP_ID+'/completion';
const requestBody = {
"input": {
"prompt": query
},
"parameters": {},
"debug": {}
};
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': "Bearer "+DASHSCOPE_API_KEY
},
body: JSON.stringify(requestBody)
});
if (!response.ok) {
thrownew Error(`Bailian API error: ${response.status} ${response.statusText}\n${await response.text()}`);
}
const descriptionsData = await response.json();
const strjson = JSON.stringify(descriptionsData)
return strjson;
}
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [MARKET_RESEARCH_ASSISTANT],
}));
server.setRequestHandler(CallToolRequestSchema, async (request) => {
try {
const { name, arguments: args } = request.params;
if (!args) {
thrownew Error("No arguments provided");
}
switch (name) {
case"market_research_tool": {
const { query } = args;
const results = await performWebMarketResearch(query);
return {
content: [{ type: "text", text: results }],
isError: false,
};
}
default:
return {
content: [{ type: "text", text: `Unknown tool: ${name}` }],
isError: true,
};
}
} catch (error) {
return {
content: [
{
type: "text",
text: `Error: ${error instanceof Error ? error.message : String(error)}`,
},
],
isError: true,
};
}
});
async function runServer(){
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("Bailian Mcp Workflow Server running on stdio");
}
runServer().catch((error) => {
console.error("Fatal error running server:", error);
process.exit(1);
});
1.3、解释一下上述代码
核心功能
初始化 Server
代码首先创建了一个 Server
实例,该实例基于 @modelcontextprotocol/sdk/server
模块。服务器的配置如下:
const server = new Server(
{
name: "bailian-mcp-workflow-server",
version: "0.1.0",
},
{
capabilities: {
tools: {},
},
}
);
环境变量检查
为了确保服务器能够正常运行,代码检查了两个关键环境变量:
如果这些变量缺失,服务器将报错并退出。
const DASHSCOPE_API_KEY = process.env.DASHSCOPE_API_KEY!;
if (!DASHSCOPE_API_KEY) {
console.error("Error: DASHSCOPE_API_KEY environment variable is required");
process.exit(1);
}
const APP_ID = process.env.APP_ID!;
if (!APP_ID) {
console.error("Error: APP_ID environment variable is required");
process.exit(1);
}
定义市场研究工具
MARKET_RESEARCH_ASSISTANT
是一个描述市场研究工具的对象,包含以下内容:
注册工具列表
通过
server.setRequestHandler(ListToolsRequestSchema, ...)
方法,服务器向客户端提供支持的工具列表:
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [MARKET_RESEARCH_ASSISTANT],
}));
当客户端请求工具列表时,服务器会返回 MARKET_RESEARCH_ASSISTANT
的定义。
API封装为MCP服务
利用fetch发起POST请求,调用百炼API接口并获取相应返回数据。若想将其他API接口封装为MCP,可参考代码中的requestBody,于此设置自定义请求参数。获取到返回数据后,可进行处理,亦可直接返回,因为在百炼中会自动处理返回的JSON,将其转化为便于用户阅读的Markdown格式。
const url = 'https://dashscope.aliyuncs.com/api/v1/apps/'+APP_ID+'/completion';
const requestBody = {
"input": {
"prompt": query
},
"parameters": {},
"debug": {}
};
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': "Bearer "+DASHSCOPE_API_KEY
},
body: JSON.stringify(requestBody)
});
1.4、本机通过Cline联调测试

{
"mcpServers": {
"bailian-mcp-workflow-server": {
"disabled": false,
"timeout": 300000,
"command": "cmd",
"args": [
"/c",
"node",
"D:\\ProgramData\\bailian-mcp-workflow-server\\index.ts"
],
"env": {
"DASHSCOPE_API_KEY": "sk-212aeb2121213232",
"APP_ID": "3621da212127b272343411337e7"
},
"transportType": "stdio"
}
}
}
DASHSCOPE_API_KEY为百炼的API-KEY,去百炼官网上申请
APP_ID 百炼的工作流应用ID,具体工作流是做什么的您可以自定义。

配置好上述内容以后,再次测试提问。

https://www.npmjs.com
登录到 npm,在项目的终端当中运行以下命令登录到 npm
系统会提示你输入用户名、密码和邮箱地址。如果登录成功,你会看到类似以下的输出。
Logged in as <your-username> on https:
在发布之前,建议检查你选择的包名是否已经被占用。你可以访问 npmjs.com 并搜索你的包名,或者直接尝试发布。
如果包名已被占用,你需要更改 package.json 中的 name 字段为一个唯一的名称。
在项目的终端当中运行以下命令打包:
如果一切正常,你会看到类似以下的输出

运行成功后,项目中会自动创建dist目录,这意味着打包成功

在项目根目录下运行以下命令发布包:
如果一切正常,你会看到类似以下的输出:

此时,你的包就已经成功发布到 npm 上了!
https://www.npmjs.com/package/bailian-mcp-workflow-server

本机再次测试一下

Windows配置
{
"mcpServers": {
"bailian-mcp-workflow-server": {
"disabled": false,
"timeout": 300000,
"command": "cmd",
"args": [
"/c",
"npx",
"-y",
"bailian-mcp-workflow-server"
],
"env": {
"DASHSCOPE_API_KEY": "sk-212aeb2121213232",
"APP_ID": "3621da212127b272343411337e7"
},
"transportType": "stdio"
}
}
}
MacOS/Linux 配置
{
"mcpServers": {
"bailian-mcp-workflow-server": {
"disabled": false,
"timeout": 300000,
"command": "npx",
"args": [
"-y",
"bailian-mcp-workflow-server"
],
"env": {
"DASHSCOPE_API_KEY": "sk-212aeb2121213232",
"APP_ID": "3621da212127b272343411337e7"
},
"transportType": "stdio"
}
}
}
三、将刚发布的项目集成到阿里云百炼的自定义MCP中
MCP服务配置
{
"mcpServers": {
"bailian-mcp-workflow-server": {
"disabled": false,
"timeout": 300000,
"command": "npx",
"args": [
"-y",
"bailian-mcp-workflow-server"
],
"env": {
"DASHSCOPE_API_KEY": "sk-212aeb2121213232",
"APP_ID": "3621da212127b272343411337e7"
},
"transportType": "stdio"
}
}
}
点击提交部署

选择【工具】进行测试,如下结果则表示测试成功




百炼未来将集成工作流的MCP服务,用户只需在平台中进行简单配置,即可将工作流转化为MCP服务,并引入智能体。