openmanus.cpp/server/mcp_server_main.cpp

123 lines
3.5 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/**
* @file mcp_server_main.cpp
* @brief OpenManus MCP服务器实现
*
* 这个文件实现了OpenManus的MCP服务器提供工具调用功能。
* 当前实现了PythonExecute工具。
*/
#include "mcp/include/mcp_server.h"
#include "mcp/include/mcp_tool.h"
#include "mcp/include/mcp_resource.h"
#include <iostream>
#include <fstream>
#include <string>
#include <memory>
#include <filesystem>
#include <cstdio>
#include <array>
#include <stdexcept>
// 执行系统命令并返回输出
std::string exec_command(const std::string& cmd) {
std::array<char, 128> buffer;
std::string result;
// 打开管道,执行命令
FILE* pipe = popen(cmd.c_str(), "r");
if (!pipe) {
throw std::runtime_error("popen() failed!");
}
// 读取命令输出
while (fgets(buffer.data(), buffer.size(), pipe) != nullptr) {
result += buffer.data();
}
// 关闭管道
int status = pclose(pipe);
if (status == -1) {
throw std::runtime_error("pclose() failed!");
}
return result;
}
// PythonExecute工具处理函数
mcp::json python_execute_handler(const mcp::json& args) {
if (!args.contains("code")) {
std::cout << args.dump() << std::endl;
throw mcp::mcp_exception(mcp::error_code::invalid_params, "缺少'code'参数");
}
std::string code = args["code"];
// 创建临时Python文件
std::string temp_file = "/tmp/openmanus_temp.py";
// 写入Python代码到临时文件
std::ofstream out(temp_file);
if (!out) {
throw mcp::mcp_exception(mcp::error_code::internal_error, "无法创建临时Python文件");
}
out << code;
out.close();
try {
// 执行Python代码
std::string cmd = "python3 " + temp_file + " 2>&1";
std::string output = exec_command(cmd);
// 删除临时文件
std::filesystem::remove(temp_file);
if (output.empty()) {
output = "Executed successfully but w/o output. Maybe you should print more information.";
}
return {{
{"type", "text"},
{"text", output}
}};
} catch (const std::exception& e) {
// 删除临时文件
std::filesystem::remove(temp_file);
throw mcp::mcp_exception(mcp::error_code::internal_error,
"执行Python代码失败: " + std::string(e.what()));
}
}
int main() {
// 创建并配置服务器
mcp::server server("localhost", 8080);
server.set_server_info("OpenManusMCPServer", "2024-11-05");
// 设置服务器能力
mcp::json capabilities = {
{"tools", {{"listChanged", true}}},
{"resources", {{"listChanged", true}}}
};
server.set_capabilities(capabilities);
// 注册方法处理函数
server.register_method("ping", [](const mcp::json& params) {
return mcp::json{{"pong", true}};
});
// 注册PythonExecute工具
mcp::tool python_tool = mcp::tool_builder("PythonExecute")
.with_description("执行Python代码并返回结果")
.with_string_param("code", "要执行的Python代码", true)
.build();
server.register_tool(python_tool, python_execute_handler);
// 启动服务器
std::cout << "启动OpenManus MCP服务器地址: localhost:8080..." << std::endl;
std::cout << "按Ctrl+C停止服务器" << std::endl;
server.start(true); // 阻塞模式
return 0;
}