Files
gxde-ai-see/src/chat/mcpclient.h
T
shenmo7192 77a4369cd6 feat(chat): MCP stdio 工具接入
- McpServer:启动进程、initialize、tools/list、tools/call
- McpManager:多服务器、工具名冲突处理、OpenAI function 定义
- ChatClient:请求携带 tools,流式累积 tool_calls,结束后交回上层
- ChatWindow:工具调用循环(最多 5 轮)、scaffold 消息、设置里的 MCP JSON 编辑
- 无头自测 gxde-ai-see-mcptest + tests/mcp/test_server.py 验证通过
2026-10-30 20:22:14 +08:00

94 lines
2.1 KiB
C++

// SPDX-FileCopyrightText: 2026 GXDE OS Team
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <QHash>
#include <QJsonArray>
#include <QJsonObject>
#include <QObject>
#include <QStringList>
#include <functional>
class QProcess;
/**
* One MCP server speaking JSON-RPC 2.0 over stdio.
*/
class McpServer : public QObject
{
Q_OBJECT
public:
McpServer(const QString &name, const QString &command, const QStringList &args,
QObject *parent = nullptr);
~McpServer() override;
void start();
QString name() const { return m_name; }
bool ready() const { return m_ready; }
QJsonArray tools() const { return m_tools; }
void callTool(const QString &tool, const QJsonObject &arguments,
std::function<void(const QJsonObject &)> callback);
signals:
void readyChanged();
private:
void send(const QJsonObject &message);
void handleLine(const QByteArray &line);
void finishToolList();
QString m_name;
QString m_command;
QStringList m_args;
QProcess *m_process = nullptr;
QByteArray m_buffer;
int m_nextId = 1;
QHash<int, std::function<void(const QJsonObject &)>> m_callbacks;
QJsonArray m_tools;
bool m_ready = false;
};
/**
* Aggregates the configured MCP servers and exposes their tools in the
* OpenAI function-calling format.
*/
class McpManager : public QObject
{
Q_OBJECT
public:
static McpManager *instance();
void reload();
bool hasTools() const;
QJsonArray toolDefinitions() const;
QStringList statusLines() const;
void callTool(const QString &exposedName, const QJsonObject &arguments,
std::function<void(const QJsonObject &)> callback);
signals:
void toolsChanged();
private:
explicit McpManager(QObject *parent = nullptr);
void clearServers();
void rebuild();
QList<McpServer *> m_servers;
struct ToolRoute
{
McpServer *server = nullptr;
QString originalName;
};
QHash<QString, ToolRoute> m_routes;
QJsonArray m_definitions;
QStringList m_status;
};