AI工具集:本地Node基于云端AI模型使用Stdio封装自定义MCP服务

背景

购买 Coding Plan 除了能替代 AI编辑器 内置 Agent 处理代码问题,还可以封装自定义 MCP 服务。在 技术方案 / 代码修改 / 单元测试 / Code Review时候进行审核辅助,毕竟单一模型在不同能力维度上各有侧重。搭建一个本地的自定义 MCP 服务,是一个很有意义的方案

本文将一步步带你配置本地版本 MCP 服务,也可以学习自建MCP服务的过程和注意事项

资源应用介绍

  1. Agent:讯飞星辰 MaaS · Astron Coding Plan
  2. 编辑器:Trae(其他编辑器类同)
  3. 服务端:本地 Node 搭建 Stdio 服务

1. Agent套餐

Coding Plan是专为开发者打造的高性能 AI 算力订阅服务,可一站式调用顶流大模型,全面提效代码生产。

1.1 购买套餐

最主要是便宜,首月3.9元不限量 https://maas.xfyun.cn/packageSubscription

在这里插入图片描述

1.2 可用模型

在这里插入图片描述

2. 搭建MCP服务

2.1 新建文件

新建一个目录,并新建【package.json】【stdio.js】
在这里插入图片描述

2.1.1 package.json
{
  "name": "localmcp",
  "version": "1.0.0",
  "description": "MCP 服务,调用云端 AI 模型",
  "main": "index.js",
  "scripts": {
    "start:stdio": "node stdio.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@modelcontextprotocol/sdk": "^1.29.0",
    "zod": "^4.4.3"
  }
}

2.1.2 stdio.js

stdio.js 是 MCP (Model Context Protocol) 服务的本地部署版本 。本地使用 sse 模式,和本文不一致

替换自己的 API_KEY,若是其他平台更换 url地址 和模型ID

#!/usr/bin/env node

const { McpServer } = require('@modelcontextprotocol/sdk/server/mcp.js');
const { StdioServerTransport } = require('@modelcontextprotocol/sdk/server/stdio.js');
const { z } = require('zod');

/**
 * 调用云端 AI 模型进行对话或代码生成
 * @param {Array<{role: 'user'|'assistant', content: string}>} messages - 对话消息数组
 * @param {Object} [options={}] - 配置选项
 * @param {string} [options.model='astron-code-latest'] - 模型名称
 * @param {'openai'|'anthropic'} [options.provider='openai'] - API 提供商类型
 * @returns {Promise<{content: Array<{type: string, text: string}>}>} AI 响应结果
 * @throws {Error} 当 API 请求失败或返回非 JSON 格式时抛出错误
 */
async function callAI(messages, options = {}) {
  const maxTokens = 131072;
  const OPENAI_URL = 'https://maas-coding-api.cn-huabei-1.xf-yun.com/v2/chat/completions';
  const ANTHROPIC_URL = 'https://maas-coding-api.cn-huabei-1.xf-yun.com/anthropic/v1/messages';
  const MODEL_ID = 'astron-code-latest';
  const API_KEY = 'xxxxxxxxxx';

  const { model = MODEL_ID, provider = 'openai' } = options;
  const apiUrl = provider === 'anthropic' ? ANTHROPIC_URL : OPENAI_URL;
  const isAnthropic = provider === 'anthropic';
  const body = isAnthropic
    ? { model, max_tokens: maxTokens, messages: messages.map(m => ({ role: m.role, content: m.content })) }
    : { model, messages: messages.map(m => ({ role: m.role, content: m.content })), max_tokens: maxTokens };

  const res = await fetch(apiUrl, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${API_KEY}`, 'X-Api-Key': API_KEY, 'X-Language': 'zh-CN', ...(isAnthropic ? { 'anthropic-version': '2023-06-01' } : {}) },
    body: JSON.stringify(body)
  });

  if (!res.ok) {
    const errText = await res.text();
    throw new Error(`API ${res.status}: ${errText.slice(0, 500)}`);
  }

  const contentType = res.headers.get('content-type') || '';
  if (!contentType.includes('application/json')) {
    const errText = await res.text();
    throw new Error(`API返回非JSON格式(${contentType}): ${errText.slice(0, 200)}`);
  }

  const data = await res.json();

  if (isAnthropic) return { content: [{ type: 'text', text: data.content?.[0]?.text || '' }] };
  return { content: [{ type: 'text', text: data.choices?.[0]?.message?.content || data.choices?.[0]?.message?.reasoning_content || JSON.stringify(data) }] };
}

/**
 * 创建 MCP 服务器实例
 * @description 定义服务名称和版本号,用于与客户端建立通信
 */
const server = new McpServer({
  name: 'agentmcp',
  version: '1.0.0'
});

/**
 * 注册 'chat' 工具
 * @description 提供调用云端 AI 模型进行对话或代码生成的能力
 * 支持 OpenAI 和 Anthropic 兼容接口
 * @param {messages} 对话消息数组,支持 user/assistant 角色
 * @param {model} [可选] 指定使用的模型名称(默认 astron-code-latest)
 * @param {provider} [可选] API 提供商类型(openai 或 anthropic)
 */
server.tool('chat', '调用云端 AI 模型进行对话或代码生成,支持 OpenAI 和 Anthropic 兼容接口', {
  messages: z.array(z.object({
    role: z.enum(['user', 'assistant']),
    content: z.string()
  })),
  model: z.string().optional().describe('模型名称,默认 astron-code-latest'),
  provider: z.enum(['openai', 'anthropic']).optional().describe('API 提供商,默认 openai')
}, async ({ messages, model, provider }) => {
  try {
    return await callAI(messages, { model, provider });
  } catch (err) {
    return { content: [{ type: 'text', text: `[ERROR] ${err.message}` }], isError: true };
  }
});

/**
 * 启动 MCP 服务器并监听 stdio 传输
 * 通过标准输入输出与客户端进行通信
 * @returns {Promise<void>}
 */
async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
}

/**
 * 启动 MCP 服务器
 * @description 调用 main 函数启动服务,捕获并输出异常信息到控制台
 */
main().catch(console.error);

2.2 配置本地服务端

安装依赖,不需要运行,不需要运行,不需要运行

npm install

在这里插入图片描述

3. 编辑器调用MCP

在这里插入图片描述

JSON 数据
{
  "mcpServers": {
    "localmcp": {
      "command": "node",
      "args": [
        "/Users/mr.w/object/localmcp/stdio.js"
      ]
    }
  }
}

注意:若是配置【node】后运行失败,则使用本地node查询,使用全链接

which node
效果

在这里插入图片描述

4. 测试功能

发送一条对话消息,测试 MCP 服务功能。

恭喜搭建完毕!现在你可以在公司或家中调用该服务了。

在这里插入图片描述

5. 调用建议

在编辑器定义【个人规则】或 【项目规则】,约定自动触发时机 和 内容,避免每次还要在对话框内说明调用,比较麻烦

优先级权重:对话框 > 项目规则 > 个人规则


宝塔面板基于云端AI模型使用SSE封装自定义MCP服务: https://blog.csdn.net/weixin_44461275/article/details/161430697

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐