MCP Server 是一个基于 Qt/C++ 的 Model Context Protocol (MCP) 服务器框架的实现。该框架提供完整的 MCP 协议实现,支持通过 HTTP 传输层与 MCP 客户端通信,并为 AI 应用提供工具、资源和提示词服务。目前处于 DEMO 阶段。
┌─────────────────────────────────────────────────────────┐
│ 应用程序层 │
│ (MCPAutoServer / 自定义服务器实现) │
└────────────────────┬────────────────────────────────────┘
│
┌────────────────────▼────────────────────────────────────┐
│ 服务器接口层 │
│ (IMCPServer / MCPServer) │
└────────────────────┬────────────────────────────────────┘
│
┌────────────┼────────────┐
│ │ │
┌───────▼──────┐ ┌──▼──────┐ ┌──▼──────────┐
│ 工具服务 │ │资源服务 │ │ 提示词服务 │
│ ToolService │ │Resource │ │ Prompt │
│ │ │Service │ │ Service │
└───────┬──────┘ └──┬──────┘ └──┬──────────┘
│ │ │
└────────────┼────────────┘
│
┌────────────────────▼────────────────────────────────────┐
│ 路由与调度层 │
│ (MCPRouter / MCPRequestDispatcher / MCPContext) │
└────────────────────┬────────────────────────────────────┘
│
┌────────────────────▼────────────────────────────────────┐
│ 消息处理层 │
│ (MCPMessage / MCPServerMessage / MCPMessageSender) │
└────────────────────┬────────────────────────────────────┘
│
┌────────────────────▼────────────────────────────────────┐
│ 传输层 │
│ (MCPHttpTransport / IMCPTransport) │
└─────────────────────────────────────────────────────────┘
接口定义:IMCPServer
实现类:MCPServer
自动启动:MCPAutoServer
MCPServerConfig 配置接口:IMCPToolService
实现:MCPToolService
功能:
支持两种注册方式:
std::function 注册工具处理函数接口:IMCPResourceService
实现:MCPResourceService
功能:
支持两种类型的资源:
接口:IMCPPromptService
实现:MCPPromptService
功能:
{{变量名}} 占位符)MCPRouter 方法:路由器
MCPRequestDispatcher:请求分配器
MCPContext:请求上下文
MCPMessage 基本消息类别
Mcpserver-sssage:服务器消息
MCPMessageSender:消息发送器
MCPHttpTransport HTTP 传输实现
MCPHttpConnection HTTP 连接管理
IMCPServerConfig:配置接口 MCPServerConfig:配置实现
功能:
配置文件结构:
MCPServerConfig/
├── ServerConfig.json # 主配置文件
├── Tools/ # 工具配置目录
│ ├── calculator.json
│ └── ...
├── Resources/ # 资源配置目录
│ └── ...
└── Prompts/ # 提示词配置目录
└── ...
#include <QCoreApplication>
#include "IMCPServer.h"
#include "MyExampleHandler.h"
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
// 创建工具处理器(必须创建,MCPAutoServer 会通过 objectName 找到它)
MyExampleHandler* pHandler = new MyExampleHandler(qApp);
pHandler->setObjectName("MyExampleHandler");
// 自动启动服务器(从 MCPServerConfig 目录加载配置)
StartAutoMCPServer();
return app.exec();
}
#include <QCoreApplication>
#include "IMCPServer.h"
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
// 创建服务器实例
auto pServer = IMCPServer::createServer();
// 配置服务器
auto pConfig = pServer->getConfig();
pConfig->setPort(8888);
pConfig->setServerName("MyServer");
// 注册工具
auto pToolService = pServer->getToolService();
QJsonObject inputSchema = {
{"type", "object"},
{"properties", QJsonObject{
{"name", QJsonObject{{"type", "string"}}}
}}
};
QJsonObject outputSchema = {
{"type", "object"},
{"properties", QJsonObject{
{"result", QJsonObject{{"type", "string"}}}
}}
};
pToolService->add("greet", "Greet Tool", "一个问候工具",
inputSchema, outputSchema,
[]() -> QJsonObject {
QJsonObject result;
result["content"] = QJsonArray{QJsonObject{{"type", "text"}, {"text", "Hello!"}}};
return result;
});
// 启动服务器
pServer->start();
return app.exec();
}
工具处理器是一个继承自 QObject 的类,包含用于处理工具调用的槽函数:
// MyExampleHandler.h
#pragma once
#include <QObject>
#include <QJsonObject>
class MyExampleHandler : public QObject
{
Q_OBJECT
public:
explicit MyExampleHandler(QObject* parent = nullptr);
public slots:
// 工具处理方法:参数类型必须与 inputSchema 匹配
QJsonObject calculateOperation(double a, double b, const QString& operation);
// 返回值必须是 QJsonObject,符合 outputSchema
};
// MyExampleHandler.cpp
#include "MyExampleHandler.h"
MyExampleHandler::MyExampleHandler(QObject* parent)
: QObject(parent)
{
// 设置属性,让 MCPAutoServer 能够找到这个处理器
setProperty("MPCToolHandlerName", "MyExampleHandler");
}
QJsonObject MyExampleHandler::calculateOperation(double a, double b, const QString& operation)
{
QJsonObject result;
double value = 0;
if (operation == "add") {
value = a + b;
} else if (operation == "subtract") {
value = a - b;
} else if (operation == "multiply") {
value = a * b;
} else if (operation == "divide") {
value = b != 0 ? a / b : 0;
}
result["operands"] = QJsonArray{a, b};
result["operation"] = operation;
result["result"] = value;
result["success"] = true;
result["timestamp"] = QDateTime::currentDateTimeUtc().toString(Qt::ISODate);
return result;
}
{
"port": 5555,
"serverInfo": {
"name": "MyServer",
"title": "我的 MCP 服务器",
"version": "1.0.0"
},
"instructions": "这是一个示例 MCP 服务器"
}
{
"name": "calculator",
"title": "计算器",
"description": "支持基本数学运算的计算器工具",
"execHandler": "MyExampleHandler",
"execMethod": "calculateOperation",
"inputSchema": {
"type": "object",
"properties": {
"a": {
"type": "number",
"description": "第一个数字"
},
"b": {
"type": "number",
"description": "第二个数字"
},
"operation": {
"type": "string",
"description": "操作类型",
"enum": ["add", "subtract", "multiply", "divide"]
}
},
"required": ["a", "b", "operation"]
},
"outputSchema": {
"type": "object",
"properties": {
"result": {
"type": "number",
"description": "计算结果"
},
"success": {
"type": "boolean",
"description": "操作是否成功"
}
}
}
}
MCP Server 使用目录结构来组织配置文件,默认配置目录为 MCPServerConfig:
MCPServerConfig/
├── ServerConfig.json # 主配置文件(必需)
├── Tools/ # 工具配置目录(可选)
│ ├── calculator.json
│ ├── my_tool.json
│ └── ...
├── Resources/ # 资源配置目录(可选)
│ ├── config_file.json
│ ├── wrapper_example.json
│ └── ...
└── Prompts/ # 提示词配置目录(可选)
├── code_review.json
├── generate_api_doc.json
└── ...
主配置文件定义了服务器的基本信息和操作参数。
| 字段 | 类型 | 必填 | 描述 |
|---|---|---|---|
port | 数字 | 是 | 服务器监听端口号(1-65535) |
serverInfo | 对象 | 是 | 服务器信息对象 |
serverInfo.name | 字符串 | 是 | 服务器名称(标识符,建议使用小写字母和连字符) |
serverInfo.title | 字符串 | 是 | 服务器显示标题 |
serverInfo.version | 字符串 | 是 | 服务器版本号(遵循语义版本规范) |
instructions | 字符串 | 否 | 服务器使用说明(可选,用于向客户端描述服务器功能) |
{
"port": 5555,
"serverInfo": {
"name": "mcp-x-server",
"title": "MCP X 服务器示例",
"version": "1.0.0"
},
"instructions": "这是一个示例 MCP 服务器,提供了计算器工具、配置资源访问和代码审查提示词等功能。"
}
工具配置文件定义了服务器提供的工具,每个工具对应一个 JSON 文件。
| 字段 | 类型 | 必填 | 描述 |
|---|---|---|---|
name | 字符串 | 是 | 工具名称(唯一标识符,建议使用小写字母和下划线) |
title | 字符串 | 是 | 工具显示标题 |
description | 字符串 | 是 | 工具功能描述 |
execHandler | 字符串 | 是 | 处理器对象名称(必须与代码中的 QOarget 的 objectName 或 MPCToolHandlerName 属性匹配) |
execMethod | 字符串 | 是 | 方法名称(在处理器类中的 public slots 方法名称) |
inputSchema | 对象 | 是 | 输入参数 JSON Schema(定义工具输入参数的结构和类型) |
outputSchema | 对象 | 是 | 输出结果 JSON Schema(定义工具返回值的结构和类型) |
annotations | 对象 | 否 | 工具注释(可选,用于扩展元数据) |
annotations.audience | 数组 | 否 | 目标受众(例如 ["user", "assistant"]) |
annotations.priority | 数字 | 否 | 优先级(0.0-1.0) |
annotations.lastModified | 字符串 | 否 | 最后修改时间(ISO 8601 格式) |
这两个字段遵循 JSON Schema 规范,用于定义工具的参数和返回值结构。
InputSchema 示例:
{
"type": "object",
"properties": {
"a": {
"type": "number",
"description": "第一个数字"
},
"b": {
"type": "number",
"description": "第二个数字"
},
"operation": {
"type": "string",
"description": "操作类型",
"enum": ["add", "subtract", "multiply", "divide"]
}
},
"required": ["a", "b", "operation"]
}
OutputSchema 示例:
{
"type": "object",
"description": "计算器操作结果",
"properties": {
"operands": {
"type": "array",
"description": "参与运算的操作数",
"items": {
"type": "number"
}
},
"operation": {
"type": "string",
"description": "执行的操作"
},
"result": {
"type": "number",
"description": "计算结果"
},
"success": {
"type": "boolean",
"description": "操作是否成功"
},
"timestamp": {
"type": "string",
"description": "操作时间戳"
}
},
"required": ["operands", "operation", "result", "success", "timestamp"]
}
工具处理方法必须满足以下要求:
public slots:使用 Qt 的元对象系统inputSchema 中定义的类型匹配
number → C++ double 或 intstring → C++ QStringboolean → C++ boolarray → C++ QJsonArrayobject → C++ QJsonObjectQJsonObject 并且结构符合 outputSchema示例方法签名:
// 对应上面的 inputSchema
QJsonObject calculateOperation(double a, double b, const QString& operation);
{
"name": "calculator",
"title": "计算器",
"description": "支持基本数学运算的计算器工具(加、减、乘、除)",
"execHandler": "MyExampleHandler",