feat(main): 添加MCP工具列表API和优化服务器路由 - 新增getToolsList函数,提供完整的编辑器操作工具集 - 包含节点操作、场景管理、预制体创建等9个核心功能 - 重构HTTP服务器路由逻辑,分离工具列表和调用接口 - 移除冗余的CORS头设置,简化请求处理流程 - 统一错误处理和日志记录机制 feat(proxy): 实现MCP协议代理服务 - 创建mcp-proxy.js作为独立的协议转换层 - 支持initialize、tools/list、tools/call方法 - 实现与Cocos编辑器的HTTP通信桥接 - 提供详细的调试日志和错误处理机制 ```
101 lines
3.0 KiB
JavaScript
101 lines
3.0 KiB
JavaScript
const http = require('http');
|
|
const COCOS_PORT = 3456;
|
|
|
|
function debugLog(msg) {
|
|
process.stderr.write(`[Proxy Debug] ${msg}\n`);
|
|
}
|
|
|
|
process.stdin.on('data', (data) => {
|
|
const lines = data.toString().split('\n');
|
|
lines.forEach(line => {
|
|
if (!line.trim()) return;
|
|
try {
|
|
const request = JSON.parse(line);
|
|
handleRequest(request);
|
|
} catch (e) {}
|
|
});
|
|
});
|
|
|
|
function handleRequest(req) {
|
|
const { method, id, params } = req;
|
|
|
|
if (method === 'initialize') {
|
|
sendToAI({
|
|
jsonrpc: "2.0", id: id,
|
|
result: {
|
|
protocolVersion: "2024-11-05",
|
|
capabilities: { tools: {} },
|
|
serverInfo: { name: "cocos-bridge", version: "1.0.0" }
|
|
}
|
|
});
|
|
return;
|
|
}
|
|
|
|
if (method === 'tools/list') {
|
|
// 使用 GET 获取列表
|
|
forwardToCocos('/list-tools', null, id, 'GET');
|
|
return;
|
|
}
|
|
|
|
if (method === 'tools/call') {
|
|
// 使用 POST 执行工具
|
|
forwardToCocos('/call-tool', {
|
|
name: params.name,
|
|
arguments: params.arguments
|
|
}, id, 'POST');
|
|
return;
|
|
}
|
|
|
|
if (id !== undefined) sendToAI({ jsonrpc: "2.0", id: id, result: {} });
|
|
}
|
|
|
|
function forwardToCocos(path, payload, id, method = 'POST') {
|
|
const postData = payload ? JSON.stringify(payload) : '';
|
|
|
|
const options = {
|
|
hostname: '127.0.0.1',
|
|
port: COCOS_PORT,
|
|
path: path,
|
|
method: method,
|
|
headers: { 'Content-Type': 'application/json' }
|
|
};
|
|
|
|
if (postData) {
|
|
options.headers['Content-Length'] = Buffer.byteLength(postData);
|
|
}
|
|
|
|
const request = http.request(options, (res) => {
|
|
let resData = '';
|
|
res.on('data', d => resData += d);
|
|
res.on('end', () => {
|
|
try {
|
|
const cocosRes = JSON.parse(resData);
|
|
|
|
// 检查关键字段
|
|
if (path === '/list-tools' && !cocosRes.tools) {
|
|
// 如果报错,把 Cocos 返回的所有内容打印到 Trae 的 stderr 日志里
|
|
debugLog(`CRITICAL: Cocos returned no tools. Received: ${resData}`);
|
|
sendError(id, -32603, "Invalid Cocos response: missing tools array");
|
|
} else {
|
|
sendToAI({ jsonrpc: "2.0", id: id, result: cocosRes });
|
|
}
|
|
} catch (e) {
|
|
debugLog(`JSON Parse Error. Cocos Sent: ${resData}`);
|
|
sendError(id, -32603, "Cocos returned non-JSON data");
|
|
}
|
|
});
|
|
});
|
|
|
|
request.on('error', (e) => {
|
|
debugLog(`Cocos is offline: ${e.message}`);
|
|
sendError(id, -32000, "Cocos Plugin Offline");
|
|
});
|
|
|
|
if (postData) request.write(postData);
|
|
request.end();
|
|
}
|
|
|
|
function sendToAI(obj) { process.stdout.write(JSON.stringify(obj) + '\n'); }
|
|
function sendError(id, code, message) {
|
|
sendToAI({ jsonrpc: "2.0", id: id, error: { code, message } });
|
|
} |