refined a bit
parent
ecbaec8ddf
commit
14ff6f9bdc
|
@ -0,0 +1,106 @@
|
|||
# Extensions
|
||||
|
||||
*.a
|
||||
*.bat
|
||||
*.bin
|
||||
*.d
|
||||
*.dll
|
||||
*.dot
|
||||
*.etag
|
||||
*.exe
|
||||
*.gcda
|
||||
*.gcno
|
||||
*.gcov
|
||||
*.gguf
|
||||
*.gguf.json
|
||||
*.lastModified
|
||||
*.log
|
||||
*.metallib
|
||||
*.o
|
||||
*.so
|
||||
*.tmp
|
||||
|
||||
# IDE / OS
|
||||
|
||||
.cache/
|
||||
.ccls-cache/
|
||||
.direnv/
|
||||
.DS_Store
|
||||
.envrc
|
||||
.idea/
|
||||
.swiftpm
|
||||
.vs/
|
||||
.vscode/
|
||||
nppBackup
|
||||
|
||||
|
||||
# Coverage
|
||||
|
||||
gcovr-report/
|
||||
lcov-report/
|
||||
|
||||
# Build Artifacts
|
||||
|
||||
tags
|
||||
.build/
|
||||
build*
|
||||
!build-info.cmake
|
||||
!build-info.cpp.in
|
||||
!build-info.sh
|
||||
!build.zig
|
||||
!docs/build.md
|
||||
/libllama.so
|
||||
/llama-*
|
||||
/vulkan-shaders-gen
|
||||
android-ndk-*
|
||||
arm_neon.h
|
||||
cmake-build-*
|
||||
CMakeSettings.json
|
||||
compile_commands.json
|
||||
ggml-metal-embed.metal
|
||||
llama-batched-swift
|
||||
/rpc-server
|
||||
out/
|
||||
tmp/
|
||||
autogen-*.md
|
||||
|
||||
# CI
|
||||
|
||||
!.github/workflows/*.yml
|
||||
|
||||
# Models
|
||||
|
||||
models/*
|
||||
models-mnt
|
||||
!models/.editorconfig
|
||||
|
||||
# Zig
|
||||
|
||||
# Logs
|
||||
|
||||
|
||||
|
||||
# Examples
|
||||
|
||||
|
||||
# Server Web UI temporary files
|
||||
node_modules
|
||||
examples/server/webui/dist
|
||||
|
||||
# Python
|
||||
|
||||
/.venv
|
||||
__pycache__/
|
||||
*/poetry.lock
|
||||
poetry.toml
|
||||
|
||||
# Nix
|
||||
/result
|
||||
|
||||
# Test binaries
|
||||
|
||||
# Scripts
|
||||
|
||||
# Test models for lora adapters
|
||||
|
||||
# Local scripts
|
|
@ -1,5 +1,5 @@
|
|||
cmake_minimum_required(VERSION 3.10)
|
||||
project(MCP VERSION 1.0.0 LANGUAGES CXX)
|
||||
project(MCP VERSION 2024.11.05 LANGUAGES CXX)
|
||||
|
||||
# Set C++ standard
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
|
|
@ -7,33 +7,37 @@ This implementation provides a complete C++ framework for the Model Context Prot
|
|||
## Directory Structure
|
||||
|
||||
```
|
||||
/MCP/
|
||||
├── mcp_protocol.h/cpp - Core protocol definitions
|
||||
├── mcp_server.h/cpp - Server implementation
|
||||
├── mcp_client.h/cpp - Client implementation
|
||||
├── mcp_resource.h - Resource definitions
|
||||
├── mcp_tools.h/cpp - Tool and workflow system implementation
|
||||
├── mcp_workflow_resource.h/cpp - Workflow resource implementation
|
||||
├── mcp_agent_resource.cpp - Agent resource implementation
|
||||
├── CMakeLists.txt - Build system configuration
|
||||
├── README.md - Project documentation
|
||||
└── examples/ - Example implementations
|
||||
├── custom_agent.h/cpp - Custom agent implementations
|
||||
├── server_example.cpp - Server example
|
||||
├── client_example.cpp - Client example
|
||||
└── host_example.cpp - Host example
|
||||
/cpp-mcp/
|
||||
├── include/ - Header files directory
|
||||
│ ├── mcp_client.h - Client interface definition
|
||||
│ ├── mcp_message.h - Core protocol definition
|
||||
│ ├── mcp_resource.h - Resource definition
|
||||
│ ├── mcp_server.h - Server interface definition
|
||||
│ └── mcp_tool.h - Tool system definition
|
||||
├── src/ - Source code directory
|
||||
│ ├── mcp_client.cpp - Client implementation
|
||||
│ ├── mcp_message.cpp - Protocol message implementation
|
||||
│ ├── mcp_resource.cpp - Resource system implementation
|
||||
│ ├── mcp_server.cpp - Server implementation
|
||||
│ ├── mcp_tool.cpp - Tool system implementation
|
||||
│ └── CMakeLists.txt - Source code build configuration
|
||||
├── examples/ - Example code
|
||||
│ ├── client_example.cpp - Client example
|
||||
│ └── server_example.cpp - Server example
|
||||
├── CMakeLists.txt - Main build configuration
|
||||
├── LICENSE - License file
|
||||
└── README.md - Project documentation
|
||||
```
|
||||
|
||||
## Key Components
|
||||
|
||||
### 1. Core Protocol (mcp_protocol.h/cpp)
|
||||
### 1. Core Protocol (mcp_message.h/cpp)
|
||||
|
||||
Defines the fundamental structures of the MCP protocol:
|
||||
Defines the fundamental message structures of the MCP protocol:
|
||||
|
||||
- `request` and `response` structures
|
||||
- Error handling with `error_code` and `mcp_exception`
|
||||
- Resource interface (`resource` base class)
|
||||
- Tool definition structure (`tool`)
|
||||
|
||||
### 2. Server (mcp_server.h/cpp)
|
||||
|
||||
|
@ -62,22 +66,13 @@ Defines various resource types:
|
|||
- `api_resource`: Custom API endpoints
|
||||
- `image_resource`: Image handling
|
||||
|
||||
### 5. Tool System (mcp_tools.h/cpp) - New Implementation
|
||||
### 5. Tool System (mcp_tool.h/cpp)
|
||||
|
||||
Provides tool-related functionality:
|
||||
|
||||
- `tool_registry`: Central registry for tools
|
||||
- `tool_builder`: Fluent API for tool creation
|
||||
- `workflow_step`: Single step in a workflow
|
||||
- `workflow`: Define and execute sequences of tool calls
|
||||
- `agent`: Base class for agents
|
||||
|
||||
### 6. Workflow Resources (mcp_workflow_resource.h/cpp, mcp_agent_resource.cpp) - New Implementation
|
||||
|
||||
Implements resources for workflow and agent management:
|
||||
|
||||
- `workflow_resource`: Create, manage, and execute workflows
|
||||
- `agent_resource`: Register and manage agents
|
||||
|
||||
## Usage Examples
|
||||
|
||||
|
@ -154,37 +149,9 @@ public:
|
|||
|
||||
The framework is specifically designed to support agent workflows with:
|
||||
|
||||
1. **Workflow Engine**: Define sequences of tool calls with data passing
|
||||
2. **Agent Base Class**: Easily create custom agents
|
||||
3. **Tool Registry**: Centralized tool management
|
||||
4. **Resource APIs**: RESTful interfaces for workflow and agent management
|
||||
1. **Tool Registry**: Centralized tool management
|
||||
2. **Resource APIs**: RESTful interfaces for workflow and agent management
|
||||
|
||||
## Custom Agent Examples
|
||||
|
||||
Three example agent implementations are provided:
|
||||
|
||||
1. **Echo Agent**: Simple agent that echoes back input with optional processing
|
||||
2. **Workflow Agent**: Executes predefined workflows
|
||||
3. **Chain Agent**: Chains multiple tools together with data mapping
|
||||
|
||||
## Host Integration
|
||||
|
||||
The host example demonstrates how to:
|
||||
|
||||
1. Combine server and client functionality
|
||||
2. Manage connections to other MCP servers
|
||||
3. Create workflows that span multiple servers
|
||||
4. Register and manage agents
|
||||
|
||||
## Building the Project
|
||||
|
||||
Use the provided CMakeLists.txt:
|
||||
|
||||
```bash
|
||||
mkdir build && cd build
|
||||
cmake ..
|
||||
make
|
||||
```
|
||||
|
||||
## Extending the Framework
|
||||
|
||||
|
@ -254,7 +221,3 @@ This MCP Protocol framework provides a robust foundation for building agent-base
|
|||
|
||||
- **Standardized Communication**: Common protocol for all components
|
||||
- **Extensible Design**: Easy to add new tools, resources, and agents
|
||||
- **Workflow Support**: Define and execute complex workflows
|
||||
- **Agent Framework**: Create specialized agents for different tasks
|
||||
|
||||
The implementation uses lower_line_naming_style as requested and provides comprehensive examples of customized host, client, and server configurations.
|
241
README.md
241
README.md
|
@ -1,241 +0,0 @@
|
|||
# MCP Protocol Framework
|
||||
|
||||
The Model Context Protocol (MCP) provides a standardized way for AI models and agents to interact with various resources, tools, and services. This framework implements the core functionality of MCP in C++ with support for agent workflows.
|
||||
|
||||
## Core Features
|
||||
|
||||
- **HTTP-based Communication**: RESTful API for client-server interaction
|
||||
- **Resource Abstraction**: Standard interface for files, directories, APIs, and more
|
||||
- **Tool Registry**: Register and invoke tools with structured parameters
|
||||
- **Agent Framework**: Create agents that can process requests and use tools
|
||||
- **Workflow System**: Define and execute sequences of tool calls
|
||||
- **Extensible Architecture**: Easy to extend with new resource types and tools
|
||||
|
||||
## Components
|
||||
|
||||
### Core Protocol (`mcp_protocol.h`, `mcp_protocol.cpp`)
|
||||
|
||||
Defines the fundamental structures and types for MCP:
|
||||
- Request/response handling
|
||||
- Error codes
|
||||
- Resource interfaces
|
||||
- Tool definitions
|
||||
|
||||
### Server (`mcp_server.h`, `mcp_server.cpp`)
|
||||
|
||||
Implements an HTTP server that exposes MCP resources and tools:
|
||||
- Register resources at specific paths
|
||||
- Register tools with handlers
|
||||
- Process incoming HTTP requests
|
||||
- Route requests to appropriate resources
|
||||
|
||||
### Client (`mcp_client.h`, `mcp_client.cpp`)
|
||||
|
||||
Implements a client for connecting to MCP servers:
|
||||
- Connect to servers
|
||||
- Discover available resources and tools
|
||||
- Make requests to resources
|
||||
- Call tools with parameters
|
||||
|
||||
### Resources (`mcp_resource.h`)
|
||||
|
||||
Provides base implementations for common resource types:
|
||||
- File resources
|
||||
- Directory resources
|
||||
- API resources
|
||||
- Image resources
|
||||
|
||||
### Tools (`mcp_tools.h`, `mcp_tools.cpp`)
|
||||
|
||||
Provides tool-related functionality and agent workflow support:
|
||||
- Tool registry
|
||||
- Tool builder (fluent API)
|
||||
- Workflow definition and execution
|
||||
- Agent base class
|
||||
|
||||
### Workflow (`mcp_workflow_resource.h`, `mcp_workflow_resource.cpp`, `mcp_agent_resource.cpp`)
|
||||
|
||||
Implements resources for workflow and agent management:
|
||||
- Create and manage workflows
|
||||
- Execute workflows
|
||||
- Register and manage agents
|
||||
- Process requests with agents
|
||||
|
||||
## Examples
|
||||
|
||||
### Custom Agents (`examples/custom_agent.h`, `examples/custom_agent.cpp`)
|
||||
|
||||
Examples of custom agent implementations:
|
||||
- Echo agent: Simple agent that echoes back input with optional processing
|
||||
- Workflow agent: An agent that executes pre-defined workflows
|
||||
- Chain agent: An agent that chains multiple tools together
|
||||
|
||||
### Server Example (`examples/server_example.cpp`)
|
||||
|
||||
Example of an MCP server implementation with custom tools:
|
||||
- Time tool: Get the current time
|
||||
- Calculator tool: Perform mathematical operations
|
||||
- Text processor tool: Process and analyze text
|
||||
- Custom workflow and agent registration
|
||||
|
||||
### Client Example (`examples/client_example.cpp`)
|
||||
|
||||
Example of an MCP client connecting to a server:
|
||||
- Get server information
|
||||
- List available tools
|
||||
- Call tools with parameters
|
||||
- List and execute workflows
|
||||
- Interact with agents
|
||||
|
||||
### Host Example (`examples/host_example.cpp`)
|
||||
|
||||
Example of a host that combines server and client functionality:
|
||||
- Register local tools and resources
|
||||
- Connect to other MCP servers
|
||||
- Create workflows that combine local and remote tools
|
||||
- Manage connections to other servers
|
||||
|
||||
## How to Use
|
||||
|
||||
### Setting Up a Server
|
||||
|
||||
```cpp
|
||||
// Create and configure the server
|
||||
mcp::server server("localhost", 8080);
|
||||
server.set_name("MCP Example Server");
|
||||
|
||||
// Register a tool
|
||||
mcp::tool time_tool = mcp::tool_builder("get_time")
|
||||
.with_description("Get the current time")
|
||||
.build();
|
||||
|
||||
server.register_tool(time_tool, [](const mcp::json& params) {
|
||||
// Tool implementation
|
||||
return mcp::json::object();
|
||||
});
|
||||
|
||||
// Register a resource
|
||||
auto file_resource = std::make_shared<mcp::file_resource>("./files");
|
||||
server.register_resource("/files", file_resource);
|
||||
|
||||
// Start the server
|
||||
server.start(true); // Blocking mode
|
||||
```
|
||||
|
||||
### Creating a Client
|
||||
|
||||
```cpp
|
||||
// Connect to a server
|
||||
mcp::client client("localhost", 8080);
|
||||
|
||||
// Get server information
|
||||
mcp::json server_info = client.get_server_info();
|
||||
|
||||
// Call a tool
|
||||
mcp::json params = {
|
||||
{"key", "value"}
|
||||
};
|
||||
mcp::json result = client.call_tool("tool_name", params);
|
||||
```
|
||||
|
||||
### Defining a Workflow
|
||||
|
||||
```cpp
|
||||
// Create a workflow
|
||||
mcp::workflow workflow("example_workflow", "Example workflow description");
|
||||
|
||||
// Add steps to the workflow
|
||||
workflow.add_tool_call("get_time");
|
||||
workflow.add_tool_call("text_processor", {
|
||||
{"text", "Example text"},
|
||||
{"to_uppercase", true}
|
||||
});
|
||||
|
||||
// Execute the workflow
|
||||
mcp::json context = workflow.execute();
|
||||
```
|
||||
|
||||
### Creating a Custom Agent
|
||||
|
||||
```cpp
|
||||
// Define a custom agent
|
||||
class my_agent : public mcp::agent {
|
||||
public:
|
||||
my_agent() : mcp::agent("MyAgent") {}
|
||||
|
||||
void initialize(const mcp::json& config) override {
|
||||
// Initialize from config
|
||||
}
|
||||
|
||||
mcp::json process(const mcp::json& input) override {
|
||||
// Process input
|
||||
return mcp::json::object();
|
||||
}
|
||||
};
|
||||
|
||||
// Register the agent with a server
|
||||
auto agent_ptr = std::make_shared<my_agent>();
|
||||
agent_ptr->initialize({});
|
||||
|
||||
auto agent_resource = std::make_shared<mcp::agent_resource>();
|
||||
agent_resource->register_agent(agent_ptr);
|
||||
server.register_resource("/agents", agent_resource);
|
||||
```
|
||||
|
||||
## Building the Framework
|
||||
|
||||
The framework depends on the following libraries:
|
||||
- httplib.h - HTTP server and client
|
||||
- json.hpp - JSON parsing and generation
|
||||
- base64.hpp - Base64 encoding/decoding
|
||||
- stb_image.h - Image loading (for image resources)
|
||||
|
||||
All dependencies are included in the repository.
|
||||
|
||||
To build the examples:
|
||||
```bash
|
||||
g++ -std=c++17 examples/server_example.cpp mcp_protocol.cpp mcp_server.cpp mcp_tools.cpp mcp_workflow_resource.cpp mcp_agent_resource.cpp -pthread -o server_example
|
||||
g++ -std=c++17 examples/client_example.cpp mcp_protocol.cpp mcp_client.cpp -pthread -o client_example
|
||||
g++ -std=c++17 examples/host_example.cpp mcp_protocol.cpp mcp_server.cpp mcp_client.cpp mcp_tools.cpp mcp_workflow_resource.cpp mcp_agent_resource.cpp -pthread -o host_example
|
||||
```
|
||||
|
||||
## Extending the Framework
|
||||
|
||||
### Adding New Resource Types
|
||||
|
||||
1. Define a new class that inherits from `mcp::resource`
|
||||
2. Implement the required methods:
|
||||
- `resource_type type() const`
|
||||
- `json metadata() const`
|
||||
- `response handle_request(const request& req)`
|
||||
- `json schema() const` (optional)
|
||||
|
||||
### Creating Custom Tools
|
||||
|
||||
Use the tool builder API:
|
||||
```cpp
|
||||
// Create a tool definition
|
||||
mcp::tool my_tool = mcp::tool_builder("my_tool")
|
||||
.with_description("My custom tool")
|
||||
.with_string_param("input", "Input parameter", true)
|
||||
.with_number_param("count", "Count parameter", false)
|
||||
.build();
|
||||
|
||||
// Register the tool handler
|
||||
server.register_tool(my_tool, [](const mcp::json& params) {
|
||||
// Tool implementation
|
||||
return mcp::json::object();
|
||||
});
|
||||
```
|
||||
|
||||
### Implementing Custom Agents
|
||||
|
||||
1. Define a new class that inherits from `mcp::agent`
|
||||
2. Implement the required methods:
|
||||
- `void initialize(const mcp::json& config)`
|
||||
- `mcp::json process(const mcp::json& input)`
|
||||
3. Register the agent with an agent resource
|
||||
|
||||
## License
|
||||
|
||||
This framework is provided under the MIT License. See the LICENSE file for details.
|
|
@ -0,0 +1,151 @@
|
|||
# MCP Protocol Framework
|
||||
|
||||
Model Context Protocol (MCP) 是一个开放协议,为AI模型和代理提供与各种资源、工具和服务交互的标准化方式。本框架实现了MCP协议的核心功能,符合2024-11-05基本协议规范。
|
||||
|
||||
## 核心特性
|
||||
|
||||
- **JSON-RPC 2.0通信**: 基于JSON-RPC 2.0标准的请求/响应通信
|
||||
- **资源抽象**: 文件、API等资源的标准接口
|
||||
- **工具注册**: 注册和调用带有结构化参数的工具
|
||||
- **可扩展架构**: 易于扩展新的资源类型和工具
|
||||
|
||||
## 组件
|
||||
|
||||
### 核心协议 (`mcp_message.h`, `mcp_message.cpp`)
|
||||
|
||||
定义MCP的基本结构和类型:
|
||||
- 请求/响应处理
|
||||
- 错误代码
|
||||
- 工具定义
|
||||
|
||||
### 服务器 (`mcp_server.h`, `mcp_server.cpp`)
|
||||
|
||||
实现一个HTTP服务器,暴露MCP资源和工具:
|
||||
- 在特定路径注册资源
|
||||
- 注册带有处理程序的工具
|
||||
- 处理传入的HTTP请求
|
||||
- 将请求路由到适当的资源
|
||||
|
||||
### 客户端 (`mcp_client.h`, `mcp_client.cpp`)
|
||||
|
||||
实现连接到MCP服务器的客户端:
|
||||
- 连接到服务器
|
||||
- 发现可用的资源和工具
|
||||
- 向资源发出请求
|
||||
- 使用参数调用工具
|
||||
|
||||
### 资源 (`mcp_resource.h`, `mcp_resource.cpp`)
|
||||
|
||||
提供常见资源类型的基本实现:
|
||||
- 文件资源
|
||||
- API资源
|
||||
|
||||
### 工具 (`mcp_tool.h`, `mcp_tool.cpp`)
|
||||
|
||||
提供工具相关功能:
|
||||
- 工具构建器 (流畅API)
|
||||
|
||||
## 示例
|
||||
|
||||
### 服务器示例 (`examples/server_example.cpp`)
|
||||
|
||||
MCP服务器实现示例,带有自定义工具:
|
||||
- 时间工具: 获取当前时间
|
||||
- 计算器工具: 执行数学运算
|
||||
- 回显工具: 处理和分析文本
|
||||
|
||||
### 客户端示例 (`examples/client_example.cpp`)
|
||||
|
||||
连接到服务器的MCP客户端示例:
|
||||
- 获取服务器信息
|
||||
- 列出可用工具
|
||||
- 使用参数调用工具
|
||||
- 访问资源
|
||||
|
||||
## 如何使用
|
||||
|
||||
### 设置服务器
|
||||
|
||||
```cpp
|
||||
// 创建并配置服务器
|
||||
mcp::server server("localhost", 8080);
|
||||
server.set_server_info("MCP Example Server", "2024-11-05");
|
||||
|
||||
// 注册工具
|
||||
mcp::tool time_tool = mcp::tool_builder("get_time")
|
||||
.with_description("Get the current time")
|
||||
.build();
|
||||
|
||||
server.register_tool(time_tool, [](const mcp::json& params) {
|
||||
// 工具实现
|
||||
return mcp::json::object();
|
||||
});
|
||||
|
||||
// 注册资源
|
||||
auto file_resource = std::make_shared<mcp::file_resource>("./files");
|
||||
server.register_resource("/files", file_resource);
|
||||
|
||||
// 启动服务器
|
||||
server.start(true); // 阻塞模式
|
||||
```
|
||||
|
||||
### 创建客户端
|
||||
|
||||
```cpp
|
||||
// 连接到服务器
|
||||
mcp::client client("localhost", 8080);
|
||||
|
||||
// 初始化连接
|
||||
client.initialize("My Client", "1.0.0");
|
||||
|
||||
// 调用工具
|
||||
mcp::json params = {
|
||||
{"key", "value"}
|
||||
};
|
||||
mcp::json result = client.call_tool("tool_name", params);
|
||||
```
|
||||
|
||||
## 构建框架
|
||||
|
||||
框架依赖以下库:
|
||||
- httplib.h - HTTP服务器和客户端
|
||||
- json.hpp - JSON解析和生成
|
||||
|
||||
所有依赖项都包含在仓库中。
|
||||
|
||||
使用CMake构建示例:
|
||||
```bash
|
||||
cmake -B build
|
||||
cmake --build build --config Release
|
||||
```
|
||||
|
||||
## 扩展框架
|
||||
|
||||
### 添加新的资源类型
|
||||
|
||||
1. 定义一个继承自`mcp::resource`的新类
|
||||
2. 实现所需的方法:
|
||||
- `json get_metadata() const`
|
||||
- `json access(const json& params) const`
|
||||
|
||||
### 创建自定义工具
|
||||
|
||||
使用工具构建器API:
|
||||
```cpp
|
||||
// 创建工具定义
|
||||
mcp::tool my_tool = mcp::tool_builder("my_tool")
|
||||
.with_description("My custom tool")
|
||||
.with_string_param("input", "Input parameter", true)
|
||||
.with_number_param("count", "Count parameter", false)
|
||||
.build();
|
||||
|
||||
// 注册工具处理程序
|
||||
server.register_tool(my_tool, [](const mcp::json& params) {
|
||||
// 工具实现
|
||||
return mcp::json::object();
|
||||
});
|
||||
```
|
||||
|
||||
## 许可证
|
||||
|
||||
本框架根据MIT许可证提供。有关详细信息,请参阅LICENSE文件。
|
|
@ -131,16 +131,16 @@ CMAKE_PROJECT_HOMEPAGE_URL:STATIC=
|
|||
CMAKE_PROJECT_NAME:STATIC=MCP
|
||||
|
||||
//Value Computed by CMake
|
||||
CMAKE_PROJECT_VERSION:STATIC=1.0.0
|
||||
CMAKE_PROJECT_VERSION:STATIC=2024.11.5
|
||||
|
||||
//Value Computed by CMake
|
||||
CMAKE_PROJECT_VERSION_MAJOR:STATIC=1
|
||||
CMAKE_PROJECT_VERSION_MAJOR:STATIC=2024
|
||||
|
||||
//Value Computed by CMake
|
||||
CMAKE_PROJECT_VERSION_MINOR:STATIC=0
|
||||
CMAKE_PROJECT_VERSION_MINOR:STATIC=11
|
||||
|
||||
//Value Computed by CMake
|
||||
CMAKE_PROJECT_VERSION_PATCH:STATIC=0
|
||||
CMAKE_PROJECT_VERSION_PATCH:STATIC=5
|
||||
|
||||
//Value Computed by CMake
|
||||
CMAKE_PROJECT_VERSION_TWEAK:STATIC=
|
||||
|
|
Binary file not shown.
|
@ -58,8 +58,8 @@ events:
|
|||
checks:
|
||||
- "Detecting CXX compiler ABI info"
|
||||
directories:
|
||||
source: "/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles/CMakeScratch/TryCompile-iTVz2W"
|
||||
binary: "/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles/CMakeScratch/TryCompile-iTVz2W"
|
||||
source: "/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles/CMakeScratch/TryCompile-t8bpiU"
|
||||
binary: "/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles/CMakeScratch/TryCompile-t8bpiU"
|
||||
cmakeVariables:
|
||||
CMAKE_CXX_FLAGS: ""
|
||||
CMAKE_CXX_FLAGS_DEBUG: "-g"
|
||||
|
@ -72,18 +72,18 @@ events:
|
|||
variable: "CMAKE_CXX_ABI_COMPILED"
|
||||
cached: true
|
||||
stdout: |
|
||||
Change Dir: '/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles/CMakeScratch/TryCompile-iTVz2W'
|
||||
Change Dir: '/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles/CMakeScratch/TryCompile-t8bpiU'
|
||||
|
||||
Run Build Command(s): /opt/homebrew/bin/cmake -E env VERBOSE=1 /usr/bin/make -f Makefile cmTC_81138/fast
|
||||
/Library/Developer/CommandLineTools/usr/bin/make -f CMakeFiles/cmTC_81138.dir/build.make CMakeFiles/cmTC_81138.dir/build
|
||||
Building CXX object CMakeFiles/cmTC_81138.dir/CMakeCXXCompilerABI.cpp.o
|
||||
/Library/Developer/CommandLineTools/usr/bin/c++ -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk -mmacosx-version-min=14.6 -v -Wl,-v -MD -MT CMakeFiles/cmTC_81138.dir/CMakeCXXCompilerABI.cpp.o -MF CMakeFiles/cmTC_81138.dir/CMakeCXXCompilerABI.cpp.o.d -o CMakeFiles/cmTC_81138.dir/CMakeCXXCompilerABI.cpp.o -c /opt/homebrew/share/cmake/Modules/CMakeCXXCompilerABI.cpp
|
||||
Run Build Command(s): /opt/homebrew/bin/cmake -E env VERBOSE=1 /usr/bin/make -f Makefile cmTC_20b78/fast
|
||||
/Library/Developer/CommandLineTools/usr/bin/make -f CMakeFiles/cmTC_20b78.dir/build.make CMakeFiles/cmTC_20b78.dir/build
|
||||
Building CXX object CMakeFiles/cmTC_20b78.dir/CMakeCXXCompilerABI.cpp.o
|
||||
/Library/Developer/CommandLineTools/usr/bin/c++ -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk -mmacosx-version-min=14.6 -v -Wl,-v -MD -MT CMakeFiles/cmTC_20b78.dir/CMakeCXXCompilerABI.cpp.o -MF CMakeFiles/cmTC_20b78.dir/CMakeCXXCompilerABI.cpp.o.d -o CMakeFiles/cmTC_20b78.dir/CMakeCXXCompilerABI.cpp.o -c /opt/homebrew/share/cmake/Modules/CMakeCXXCompilerABI.cpp
|
||||
Apple clang version 15.0.0 (clang-1500.3.9.4)
|
||||
Target: arm64-apple-darwin23.6.0
|
||||
Thread model: posix
|
||||
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
|
||||
clang: warning: -Wl,-v: 'linker' input unused [-Wunused-command-line-argument]
|
||||
"/Library/Developer/CommandLineTools/usr/bin/clang" -cc1 -triple arm64-apple-macosx14.6.0 -Wundef-prefix=TARGET_OS_ -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -Werror=implicit-function-declaration -emit-obj -mrelax-all --mrelax-relocations -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name CMakeCXXCompilerABI.cpp -mrelocation-model pic -pic-level 2 -mframe-pointer=non-leaf -fno-strict-return -ffp-contract=on -fno-rounding-math -funwind-tables=1 -fobjc-msgsend-selector-stubs -target-sdk-version=15.0 -fvisibility-inlines-hidden-static-local-var -target-cpu apple-m1 -target-feature +v8.5a -target-feature +crc -target-feature +lse -target-feature +rdm -target-feature +crypto -target-feature +dotprod -target-feature +fp-armv8 -target-feature +neon -target-feature +fp16fml -target-feature +ras -target-feature +rcpc -target-feature +zcm -target-feature +zcz -target-feature +fullfp16 -target-feature +sm4 -target-feature +sha3 -target-feature +sha2 -target-feature +aes -target-abi darwinpcs -debugger-tuning=lldb -target-linker-version 1053.12 -v -fcoverage-compilation-dir=/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles/CMakeScratch/TryCompile-iTVz2W -resource-dir /Library/Developer/CommandLineTools/usr/lib/clang/15.0.0 -dependency-file CMakeFiles/cmTC_81138.dir/CMakeCXXCompilerABI.cpp.o.d -skip-unused-modulemap-deps -MT CMakeFiles/cmTC_81138.dir/CMakeCXXCompilerABI.cpp.o -sys-header-deps -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk -internal-isystem /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1 -internal-isystem /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/local/include -internal-isystem /Library/Developer/CommandLineTools/usr/lib/clang/15.0.0/include -internal-externc-isystem /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include -internal-externc-isystem /Library/Developer/CommandLineTools/usr/include -Wno-reorder-init-list -Wno-implicit-int-float-conversion -Wno-c99-designator -Wno-final-dtor-non-final-class -Wno-extra-semi-stmt -Wno-misleading-indentation -Wno-quoted-include-in-framework-header -Wno-implicit-fallthrough -Wno-enum-enum-conversion -Wno-enum-float-conversion -Wno-elaborated-enum-base -Wno-reserved-identifier -Wno-gnu-folding-constant -fdeprecated-macro -fdebug-compilation-dir=/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles/CMakeScratch/TryCompile-iTVz2W -ferror-limit 19 -stack-protector 1 -fstack-check -mdarwin-stkchk-strong-link -fblocks -fencode-extended-block-signature -fregister-global-dtors-with-atexit -fgnuc-version=4.2.1 -fno-cxx-modules -fcxx-exceptions -fexceptions -fmax-type-align=16 -fcommon -clang-vendor-feature=+disableNonDependentMemberExprInCurrentInstantiation -fno-odr-hash-protocols -clang-vendor-feature=+enableAggressiveVLAFolding -clang-vendor-feature=+revert09abecef7bbf -clang-vendor-feature=+thisNoAlignAttr -clang-vendor-feature=+thisNoNullAttr -mllvm -disable-aligned-alloc-awareness=1 -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o CMakeFiles/cmTC_81138.dir/CMakeCXXCompilerABI.cpp.o -x c++ /opt/homebrew/share/cmake/Modules/CMakeCXXCompilerABI.cpp
|
||||
"/Library/Developer/CommandLineTools/usr/bin/clang" -cc1 -triple arm64-apple-macosx14.6.0 -Wundef-prefix=TARGET_OS_ -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -Werror=implicit-function-declaration -emit-obj -mrelax-all --mrelax-relocations -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name CMakeCXXCompilerABI.cpp -mrelocation-model pic -pic-level 2 -mframe-pointer=non-leaf -fno-strict-return -ffp-contract=on -fno-rounding-math -funwind-tables=1 -fobjc-msgsend-selector-stubs -target-sdk-version=15.0 -fvisibility-inlines-hidden-static-local-var -target-cpu apple-m1 -target-feature +v8.5a -target-feature +crc -target-feature +lse -target-feature +rdm -target-feature +crypto -target-feature +dotprod -target-feature +fp-armv8 -target-feature +neon -target-feature +fp16fml -target-feature +ras -target-feature +rcpc -target-feature +zcm -target-feature +zcz -target-feature +fullfp16 -target-feature +sm4 -target-feature +sha3 -target-feature +sha2 -target-feature +aes -target-abi darwinpcs -debugger-tuning=lldb -target-linker-version 1053.12 -v -fcoverage-compilation-dir=/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles/CMakeScratch/TryCompile-t8bpiU -resource-dir /Library/Developer/CommandLineTools/usr/lib/clang/15.0.0 -dependency-file CMakeFiles/cmTC_20b78.dir/CMakeCXXCompilerABI.cpp.o.d -skip-unused-modulemap-deps -MT CMakeFiles/cmTC_20b78.dir/CMakeCXXCompilerABI.cpp.o -sys-header-deps -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk -internal-isystem /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1 -internal-isystem /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/local/include -internal-isystem /Library/Developer/CommandLineTools/usr/lib/clang/15.0.0/include -internal-externc-isystem /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include -internal-externc-isystem /Library/Developer/CommandLineTools/usr/include -Wno-reorder-init-list -Wno-implicit-int-float-conversion -Wno-c99-designator -Wno-final-dtor-non-final-class -Wno-extra-semi-stmt -Wno-misleading-indentation -Wno-quoted-include-in-framework-header -Wno-implicit-fallthrough -Wno-enum-enum-conversion -Wno-enum-float-conversion -Wno-elaborated-enum-base -Wno-reserved-identifier -Wno-gnu-folding-constant -fdeprecated-macro -fdebug-compilation-dir=/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles/CMakeScratch/TryCompile-t8bpiU -ferror-limit 19 -stack-protector 1 -fstack-check -mdarwin-stkchk-strong-link -fblocks -fencode-extended-block-signature -fregister-global-dtors-with-atexit -fgnuc-version=4.2.1 -fno-cxx-modules -fcxx-exceptions -fexceptions -fmax-type-align=16 -fcommon -clang-vendor-feature=+disableNonDependentMemberExprInCurrentInstantiation -fno-odr-hash-protocols -clang-vendor-feature=+enableAggressiveVLAFolding -clang-vendor-feature=+revert09abecef7bbf -clang-vendor-feature=+thisNoAlignAttr -clang-vendor-feature=+thisNoNullAttr -mllvm -disable-aligned-alloc-awareness=1 -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o CMakeFiles/cmTC_20b78.dir/CMakeCXXCompilerABI.cpp.o -x c++ /opt/homebrew/share/cmake/Modules/CMakeCXXCompilerABI.cpp
|
||||
clang -cc1 version 15.0.0 (clang-1500.3.9.4) default target arm64-apple-darwin23.6.0
|
||||
ignoring nonexistent directory "/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/local/include"
|
||||
ignoring nonexistent directory "/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/Library/Frameworks"
|
||||
|
@ -95,13 +95,13 @@ events:
|
|||
/Library/Developer/CommandLineTools/usr/include
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/System/Library/Frameworks (framework directory)
|
||||
End of search list.
|
||||
Linking CXX executable cmTC_81138
|
||||
/opt/homebrew/bin/cmake -E cmake_link_script CMakeFiles/cmTC_81138.dir/link.txt --verbose=1
|
||||
Linking CXX executable cmTC_20b78
|
||||
/opt/homebrew/bin/cmake -E cmake_link_script CMakeFiles/cmTC_20b78.dir/link.txt --verbose=1
|
||||
Apple clang version 15.0.0 (clang-1500.3.9.4)
|
||||
Target: arm64-apple-darwin23.6.0
|
||||
Thread model: posix
|
||||
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
|
||||
"/Library/Developer/CommandLineTools/usr/bin/ld" -demangle -lto_library /Library/Developer/CommandLineTools/usr/lib/libLTO.dylib -dynamic -arch arm64 -platform_version macos 14.6.0 15.0 -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk -o cmTC_81138 -L/opt/homebrew/opt/openssl@3/lib -search_paths_first -headerpad_max_install_names -v CMakeFiles/cmTC_81138.dir/CMakeCXXCompilerABI.cpp.o -lc++ -lSystem /Library/Developer/CommandLineTools/usr/lib/clang/15.0.0/lib/darwin/libclang_rt.osx.a
|
||||
"/Library/Developer/CommandLineTools/usr/bin/ld" -demangle -lto_library /Library/Developer/CommandLineTools/usr/lib/libLTO.dylib -dynamic -arch arm64 -platform_version macos 14.6.0 15.0 -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk -o cmTC_20b78 -L/opt/homebrew/opt/openssl@3/lib -search_paths_first -headerpad_max_install_names -v CMakeFiles/cmTC_20b78.dir/CMakeCXXCompilerABI.cpp.o -lc++ -lSystem /Library/Developer/CommandLineTools/usr/lib/clang/15.0.0/lib/darwin/libclang_rt.osx.a
|
||||
@(#)PROGRAM:ld PROJECT:ld-1053.12
|
||||
BUILD 15:45:29 Feb 3 2024
|
||||
configured to support archs: armv6 armv7 armv7s arm64 arm64e arm64_32 i386 x86_64 x86_64h armv6m armv7k armv7m armv7em
|
||||
|
@ -114,7 +114,7 @@ events:
|
|||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/lib/swift
|
||||
Framework search paths:
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/System/Library/Frameworks
|
||||
/Library/Developer/CommandLineTools/usr/bin/c++ -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk -mmacosx-version-min=14.6 -Wl,-search_paths_first -Wl,-headerpad_max_install_names -L/opt/homebrew/opt/openssl@3/lib -v -Wl,-v CMakeFiles/cmTC_81138.dir/CMakeCXXCompilerABI.cpp.o -o cmTC_81138
|
||||
/Library/Developer/CommandLineTools/usr/bin/c++ -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk -mmacosx-version-min=14.6 -Wl,-search_paths_first -Wl,-headerpad_max_install_names -L/opt/homebrew/opt/openssl@3/lib -v -Wl,-v CMakeFiles/cmTC_20b78.dir/CMakeCXXCompilerABI.cpp.o -o cmTC_20b78
|
||||
|
||||
exitCode: 0
|
||||
-
|
||||
|
@ -158,18 +158,18 @@ events:
|
|||
Parsed CXX implicit link information:
|
||||
link line regex: [^( *|.*[/\\])(ld[0-9]*(\\.[a-z]+)?|CMAKE_LINK_STARTFILE-NOTFOUND|([^/\\]+-)?ld|collect2)[^/\\]*( |$)]
|
||||
linker tool regex: [^[ ]*(->|")?[ ]*(([^"]*[/\\])?(ld[0-9]*(\\.[a-z]+)?))("|,| |$)]
|
||||
ignore line: [Change Dir: '/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles/CMakeScratch/TryCompile-iTVz2W']
|
||||
ignore line: [Change Dir: '/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles/CMakeScratch/TryCompile-t8bpiU']
|
||||
ignore line: []
|
||||
ignore line: [Run Build Command(s): /opt/homebrew/bin/cmake -E env VERBOSE=1 /usr/bin/make -f Makefile cmTC_81138/fast]
|
||||
ignore line: [/Library/Developer/CommandLineTools/usr/bin/make -f CMakeFiles/cmTC_81138.dir/build.make CMakeFiles/cmTC_81138.dir/build]
|
||||
ignore line: [Building CXX object CMakeFiles/cmTC_81138.dir/CMakeCXXCompilerABI.cpp.o]
|
||||
ignore line: [/Library/Developer/CommandLineTools/usr/bin/c++ -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk -mmacosx-version-min=14.6 -v -Wl -v -MD -MT CMakeFiles/cmTC_81138.dir/CMakeCXXCompilerABI.cpp.o -MF CMakeFiles/cmTC_81138.dir/CMakeCXXCompilerABI.cpp.o.d -o CMakeFiles/cmTC_81138.dir/CMakeCXXCompilerABI.cpp.o -c /opt/homebrew/share/cmake/Modules/CMakeCXXCompilerABI.cpp]
|
||||
ignore line: [Run Build Command(s): /opt/homebrew/bin/cmake -E env VERBOSE=1 /usr/bin/make -f Makefile cmTC_20b78/fast]
|
||||
ignore line: [/Library/Developer/CommandLineTools/usr/bin/make -f CMakeFiles/cmTC_20b78.dir/build.make CMakeFiles/cmTC_20b78.dir/build]
|
||||
ignore line: [Building CXX object CMakeFiles/cmTC_20b78.dir/CMakeCXXCompilerABI.cpp.o]
|
||||
ignore line: [/Library/Developer/CommandLineTools/usr/bin/c++ -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk -mmacosx-version-min=14.6 -v -Wl -v -MD -MT CMakeFiles/cmTC_20b78.dir/CMakeCXXCompilerABI.cpp.o -MF CMakeFiles/cmTC_20b78.dir/CMakeCXXCompilerABI.cpp.o.d -o CMakeFiles/cmTC_20b78.dir/CMakeCXXCompilerABI.cpp.o -c /opt/homebrew/share/cmake/Modules/CMakeCXXCompilerABI.cpp]
|
||||
ignore line: [Apple clang version 15.0.0 (clang-1500.3.9.4)]
|
||||
ignore line: [Target: arm64-apple-darwin23.6.0]
|
||||
ignore line: [Thread model: posix]
|
||||
ignore line: [InstalledDir: /Library/Developer/CommandLineTools/usr/bin]
|
||||
ignore line: [clang: warning: -Wl -v: 'linker' input unused [-Wunused-command-line-argument]]
|
||||
ignore line: [ "/Library/Developer/CommandLineTools/usr/bin/clang" -cc1 -triple arm64-apple-macosx14.6.0 -Wundef-prefix=TARGET_OS_ -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -Werror=implicit-function-declaration -emit-obj -mrelax-all --mrelax-relocations -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name CMakeCXXCompilerABI.cpp -mrelocation-model pic -pic-level 2 -mframe-pointer=non-leaf -fno-strict-return -ffp-contract=on -fno-rounding-math -funwind-tables=1 -fobjc-msgsend-selector-stubs -target-sdk-version=15.0 -fvisibility-inlines-hidden-static-local-var -target-cpu apple-m1 -target-feature +v8.5a -target-feature +crc -target-feature +lse -target-feature +rdm -target-feature +crypto -target-feature +dotprod -target-feature +fp-armv8 -target-feature +neon -target-feature +fp16fml -target-feature +ras -target-feature +rcpc -target-feature +zcm -target-feature +zcz -target-feature +fullfp16 -target-feature +sm4 -target-feature +sha3 -target-feature +sha2 -target-feature +aes -target-abi darwinpcs -debugger-tuning=lldb -target-linker-version 1053.12 -v -fcoverage-compilation-dir=/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles/CMakeScratch/TryCompile-iTVz2W -resource-dir /Library/Developer/CommandLineTools/usr/lib/clang/15.0.0 -dependency-file CMakeFiles/cmTC_81138.dir/CMakeCXXCompilerABI.cpp.o.d -skip-unused-modulemap-deps -MT CMakeFiles/cmTC_81138.dir/CMakeCXXCompilerABI.cpp.o -sys-header-deps -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk -internal-isystem /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1 -internal-isystem /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/local/include -internal-isystem /Library/Developer/CommandLineTools/usr/lib/clang/15.0.0/include -internal-externc-isystem /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include -internal-externc-isystem /Library/Developer/CommandLineTools/usr/include -Wno-reorder-init-list -Wno-implicit-int-float-conversion -Wno-c99-designator -Wno-final-dtor-non-final-class -Wno-extra-semi-stmt -Wno-misleading-indentation -Wno-quoted-include-in-framework-header -Wno-implicit-fallthrough -Wno-enum-enum-conversion -Wno-enum-float-conversion -Wno-elaborated-enum-base -Wno-reserved-identifier -Wno-gnu-folding-constant -fdeprecated-macro -fdebug-compilation-dir=/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles/CMakeScratch/TryCompile-iTVz2W -ferror-limit 19 -stack-protector 1 -fstack-check -mdarwin-stkchk-strong-link -fblocks -fencode-extended-block-signature -fregister-global-dtors-with-atexit -fgnuc-version=4.2.1 -fno-cxx-modules -fcxx-exceptions -fexceptions -fmax-type-align=16 -fcommon -clang-vendor-feature=+disableNonDependentMemberExprInCurrentInstantiation -fno-odr-hash-protocols -clang-vendor-feature=+enableAggressiveVLAFolding -clang-vendor-feature=+revert09abecef7bbf -clang-vendor-feature=+thisNoAlignAttr -clang-vendor-feature=+thisNoNullAttr -mllvm -disable-aligned-alloc-awareness=1 -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o CMakeFiles/cmTC_81138.dir/CMakeCXXCompilerABI.cpp.o -x c++ /opt/homebrew/share/cmake/Modules/CMakeCXXCompilerABI.cpp]
|
||||
ignore line: [ "/Library/Developer/CommandLineTools/usr/bin/clang" -cc1 -triple arm64-apple-macosx14.6.0 -Wundef-prefix=TARGET_OS_ -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -Werror=implicit-function-declaration -emit-obj -mrelax-all --mrelax-relocations -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name CMakeCXXCompilerABI.cpp -mrelocation-model pic -pic-level 2 -mframe-pointer=non-leaf -fno-strict-return -ffp-contract=on -fno-rounding-math -funwind-tables=1 -fobjc-msgsend-selector-stubs -target-sdk-version=15.0 -fvisibility-inlines-hidden-static-local-var -target-cpu apple-m1 -target-feature +v8.5a -target-feature +crc -target-feature +lse -target-feature +rdm -target-feature +crypto -target-feature +dotprod -target-feature +fp-armv8 -target-feature +neon -target-feature +fp16fml -target-feature +ras -target-feature +rcpc -target-feature +zcm -target-feature +zcz -target-feature +fullfp16 -target-feature +sm4 -target-feature +sha3 -target-feature +sha2 -target-feature +aes -target-abi darwinpcs -debugger-tuning=lldb -target-linker-version 1053.12 -v -fcoverage-compilation-dir=/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles/CMakeScratch/TryCompile-t8bpiU -resource-dir /Library/Developer/CommandLineTools/usr/lib/clang/15.0.0 -dependency-file CMakeFiles/cmTC_20b78.dir/CMakeCXXCompilerABI.cpp.o.d -skip-unused-modulemap-deps -MT CMakeFiles/cmTC_20b78.dir/CMakeCXXCompilerABI.cpp.o -sys-header-deps -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk -internal-isystem /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1 -internal-isystem /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/local/include -internal-isystem /Library/Developer/CommandLineTools/usr/lib/clang/15.0.0/include -internal-externc-isystem /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include -internal-externc-isystem /Library/Developer/CommandLineTools/usr/include -Wno-reorder-init-list -Wno-implicit-int-float-conversion -Wno-c99-designator -Wno-final-dtor-non-final-class -Wno-extra-semi-stmt -Wno-misleading-indentation -Wno-quoted-include-in-framework-header -Wno-implicit-fallthrough -Wno-enum-enum-conversion -Wno-enum-float-conversion -Wno-elaborated-enum-base -Wno-reserved-identifier -Wno-gnu-folding-constant -fdeprecated-macro -fdebug-compilation-dir=/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles/CMakeScratch/TryCompile-t8bpiU -ferror-limit 19 -stack-protector 1 -fstack-check -mdarwin-stkchk-strong-link -fblocks -fencode-extended-block-signature -fregister-global-dtors-with-atexit -fgnuc-version=4.2.1 -fno-cxx-modules -fcxx-exceptions -fexceptions -fmax-type-align=16 -fcommon -clang-vendor-feature=+disableNonDependentMemberExprInCurrentInstantiation -fno-odr-hash-protocols -clang-vendor-feature=+enableAggressiveVLAFolding -clang-vendor-feature=+revert09abecef7bbf -clang-vendor-feature=+thisNoAlignAttr -clang-vendor-feature=+thisNoNullAttr -mllvm -disable-aligned-alloc-awareness=1 -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o CMakeFiles/cmTC_20b78.dir/CMakeCXXCompilerABI.cpp.o -x c++ /opt/homebrew/share/cmake/Modules/CMakeCXXCompilerABI.cpp]
|
||||
ignore line: [clang -cc1 version 15.0.0 (clang-1500.3.9.4) default target arm64-apple-darwin23.6.0]
|
||||
ignore line: [ignoring nonexistent directory "/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/local/include"]
|
||||
ignore line: [ignoring nonexistent directory "/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/Library/Frameworks"]
|
||||
|
@ -181,13 +181,13 @@ events:
|
|||
ignore line: [ /Library/Developer/CommandLineTools/usr/include]
|
||||
ignore line: [ /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/System/Library/Frameworks (framework directory)]
|
||||
ignore line: [End of search list.]
|
||||
ignore line: [Linking CXX executable cmTC_81138]
|
||||
ignore line: [/opt/homebrew/bin/cmake -E cmake_link_script CMakeFiles/cmTC_81138.dir/link.txt --verbose=1]
|
||||
ignore line: [Linking CXX executable cmTC_20b78]
|
||||
ignore line: [/opt/homebrew/bin/cmake -E cmake_link_script CMakeFiles/cmTC_20b78.dir/link.txt --verbose=1]
|
||||
ignore line: [Apple clang version 15.0.0 (clang-1500.3.9.4)]
|
||||
ignore line: [Target: arm64-apple-darwin23.6.0]
|
||||
ignore line: [Thread model: posix]
|
||||
ignore line: [InstalledDir: /Library/Developer/CommandLineTools/usr/bin]
|
||||
link line: [ "/Library/Developer/CommandLineTools/usr/bin/ld" -demangle -lto_library /Library/Developer/CommandLineTools/usr/lib/libLTO.dylib -dynamic -arch arm64 -platform_version macos 14.6.0 15.0 -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk -o cmTC_81138 -L/opt/homebrew/opt/openssl@3/lib -search_paths_first -headerpad_max_install_names -v CMakeFiles/cmTC_81138.dir/CMakeCXXCompilerABI.cpp.o -lc++ -lSystem /Library/Developer/CommandLineTools/usr/lib/clang/15.0.0/lib/darwin/libclang_rt.osx.a]
|
||||
link line: [ "/Library/Developer/CommandLineTools/usr/bin/ld" -demangle -lto_library /Library/Developer/CommandLineTools/usr/lib/libLTO.dylib -dynamic -arch arm64 -platform_version macos 14.6.0 15.0 -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk -o cmTC_20b78 -L/opt/homebrew/opt/openssl@3/lib -search_paths_first -headerpad_max_install_names -v CMakeFiles/cmTC_20b78.dir/CMakeCXXCompilerABI.cpp.o -lc++ -lSystem /Library/Developer/CommandLineTools/usr/lib/clang/15.0.0/lib/darwin/libclang_rt.osx.a]
|
||||
arg [/Library/Developer/CommandLineTools/usr/bin/ld] ==> ignore
|
||||
arg [-demangle] ==> ignore
|
||||
arg [-lto_library] ==> ignore, skip following value
|
||||
|
@ -202,12 +202,12 @@ events:
|
|||
arg [-syslibroot] ==> ignore
|
||||
arg [/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk] ==> ignore
|
||||
arg [-o] ==> ignore
|
||||
arg [cmTC_81138] ==> ignore
|
||||
arg [cmTC_20b78] ==> ignore
|
||||
arg [-L/opt/homebrew/opt/openssl@3/lib] ==> dir [/opt/homebrew/opt/openssl@3/lib]
|
||||
arg [-search_paths_first] ==> ignore
|
||||
arg [-headerpad_max_install_names] ==> ignore
|
||||
arg [-v] ==> ignore
|
||||
arg [CMakeFiles/cmTC_81138.dir/CMakeCXXCompilerABI.cpp.o] ==> ignore
|
||||
arg [CMakeFiles/cmTC_20b78.dir/CMakeCXXCompilerABI.cpp.o] ==> ignore
|
||||
arg [-lc++] ==> lib [c++]
|
||||
arg [-lSystem] ==> lib [System]
|
||||
arg [/Library/Developer/CommandLineTools/usr/lib/clang/15.0.0/lib/darwin/libclang_rt.osx.a] ==> lib [/Library/Developer/CommandLineTools/usr/lib/clang/15.0.0/lib/darwin/libclang_rt.osx.a]
|
||||
|
@ -253,8 +253,8 @@ events:
|
|||
checks:
|
||||
- "Performing Test CMAKE_HAVE_LIBC_PTHREAD"
|
||||
directories:
|
||||
source: "/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles/CMakeScratch/TryCompile-KRhC90"
|
||||
binary: "/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles/CMakeScratch/TryCompile-KRhC90"
|
||||
source: "/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles/CMakeScratch/TryCompile-oaNK9l"
|
||||
binary: "/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles/CMakeScratch/TryCompile-oaNK9l"
|
||||
cmakeVariables:
|
||||
CMAKE_CXX_FLAGS: ""
|
||||
CMAKE_CXX_FLAGS_DEBUG: "-g"
|
||||
|
@ -266,15 +266,15 @@ events:
|
|||
variable: "CMAKE_HAVE_LIBC_PTHREAD"
|
||||
cached: true
|
||||
stdout: |
|
||||
Change Dir: '/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles/CMakeScratch/TryCompile-KRhC90'
|
||||
Change Dir: '/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles/CMakeScratch/TryCompile-oaNK9l'
|
||||
|
||||
Run Build Command(s): /opt/homebrew/bin/cmake -E env VERBOSE=1 /usr/bin/make -f Makefile cmTC_dbfac/fast
|
||||
/Library/Developer/CommandLineTools/usr/bin/make -f CMakeFiles/cmTC_dbfac.dir/build.make CMakeFiles/cmTC_dbfac.dir/build
|
||||
Building CXX object CMakeFiles/cmTC_dbfac.dir/src.cxx.o
|
||||
/Library/Developer/CommandLineTools/usr/bin/c++ -DCMAKE_HAVE_LIBC_PTHREAD -std=gnu++17 -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk -mmacosx-version-min=14.6 -MD -MT CMakeFiles/cmTC_dbfac.dir/src.cxx.o -MF CMakeFiles/cmTC_dbfac.dir/src.cxx.o.d -o CMakeFiles/cmTC_dbfac.dir/src.cxx.o -c /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles/CMakeScratch/TryCompile-KRhC90/src.cxx
|
||||
Linking CXX executable cmTC_dbfac
|
||||
/opt/homebrew/bin/cmake -E cmake_link_script CMakeFiles/cmTC_dbfac.dir/link.txt --verbose=1
|
||||
/Library/Developer/CommandLineTools/usr/bin/c++ -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk -mmacosx-version-min=14.6 -Wl,-search_paths_first -Wl,-headerpad_max_install_names -L/opt/homebrew/opt/openssl@3/lib CMakeFiles/cmTC_dbfac.dir/src.cxx.o -o cmTC_dbfac
|
||||
Run Build Command(s): /opt/homebrew/bin/cmake -E env VERBOSE=1 /usr/bin/make -f Makefile cmTC_6754c/fast
|
||||
/Library/Developer/CommandLineTools/usr/bin/make -f CMakeFiles/cmTC_6754c.dir/build.make CMakeFiles/cmTC_6754c.dir/build
|
||||
Building CXX object CMakeFiles/cmTC_6754c.dir/src.cxx.o
|
||||
/Library/Developer/CommandLineTools/usr/bin/c++ -DCMAKE_HAVE_LIBC_PTHREAD -std=gnu++17 -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk -mmacosx-version-min=14.6 -MD -MT CMakeFiles/cmTC_6754c.dir/src.cxx.o -MF CMakeFiles/cmTC_6754c.dir/src.cxx.o.d -o CMakeFiles/cmTC_6754c.dir/src.cxx.o -c /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles/CMakeScratch/TryCompile-oaNK9l/src.cxx
|
||||
Linking CXX executable cmTC_6754c
|
||||
/opt/homebrew/bin/cmake -E cmake_link_script CMakeFiles/cmTC_6754c.dir/link.txt --verbose=1
|
||||
/Library/Developer/CommandLineTools/usr/bin/c++ -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk -mmacosx-version-min=14.6 -Wl,-search_paths_first -Wl,-headerpad_max_install_names -L/opt/homebrew/opt/openssl@3/lib CMakeFiles/cmTC_6754c.dir/src.cxx.o -o cmTC_6754c
|
||||
|
||||
exitCode: 0
|
||||
...
|
||||
|
|
|
@ -62,5 +62,4 @@ set(CMAKE_DEPEND_INFO_FILES
|
|||
"src/CMakeFiles/mcp.dir/DependInfo.cmake"
|
||||
"examples/CMakeFiles/client_example.dir/DependInfo.cmake"
|
||||
"examples/CMakeFiles/server_example.dir/DependInfo.cmake"
|
||||
"examples/CMakeFiles/host_example.dir/DependInfo.cmake"
|
||||
)
|
||||
|
|
|
@ -88,13 +88,11 @@ clean: examples/clean
|
|||
# Recursive "all" directory target.
|
||||
examples/all: examples/CMakeFiles/client_example.dir/all
|
||||
examples/all: examples/CMakeFiles/server_example.dir/all
|
||||
examples/all: examples/CMakeFiles/host_example.dir/all
|
||||
.PHONY : examples/all
|
||||
|
||||
# Recursive "codegen" directory target.
|
||||
examples/codegen: examples/CMakeFiles/client_example.dir/codegen
|
||||
examples/codegen: examples/CMakeFiles/server_example.dir/codegen
|
||||
examples/codegen: examples/CMakeFiles/host_example.dir/codegen
|
||||
.PHONY : examples/codegen
|
||||
|
||||
# Recursive "preinstall" directory target.
|
||||
|
@ -104,7 +102,6 @@ examples/preinstall:
|
|||
# Recursive "clean" directory target.
|
||||
examples/clean: examples/CMakeFiles/client_example.dir/clean
|
||||
examples/clean: examples/CMakeFiles/server_example.dir/clean
|
||||
examples/clean: examples/CMakeFiles/host_example.dir/clean
|
||||
.PHONY : examples/clean
|
||||
|
||||
#=============================================================================
|
||||
|
@ -133,12 +130,12 @@ src/clean: src/CMakeFiles/mcp.dir/clean
|
|||
src/CMakeFiles/mcp.dir/all:
|
||||
$(MAKE) $(MAKESILENT) -f src/CMakeFiles/mcp.dir/build.make src/CMakeFiles/mcp.dir/depend
|
||||
$(MAKE) $(MAKESILENT) -f src/CMakeFiles/mcp.dir/build.make src/CMakeFiles/mcp.dir/build
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles --progress-num=6,7,8,9,10,11,12,13 "Built target mcp"
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles --progress-num=3,4,5,6,7,8 "Built target mcp"
|
||||
.PHONY : src/CMakeFiles/mcp.dir/all
|
||||
|
||||
# Build rule for subdir invocation for target.
|
||||
src/CMakeFiles/mcp.dir/rule: cmake_check_build_system
|
||||
$(CMAKE_COMMAND) -E cmake_progress_start /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles 8
|
||||
$(CMAKE_COMMAND) -E cmake_progress_start /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles 6
|
||||
$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 src/CMakeFiles/mcp.dir/all
|
||||
$(CMAKE_COMMAND) -E cmake_progress_start /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles 0
|
||||
.PHONY : src/CMakeFiles/mcp.dir/rule
|
||||
|
@ -169,7 +166,7 @@ examples/CMakeFiles/client_example.dir/all: src/CMakeFiles/mcp.dir/all
|
|||
|
||||
# Build rule for subdir invocation for target.
|
||||
examples/CMakeFiles/client_example.dir/rule: cmake_check_build_system
|
||||
$(CMAKE_COMMAND) -E cmake_progress_start /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles 10
|
||||
$(CMAKE_COMMAND) -E cmake_progress_start /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles 8
|
||||
$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 examples/CMakeFiles/client_example.dir/all
|
||||
$(CMAKE_COMMAND) -E cmake_progress_start /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles 0
|
||||
.PHONY : examples/CMakeFiles/client_example.dir/rule
|
||||
|
@ -195,12 +192,12 @@ examples/CMakeFiles/client_example.dir/clean:
|
|||
examples/CMakeFiles/server_example.dir/all: src/CMakeFiles/mcp.dir/all
|
||||
$(MAKE) $(MAKESILENT) -f examples/CMakeFiles/server_example.dir/build.make examples/CMakeFiles/server_example.dir/depend
|
||||
$(MAKE) $(MAKESILENT) -f examples/CMakeFiles/server_example.dir/build.make examples/CMakeFiles/server_example.dir/build
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles --progress-num=14,15,16 "Built target server_example"
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles --progress-num=9,10 "Built target server_example"
|
||||
.PHONY : examples/CMakeFiles/server_example.dir/all
|
||||
|
||||
# Build rule for subdir invocation for target.
|
||||
examples/CMakeFiles/server_example.dir/rule: cmake_check_build_system
|
||||
$(CMAKE_COMMAND) -E cmake_progress_start /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles 11
|
||||
$(CMAKE_COMMAND) -E cmake_progress_start /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles 8
|
||||
$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 examples/CMakeFiles/server_example.dir/all
|
||||
$(CMAKE_COMMAND) -E cmake_progress_start /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles 0
|
||||
.PHONY : examples/CMakeFiles/server_example.dir/rule
|
||||
|
@ -219,37 +216,6 @@ examples/CMakeFiles/server_example.dir/clean:
|
|||
$(MAKE) $(MAKESILENT) -f examples/CMakeFiles/server_example.dir/build.make examples/CMakeFiles/server_example.dir/clean
|
||||
.PHONY : examples/CMakeFiles/server_example.dir/clean
|
||||
|
||||
#=============================================================================
|
||||
# Target rules for target examples/CMakeFiles/host_example.dir
|
||||
|
||||
# All Build rule for target.
|
||||
examples/CMakeFiles/host_example.dir/all: src/CMakeFiles/mcp.dir/all
|
||||
$(MAKE) $(MAKESILENT) -f examples/CMakeFiles/host_example.dir/build.make examples/CMakeFiles/host_example.dir/depend
|
||||
$(MAKE) $(MAKESILENT) -f examples/CMakeFiles/host_example.dir/build.make examples/CMakeFiles/host_example.dir/build
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles --progress-num=3,4,5 "Built target host_example"
|
||||
.PHONY : examples/CMakeFiles/host_example.dir/all
|
||||
|
||||
# Build rule for subdir invocation for target.
|
||||
examples/CMakeFiles/host_example.dir/rule: cmake_check_build_system
|
||||
$(CMAKE_COMMAND) -E cmake_progress_start /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles 11
|
||||
$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 examples/CMakeFiles/host_example.dir/all
|
||||
$(CMAKE_COMMAND) -E cmake_progress_start /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles 0
|
||||
.PHONY : examples/CMakeFiles/host_example.dir/rule
|
||||
|
||||
# Convenience name for target.
|
||||
host_example: examples/CMakeFiles/host_example.dir/rule
|
||||
.PHONY : host_example
|
||||
|
||||
# codegen rule for target.
|
||||
examples/CMakeFiles/host_example.dir/codegen:
|
||||
$(MAKE) $(MAKESILENT) -f examples/CMakeFiles/host_example.dir/build.make examples/CMakeFiles/host_example.dir/codegen
|
||||
.PHONY : examples/CMakeFiles/host_example.dir/codegen
|
||||
|
||||
# clean rule for target.
|
||||
examples/CMakeFiles/host_example.dir/clean:
|
||||
$(MAKE) $(MAKESILENT) -f examples/CMakeFiles/host_example.dir/build.make examples/CMakeFiles/host_example.dir/clean
|
||||
.PHONY : examples/CMakeFiles/host_example.dir/clean
|
||||
|
||||
#=============================================================================
|
||||
# Special targets to cleanup operation of make.
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/src/CMakeFiles/install/strip.dir
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/examples/CMakeFiles/client_example.dir
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/examples/CMakeFiles/server_example.dir
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/examples/CMakeFiles/host_example.dir
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/examples/CMakeFiles/edit_cache.dir
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/examples/CMakeFiles/rebuild_cache.dir
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/examples/CMakeFiles/list_install_components.dir
|
||||
|
|
|
@ -1 +1 @@
|
|||
16
|
||||
10
|
||||
|
|
|
@ -200,19 +200,6 @@ server_example/fast:
|
|||
$(MAKE) $(MAKESILENT) -f examples/CMakeFiles/server_example.dir/build.make examples/CMakeFiles/server_example.dir/build
|
||||
.PHONY : server_example/fast
|
||||
|
||||
#=============================================================================
|
||||
# Target rules for targets named host_example
|
||||
|
||||
# Build rule for target.
|
||||
host_example: cmake_check_build_system
|
||||
$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 host_example
|
||||
.PHONY : host_example
|
||||
|
||||
# fast build rule for target.
|
||||
host_example/fast:
|
||||
$(MAKE) $(MAKESILENT) -f examples/CMakeFiles/host_example.dir/build.make examples/CMakeFiles/host_example.dir/build
|
||||
.PHONY : host_example/fast
|
||||
|
||||
# Help Target
|
||||
help:
|
||||
@echo "The following are some of the valid targets for this Makefile:"
|
||||
|
@ -226,7 +213,6 @@ help:
|
|||
@echo "... list_install_components"
|
||||
@echo "... rebuild_cache"
|
||||
@echo "... client_example"
|
||||
@echo "... host_example"
|
||||
@echo "... mcp"
|
||||
@echo "... server_example"
|
||||
.PHONY : help
|
||||
|
|
Binary file not shown.
|
@ -1,7 +1,7 @@
|
|||
examples/CMakeFiles/client_example.dir/client_example.cpp.o: \
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/examples/client_example.cpp \
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/include/mcp_client.h \
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/include/mcp_protocol.h \
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/include/mcp_message.h \
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/string \
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__algorithm/max.h \
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__algorithm/comp.h \
|
||||
|
@ -1001,6 +1001,7 @@ examples/CMakeFiles/client_example.dir/client_example.cpp.o: \
|
|||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__chrono/year_month_day.h \
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__chrono/year_month_weekday.h \
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__chrono/literals.h \
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/include/mcp_tool.h \
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/common/httplib.h \
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/arpa/inet.h \
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/netinet/in.h \
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,24 +0,0 @@
|
|||
|
||||
# Consider dependencies only in project.
|
||||
set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF)
|
||||
|
||||
# The set of languages for which implicit dependencies are needed:
|
||||
set(CMAKE_DEPENDS_LANGUAGES
|
||||
)
|
||||
|
||||
# The set of dependency files which are needed:
|
||||
set(CMAKE_DEPENDS_DEPENDENCY_FILES
|
||||
"/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/examples/custom_agent.cpp" "examples/CMakeFiles/host_example.dir/custom_agent.cpp.o" "gcc" "examples/CMakeFiles/host_example.dir/custom_agent.cpp.o.d"
|
||||
"/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/examples/host_example.cpp" "examples/CMakeFiles/host_example.dir/host_example.cpp.o" "gcc" "examples/CMakeFiles/host_example.dir/host_example.cpp.o.d"
|
||||
)
|
||||
|
||||
# Targets to which this target links which contain Fortran sources.
|
||||
set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES
|
||||
)
|
||||
|
||||
# Targets to which this target links which contain Fortran sources.
|
||||
set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES
|
||||
)
|
||||
|
||||
# Fortran module output directory.
|
||||
set(CMAKE_Fortran_TARGET_MODULE_DIR "")
|
|
@ -1,130 +0,0 @@
|
|||
# CMAKE generated file: DO NOT EDIT!
|
||||
# Generated by "Unix Makefiles" Generator, CMake Version 3.31
|
||||
|
||||
# Delete rule output on recipe failure.
|
||||
.DELETE_ON_ERROR:
|
||||
|
||||
#=============================================================================
|
||||
# Special targets provided by cmake.
|
||||
|
||||
# Disable implicit rules so canonical targets will work.
|
||||
.SUFFIXES:
|
||||
|
||||
# Disable VCS-based implicit rules.
|
||||
% : %,v
|
||||
|
||||
# Disable VCS-based implicit rules.
|
||||
% : RCS/%
|
||||
|
||||
# Disable VCS-based implicit rules.
|
||||
% : RCS/%,v
|
||||
|
||||
# Disable VCS-based implicit rules.
|
||||
% : SCCS/s.%
|
||||
|
||||
# Disable VCS-based implicit rules.
|
||||
% : s.%
|
||||
|
||||
.SUFFIXES: .hpux_make_needs_suffix_list
|
||||
|
||||
# Command-line flag to silence nested $(MAKE).
|
||||
$(VERBOSE)MAKESILENT = -s
|
||||
|
||||
#Suppress display of executed commands.
|
||||
$(VERBOSE).SILENT:
|
||||
|
||||
# A target that is always out of date.
|
||||
cmake_force:
|
||||
.PHONY : cmake_force
|
||||
|
||||
#=============================================================================
|
||||
# Set environment variables for the build.
|
||||
|
||||
# The shell in which to execute make rules.
|
||||
SHELL = /bin/sh
|
||||
|
||||
# The CMake executable.
|
||||
CMAKE_COMMAND = /opt/homebrew/bin/cmake
|
||||
|
||||
# The command to remove a file.
|
||||
RM = /opt/homebrew/bin/cmake -E rm -f
|
||||
|
||||
# Escaping for special characters.
|
||||
EQUALS = =
|
||||
|
||||
# The top-level source directory on which CMake was run.
|
||||
CMAKE_SOURCE_DIR = /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP
|
||||
|
||||
# The top-level build directory on which CMake was run.
|
||||
CMAKE_BINARY_DIR = /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build
|
||||
|
||||
# Include any dependencies generated for this target.
|
||||
include examples/CMakeFiles/host_example.dir/depend.make
|
||||
# Include any dependencies generated by the compiler for this target.
|
||||
include examples/CMakeFiles/host_example.dir/compiler_depend.make
|
||||
|
||||
# Include the progress variables for this target.
|
||||
include examples/CMakeFiles/host_example.dir/progress.make
|
||||
|
||||
# Include the compile flags for this target's objects.
|
||||
include examples/CMakeFiles/host_example.dir/flags.make
|
||||
|
||||
examples/CMakeFiles/host_example.dir/codegen:
|
||||
.PHONY : examples/CMakeFiles/host_example.dir/codegen
|
||||
|
||||
examples/CMakeFiles/host_example.dir/host_example.cpp.o: examples/CMakeFiles/host_example.dir/flags.make
|
||||
examples/CMakeFiles/host_example.dir/host_example.cpp.o: /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/examples/host_example.cpp
|
||||
examples/CMakeFiles/host_example.dir/host_example.cpp.o: examples/CMakeFiles/host_example.dir/compiler_depend.ts
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object examples/CMakeFiles/host_example.dir/host_example.cpp.o"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/examples && /Library/Developer/CommandLineTools/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT examples/CMakeFiles/host_example.dir/host_example.cpp.o -MF CMakeFiles/host_example.dir/host_example.cpp.o.d -o CMakeFiles/host_example.dir/host_example.cpp.o -c /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/examples/host_example.cpp
|
||||
|
||||
examples/CMakeFiles/host_example.dir/host_example.cpp.i: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/host_example.dir/host_example.cpp.i"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/examples && /Library/Developer/CommandLineTools/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/examples/host_example.cpp > CMakeFiles/host_example.dir/host_example.cpp.i
|
||||
|
||||
examples/CMakeFiles/host_example.dir/host_example.cpp.s: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/host_example.dir/host_example.cpp.s"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/examples && /Library/Developer/CommandLineTools/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/examples/host_example.cpp -o CMakeFiles/host_example.dir/host_example.cpp.s
|
||||
|
||||
examples/CMakeFiles/host_example.dir/custom_agent.cpp.o: examples/CMakeFiles/host_example.dir/flags.make
|
||||
examples/CMakeFiles/host_example.dir/custom_agent.cpp.o: /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/examples/custom_agent.cpp
|
||||
examples/CMakeFiles/host_example.dir/custom_agent.cpp.o: examples/CMakeFiles/host_example.dir/compiler_depend.ts
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Building CXX object examples/CMakeFiles/host_example.dir/custom_agent.cpp.o"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/examples && /Library/Developer/CommandLineTools/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT examples/CMakeFiles/host_example.dir/custom_agent.cpp.o -MF CMakeFiles/host_example.dir/custom_agent.cpp.o.d -o CMakeFiles/host_example.dir/custom_agent.cpp.o -c /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/examples/custom_agent.cpp
|
||||
|
||||
examples/CMakeFiles/host_example.dir/custom_agent.cpp.i: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/host_example.dir/custom_agent.cpp.i"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/examples && /Library/Developer/CommandLineTools/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/examples/custom_agent.cpp > CMakeFiles/host_example.dir/custom_agent.cpp.i
|
||||
|
||||
examples/CMakeFiles/host_example.dir/custom_agent.cpp.s: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/host_example.dir/custom_agent.cpp.s"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/examples && /Library/Developer/CommandLineTools/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/examples/custom_agent.cpp -o CMakeFiles/host_example.dir/custom_agent.cpp.s
|
||||
|
||||
# Object files for target host_example
|
||||
host_example_OBJECTS = \
|
||||
"CMakeFiles/host_example.dir/host_example.cpp.o" \
|
||||
"CMakeFiles/host_example.dir/custom_agent.cpp.o"
|
||||
|
||||
# External object files for target host_example
|
||||
host_example_EXTERNAL_OBJECTS =
|
||||
|
||||
examples/host_example: examples/CMakeFiles/host_example.dir/host_example.cpp.o
|
||||
examples/host_example: examples/CMakeFiles/host_example.dir/custom_agent.cpp.o
|
||||
examples/host_example: examples/CMakeFiles/host_example.dir/build.make
|
||||
examples/host_example: src/libmcp.a
|
||||
examples/host_example: examples/CMakeFiles/host_example.dir/link.txt
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles --progress-num=$(CMAKE_PROGRESS_3) "Linking CXX executable host_example"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/examples && $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/host_example.dir/link.txt --verbose=$(VERBOSE)
|
||||
|
||||
# Rule to build all files generated by this target.
|
||||
examples/CMakeFiles/host_example.dir/build: examples/host_example
|
||||
.PHONY : examples/CMakeFiles/host_example.dir/build
|
||||
|
||||
examples/CMakeFiles/host_example.dir/clean:
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/examples && $(CMAKE_COMMAND) -P CMakeFiles/host_example.dir/cmake_clean.cmake
|
||||
.PHONY : examples/CMakeFiles/host_example.dir/clean
|
||||
|
||||
examples/CMakeFiles/host_example.dir/depend:
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/examples /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/examples /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/examples/CMakeFiles/host_example.dir/DependInfo.cmake "--color=$(COLOR)"
|
||||
.PHONY : examples/CMakeFiles/host_example.dir/depend
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
file(REMOVE_RECURSE
|
||||
"CMakeFiles/host_example.dir/custom_agent.cpp.o"
|
||||
"CMakeFiles/host_example.dir/custom_agent.cpp.o.d"
|
||||
"CMakeFiles/host_example.dir/host_example.cpp.o"
|
||||
"CMakeFiles/host_example.dir/host_example.cpp.o.d"
|
||||
"host_example"
|
||||
"host_example.pdb"
|
||||
)
|
||||
|
||||
# Per-language clean rules from dependency scanning.
|
||||
foreach(lang CXX)
|
||||
include(CMakeFiles/host_example.dir/cmake_clean_${lang}.cmake OPTIONAL)
|
||||
endforeach()
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,2 +0,0 @@
|
|||
# CMAKE generated file: DO NOT EDIT!
|
||||
# Timestamp file for compiler generated dependencies management for host_example.
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
@ -1,2 +0,0 @@
|
|||
# Empty dependencies file for host_example.
|
||||
# This may be replaced when dependencies are built.
|
|
@ -1,12 +0,0 @@
|
|||
# CMAKE generated file: DO NOT EDIT!
|
||||
# Generated by "Unix Makefiles" Generator, CMake Version 3.31
|
||||
|
||||
# compile CXX with /Library/Developer/CommandLineTools/usr/bin/c++
|
||||
CXX_DEFINES =
|
||||
|
||||
CXX_INCLUDES = -I/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/include -I/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/common -I/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/examples
|
||||
|
||||
CXX_FLAGSarm64 = -std=gnu++17 -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk -mmacosx-version-min=14.6
|
||||
|
||||
CXX_FLAGS = -std=gnu++17 -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk -mmacosx-version-min=14.6
|
||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
@ -1 +0,0 @@
|
|||
/Library/Developer/CommandLineTools/usr/bin/c++ -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk -mmacosx-version-min=14.6 -Wl,-search_paths_first -Wl,-headerpad_max_install_names -L/opt/homebrew/opt/openssl@3/lib CMakeFiles/host_example.dir/host_example.cpp.o CMakeFiles/host_example.dir/custom_agent.cpp.o -o host_example ../src/libmcp.a
|
|
@ -1,4 +0,0 @@
|
|||
CMAKE_PROGRESS_1 = 3
|
||||
CMAKE_PROGRESS_2 = 4
|
||||
CMAKE_PROGRESS_3 = 5
|
||||
|
|
@ -1 +1 @@
|
|||
16
|
||||
10
|
||||
|
|
|
@ -8,7 +8,6 @@ set(CMAKE_DEPENDS_LANGUAGES
|
|||
|
||||
# The set of dependency files which are needed:
|
||||
set(CMAKE_DEPENDS_DEPENDENCY_FILES
|
||||
"/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/examples/custom_agent.cpp" "examples/CMakeFiles/server_example.dir/custom_agent.cpp.o" "gcc" "examples/CMakeFiles/server_example.dir/custom_agent.cpp.o.d"
|
||||
"/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/examples/server_example.cpp" "examples/CMakeFiles/server_example.dir/server_example.cpp.o" "gcc" "examples/CMakeFiles/server_example.dir/server_example.cpp.o.d"
|
||||
)
|
||||
|
||||
|
|
|
@ -86,34 +86,18 @@ examples/CMakeFiles/server_example.dir/server_example.cpp.s: cmake_force
|
|||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/server_example.dir/server_example.cpp.s"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/examples && /Library/Developer/CommandLineTools/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/examples/server_example.cpp -o CMakeFiles/server_example.dir/server_example.cpp.s
|
||||
|
||||
examples/CMakeFiles/server_example.dir/custom_agent.cpp.o: examples/CMakeFiles/server_example.dir/flags.make
|
||||
examples/CMakeFiles/server_example.dir/custom_agent.cpp.o: /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/examples/custom_agent.cpp
|
||||
examples/CMakeFiles/server_example.dir/custom_agent.cpp.o: examples/CMakeFiles/server_example.dir/compiler_depend.ts
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Building CXX object examples/CMakeFiles/server_example.dir/custom_agent.cpp.o"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/examples && /Library/Developer/CommandLineTools/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT examples/CMakeFiles/server_example.dir/custom_agent.cpp.o -MF CMakeFiles/server_example.dir/custom_agent.cpp.o.d -o CMakeFiles/server_example.dir/custom_agent.cpp.o -c /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/examples/custom_agent.cpp
|
||||
|
||||
examples/CMakeFiles/server_example.dir/custom_agent.cpp.i: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/server_example.dir/custom_agent.cpp.i"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/examples && /Library/Developer/CommandLineTools/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/examples/custom_agent.cpp > CMakeFiles/server_example.dir/custom_agent.cpp.i
|
||||
|
||||
examples/CMakeFiles/server_example.dir/custom_agent.cpp.s: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/server_example.dir/custom_agent.cpp.s"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/examples && /Library/Developer/CommandLineTools/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/examples/custom_agent.cpp -o CMakeFiles/server_example.dir/custom_agent.cpp.s
|
||||
|
||||
# Object files for target server_example
|
||||
server_example_OBJECTS = \
|
||||
"CMakeFiles/server_example.dir/server_example.cpp.o" \
|
||||
"CMakeFiles/server_example.dir/custom_agent.cpp.o"
|
||||
"CMakeFiles/server_example.dir/server_example.cpp.o"
|
||||
|
||||
# External object files for target server_example
|
||||
server_example_EXTERNAL_OBJECTS =
|
||||
|
||||
examples/server_example: examples/CMakeFiles/server_example.dir/server_example.cpp.o
|
||||
examples/server_example: examples/CMakeFiles/server_example.dir/custom_agent.cpp.o
|
||||
examples/server_example: examples/CMakeFiles/server_example.dir/build.make
|
||||
examples/server_example: src/libmcp.a
|
||||
examples/server_example: examples/CMakeFiles/server_example.dir/link.txt
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles --progress-num=$(CMAKE_PROGRESS_3) "Linking CXX executable server_example"
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable server_example"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/examples && $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/server_example.dir/link.txt --verbose=$(VERBOSE)
|
||||
|
||||
# Rule to build all files generated by this target.
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
file(REMOVE_RECURSE
|
||||
"CMakeFiles/server_example.dir/custom_agent.cpp.o"
|
||||
"CMakeFiles/server_example.dir/custom_agent.cpp.o.d"
|
||||
"CMakeFiles/server_example.dir/server_example.cpp.o"
|
||||
"CMakeFiles/server_example.dir/server_example.cpp.o.d"
|
||||
"server_example"
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
@ -1 +1 @@
|
|||
/Library/Developer/CommandLineTools/usr/bin/c++ -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk -mmacosx-version-min=14.6 -Wl,-search_paths_first -Wl,-headerpad_max_install_names -L/opt/homebrew/opt/openssl@3/lib CMakeFiles/server_example.dir/server_example.cpp.o CMakeFiles/server_example.dir/custom_agent.cpp.o -o server_example ../src/libmcp.a
|
||||
/Library/Developer/CommandLineTools/usr/bin/c++ -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk -mmacosx-version-min=14.6 -Wl,-search_paths_first -Wl,-headerpad_max_install_names -L/opt/homebrew/opt/openssl@3/lib CMakeFiles/server_example.dir/server_example.cpp.o -o server_example ../src/libmcp.a
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
CMAKE_PROGRESS_1 = 14
|
||||
CMAKE_PROGRESS_2 = 15
|
||||
CMAKE_PROGRESS_3 = 16
|
||||
CMAKE_PROGRESS_1 = 9
|
||||
CMAKE_PROGRESS_2 = 10
|
||||
|
||||
|
|
Binary file not shown.
|
@ -1,7 +1,7 @@
|
|||
examples/CMakeFiles/server_example.dir/server_example.cpp.o: \
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/examples/server_example.cpp \
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/include/mcp_server.h \
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/include/mcp_protocol.h \
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/include/mcp_message.h \
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/string \
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__algorithm/max.h \
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__algorithm/comp.h \
|
||||
|
@ -1002,7 +1002,7 @@ examples/CMakeFiles/server_example.dir/server_example.cpp.o: \
|
|||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__chrono/year_month_weekday.h \
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__chrono/literals.h \
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/include/mcp_resource.h \
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/include/mcp_tools.h \
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/include/mcp_tool.h \
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/common/httplib.h \
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/arpa/inet.h \
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/netinet/in.h \
|
||||
|
@ -1095,6 +1095,4 @@ examples/CMakeFiles/server_example.dir/server_example.cpp.o: \
|
|||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__stop_token/stop_source.h \
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__thread/thread.h \
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__thread/this_thread.h \
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/unordered_set \
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/include/mcp_workflow_resource.h \
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/examples/custom_agent.h
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/unordered_set
|
||||
|
|
|
@ -189,20 +189,6 @@ server_example/fast:
|
|||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build && $(MAKE) $(MAKESILENT) -f examples/CMakeFiles/server_example.dir/build.make examples/CMakeFiles/server_example.dir/build
|
||||
.PHONY : server_example/fast
|
||||
|
||||
# Convenience name for target.
|
||||
examples/CMakeFiles/host_example.dir/rule:
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build && $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 examples/CMakeFiles/host_example.dir/rule
|
||||
.PHONY : examples/CMakeFiles/host_example.dir/rule
|
||||
|
||||
# Convenience name for target.
|
||||
host_example: examples/CMakeFiles/host_example.dir/rule
|
||||
.PHONY : host_example
|
||||
|
||||
# fast build rule for target.
|
||||
host_example/fast:
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build && $(MAKE) $(MAKESILENT) -f examples/CMakeFiles/host_example.dir/build.make examples/CMakeFiles/host_example.dir/build
|
||||
.PHONY : host_example/fast
|
||||
|
||||
client_example.o: client_example.cpp.o
|
||||
.PHONY : client_example.o
|
||||
|
||||
|
@ -227,57 +213,6 @@ client_example.cpp.s:
|
|||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build && $(MAKE) $(MAKESILENT) -f examples/CMakeFiles/client_example.dir/build.make examples/CMakeFiles/client_example.dir/client_example.cpp.s
|
||||
.PHONY : client_example.cpp.s
|
||||
|
||||
custom_agent.o: custom_agent.cpp.o
|
||||
.PHONY : custom_agent.o
|
||||
|
||||
# target to build an object file
|
||||
custom_agent.cpp.o:
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build && $(MAKE) $(MAKESILENT) -f examples/CMakeFiles/server_example.dir/build.make examples/CMakeFiles/server_example.dir/custom_agent.cpp.o
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build && $(MAKE) $(MAKESILENT) -f examples/CMakeFiles/host_example.dir/build.make examples/CMakeFiles/host_example.dir/custom_agent.cpp.o
|
||||
.PHONY : custom_agent.cpp.o
|
||||
|
||||
custom_agent.i: custom_agent.cpp.i
|
||||
.PHONY : custom_agent.i
|
||||
|
||||
# target to preprocess a source file
|
||||
custom_agent.cpp.i:
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build && $(MAKE) $(MAKESILENT) -f examples/CMakeFiles/server_example.dir/build.make examples/CMakeFiles/server_example.dir/custom_agent.cpp.i
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build && $(MAKE) $(MAKESILENT) -f examples/CMakeFiles/host_example.dir/build.make examples/CMakeFiles/host_example.dir/custom_agent.cpp.i
|
||||
.PHONY : custom_agent.cpp.i
|
||||
|
||||
custom_agent.s: custom_agent.cpp.s
|
||||
.PHONY : custom_agent.s
|
||||
|
||||
# target to generate assembly for a file
|
||||
custom_agent.cpp.s:
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build && $(MAKE) $(MAKESILENT) -f examples/CMakeFiles/server_example.dir/build.make examples/CMakeFiles/server_example.dir/custom_agent.cpp.s
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build && $(MAKE) $(MAKESILENT) -f examples/CMakeFiles/host_example.dir/build.make examples/CMakeFiles/host_example.dir/custom_agent.cpp.s
|
||||
.PHONY : custom_agent.cpp.s
|
||||
|
||||
host_example.o: host_example.cpp.o
|
||||
.PHONY : host_example.o
|
||||
|
||||
# target to build an object file
|
||||
host_example.cpp.o:
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build && $(MAKE) $(MAKESILENT) -f examples/CMakeFiles/host_example.dir/build.make examples/CMakeFiles/host_example.dir/host_example.cpp.o
|
||||
.PHONY : host_example.cpp.o
|
||||
|
||||
host_example.i: host_example.cpp.i
|
||||
.PHONY : host_example.i
|
||||
|
||||
# target to preprocess a source file
|
||||
host_example.cpp.i:
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build && $(MAKE) $(MAKESILENT) -f examples/CMakeFiles/host_example.dir/build.make examples/CMakeFiles/host_example.dir/host_example.cpp.i
|
||||
.PHONY : host_example.cpp.i
|
||||
|
||||
host_example.s: host_example.cpp.s
|
||||
.PHONY : host_example.s
|
||||
|
||||
# target to generate assembly for a file
|
||||
host_example.cpp.s:
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build && $(MAKE) $(MAKESILENT) -f examples/CMakeFiles/host_example.dir/build.make examples/CMakeFiles/host_example.dir/host_example.cpp.s
|
||||
.PHONY : host_example.cpp.s
|
||||
|
||||
server_example.o: server_example.cpp.o
|
||||
.PHONY : server_example.o
|
||||
|
||||
|
@ -315,17 +250,10 @@ help:
|
|||
@echo "... list_install_components"
|
||||
@echo "... rebuild_cache"
|
||||
@echo "... client_example"
|
||||
@echo "... host_example"
|
||||
@echo "... server_example"
|
||||
@echo "... client_example.o"
|
||||
@echo "... client_example.i"
|
||||
@echo "... client_example.s"
|
||||
@echo "... custom_agent.o"
|
||||
@echo "... custom_agent.i"
|
||||
@echo "... custom_agent.s"
|
||||
@echo "... host_example.o"
|
||||
@echo "... host_example.i"
|
||||
@echo "... host_example.s"
|
||||
@echo "... server_example.o"
|
||||
@echo "... server_example.i"
|
||||
@echo "... server_example.s"
|
||||
|
|
Binary file not shown.
|
@ -57,16 +57,6 @@ if(CMAKE_INSTALL_COMPONENT STREQUAL "Unspecified" OR NOT CMAKE_INSTALL_COMPONENT
|
|||
endif()
|
||||
endif()
|
||||
|
||||
if(CMAKE_INSTALL_COMPONENT STREQUAL "Unspecified" OR NOT CMAKE_INSTALL_COMPONENT)
|
||||
file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/bin" TYPE EXECUTABLE FILES "/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/examples/host_example")
|
||||
if(EXISTS "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/host_example" AND
|
||||
NOT IS_SYMLINK "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/host_example")
|
||||
if(CMAKE_INSTALL_DO_STRIP)
|
||||
execute_process(COMMAND "/Library/Developer/CommandLineTools/usr/bin/strip" -u -r "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/host_example")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
string(REPLACE ";" "\n" CMAKE_INSTALL_MANIFEST_CONTENT
|
||||
"${CMAKE_INSTALL_MANIFEST_FILES}")
|
||||
if(CMAKE_INSTALL_LOCAL_ONLY)
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -8,13 +8,11 @@ set(CMAKE_DEPENDS_LANGUAGES
|
|||
|
||||
# The set of dependency files which are needed:
|
||||
set(CMAKE_DEPENDS_DEPENDENCY_FILES
|
||||
"/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_agent_resource.cpp" "src/CMakeFiles/mcp.dir/mcp_agent_resource.cpp.o" "gcc" "src/CMakeFiles/mcp.dir/mcp_agent_resource.cpp.o.d"
|
||||
"/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_client.cpp" "src/CMakeFiles/mcp.dir/mcp_client.cpp.o" "gcc" "src/CMakeFiles/mcp.dir/mcp_client.cpp.o.d"
|
||||
"/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_protocol.cpp" "src/CMakeFiles/mcp.dir/mcp_protocol.cpp.o" "gcc" "src/CMakeFiles/mcp.dir/mcp_protocol.cpp.o.d"
|
||||
"/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_message.cpp" "src/CMakeFiles/mcp.dir/mcp_message.cpp.o" "gcc" "src/CMakeFiles/mcp.dir/mcp_message.cpp.o.d"
|
||||
"/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_resource.cpp" "src/CMakeFiles/mcp.dir/mcp_resource.cpp.o" "gcc" "src/CMakeFiles/mcp.dir/mcp_resource.cpp.o.d"
|
||||
"/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_server.cpp" "src/CMakeFiles/mcp.dir/mcp_server.cpp.o" "gcc" "src/CMakeFiles/mcp.dir/mcp_server.cpp.o.d"
|
||||
"/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_tools.cpp" "src/CMakeFiles/mcp.dir/mcp_tools.cpp.o" "gcc" "src/CMakeFiles/mcp.dir/mcp_tools.cpp.o.d"
|
||||
"/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_workflow_resource.cpp" "src/CMakeFiles/mcp.dir/mcp_workflow_resource.cpp.o" "gcc" "src/CMakeFiles/mcp.dir/mcp_workflow_resource.cpp.o.d"
|
||||
"/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_tool.cpp" "src/CMakeFiles/mcp.dir/mcp_tool.cpp.o" "gcc" "src/CMakeFiles/mcp.dir/mcp_tool.cpp.o.d"
|
||||
)
|
||||
|
||||
# Targets to which this target links which contain Fortran sources.
|
||||
|
|
|
@ -72,24 +72,10 @@ include src/CMakeFiles/mcp.dir/flags.make
|
|||
src/CMakeFiles/mcp.dir/codegen:
|
||||
.PHONY : src/CMakeFiles/mcp.dir/codegen
|
||||
|
||||
src/CMakeFiles/mcp.dir/mcp_agent_resource.cpp.o: src/CMakeFiles/mcp.dir/flags.make
|
||||
src/CMakeFiles/mcp.dir/mcp_agent_resource.cpp.o: /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_agent_resource.cpp
|
||||
src/CMakeFiles/mcp.dir/mcp_agent_resource.cpp.o: src/CMakeFiles/mcp.dir/compiler_depend.ts
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object src/CMakeFiles/mcp.dir/mcp_agent_resource.cpp.o"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/src && /Library/Developer/CommandLineTools/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT src/CMakeFiles/mcp.dir/mcp_agent_resource.cpp.o -MF CMakeFiles/mcp.dir/mcp_agent_resource.cpp.o.d -o CMakeFiles/mcp.dir/mcp_agent_resource.cpp.o -c /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_agent_resource.cpp
|
||||
|
||||
src/CMakeFiles/mcp.dir/mcp_agent_resource.cpp.i: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/mcp.dir/mcp_agent_resource.cpp.i"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/src && /Library/Developer/CommandLineTools/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_agent_resource.cpp > CMakeFiles/mcp.dir/mcp_agent_resource.cpp.i
|
||||
|
||||
src/CMakeFiles/mcp.dir/mcp_agent_resource.cpp.s: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/mcp.dir/mcp_agent_resource.cpp.s"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/src && /Library/Developer/CommandLineTools/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_agent_resource.cpp -o CMakeFiles/mcp.dir/mcp_agent_resource.cpp.s
|
||||
|
||||
src/CMakeFiles/mcp.dir/mcp_client.cpp.o: src/CMakeFiles/mcp.dir/flags.make
|
||||
src/CMakeFiles/mcp.dir/mcp_client.cpp.o: /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_client.cpp
|
||||
src/CMakeFiles/mcp.dir/mcp_client.cpp.o: src/CMakeFiles/mcp.dir/compiler_depend.ts
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Building CXX object src/CMakeFiles/mcp.dir/mcp_client.cpp.o"
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object src/CMakeFiles/mcp.dir/mcp_client.cpp.o"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/src && /Library/Developer/CommandLineTools/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT src/CMakeFiles/mcp.dir/mcp_client.cpp.o -MF CMakeFiles/mcp.dir/mcp_client.cpp.o.d -o CMakeFiles/mcp.dir/mcp_client.cpp.o -c /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_client.cpp
|
||||
|
||||
src/CMakeFiles/mcp.dir/mcp_client.cpp.i: cmake_force
|
||||
|
@ -100,24 +86,24 @@ src/CMakeFiles/mcp.dir/mcp_client.cpp.s: cmake_force
|
|||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/mcp.dir/mcp_client.cpp.s"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/src && /Library/Developer/CommandLineTools/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_client.cpp -o CMakeFiles/mcp.dir/mcp_client.cpp.s
|
||||
|
||||
src/CMakeFiles/mcp.dir/mcp_protocol.cpp.o: src/CMakeFiles/mcp.dir/flags.make
|
||||
src/CMakeFiles/mcp.dir/mcp_protocol.cpp.o: /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_protocol.cpp
|
||||
src/CMakeFiles/mcp.dir/mcp_protocol.cpp.o: src/CMakeFiles/mcp.dir/compiler_depend.ts
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles --progress-num=$(CMAKE_PROGRESS_3) "Building CXX object src/CMakeFiles/mcp.dir/mcp_protocol.cpp.o"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/src && /Library/Developer/CommandLineTools/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT src/CMakeFiles/mcp.dir/mcp_protocol.cpp.o -MF CMakeFiles/mcp.dir/mcp_protocol.cpp.o.d -o CMakeFiles/mcp.dir/mcp_protocol.cpp.o -c /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_protocol.cpp
|
||||
src/CMakeFiles/mcp.dir/mcp_message.cpp.o: src/CMakeFiles/mcp.dir/flags.make
|
||||
src/CMakeFiles/mcp.dir/mcp_message.cpp.o: /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_message.cpp
|
||||
src/CMakeFiles/mcp.dir/mcp_message.cpp.o: src/CMakeFiles/mcp.dir/compiler_depend.ts
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Building CXX object src/CMakeFiles/mcp.dir/mcp_message.cpp.o"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/src && /Library/Developer/CommandLineTools/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT src/CMakeFiles/mcp.dir/mcp_message.cpp.o -MF CMakeFiles/mcp.dir/mcp_message.cpp.o.d -o CMakeFiles/mcp.dir/mcp_message.cpp.o -c /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_message.cpp
|
||||
|
||||
src/CMakeFiles/mcp.dir/mcp_protocol.cpp.i: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/mcp.dir/mcp_protocol.cpp.i"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/src && /Library/Developer/CommandLineTools/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_protocol.cpp > CMakeFiles/mcp.dir/mcp_protocol.cpp.i
|
||||
src/CMakeFiles/mcp.dir/mcp_message.cpp.i: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/mcp.dir/mcp_message.cpp.i"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/src && /Library/Developer/CommandLineTools/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_message.cpp > CMakeFiles/mcp.dir/mcp_message.cpp.i
|
||||
|
||||
src/CMakeFiles/mcp.dir/mcp_protocol.cpp.s: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/mcp.dir/mcp_protocol.cpp.s"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/src && /Library/Developer/CommandLineTools/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_protocol.cpp -o CMakeFiles/mcp.dir/mcp_protocol.cpp.s
|
||||
src/CMakeFiles/mcp.dir/mcp_message.cpp.s: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/mcp.dir/mcp_message.cpp.s"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/src && /Library/Developer/CommandLineTools/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_message.cpp -o CMakeFiles/mcp.dir/mcp_message.cpp.s
|
||||
|
||||
src/CMakeFiles/mcp.dir/mcp_resource.cpp.o: src/CMakeFiles/mcp.dir/flags.make
|
||||
src/CMakeFiles/mcp.dir/mcp_resource.cpp.o: /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_resource.cpp
|
||||
src/CMakeFiles/mcp.dir/mcp_resource.cpp.o: src/CMakeFiles/mcp.dir/compiler_depend.ts
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles --progress-num=$(CMAKE_PROGRESS_4) "Building CXX object src/CMakeFiles/mcp.dir/mcp_resource.cpp.o"
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles --progress-num=$(CMAKE_PROGRESS_3) "Building CXX object src/CMakeFiles/mcp.dir/mcp_resource.cpp.o"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/src && /Library/Developer/CommandLineTools/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT src/CMakeFiles/mcp.dir/mcp_resource.cpp.o -MF CMakeFiles/mcp.dir/mcp_resource.cpp.o.d -o CMakeFiles/mcp.dir/mcp_resource.cpp.o -c /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_resource.cpp
|
||||
|
||||
src/CMakeFiles/mcp.dir/mcp_resource.cpp.i: cmake_force
|
||||
|
@ -131,7 +117,7 @@ src/CMakeFiles/mcp.dir/mcp_resource.cpp.s: cmake_force
|
|||
src/CMakeFiles/mcp.dir/mcp_server.cpp.o: src/CMakeFiles/mcp.dir/flags.make
|
||||
src/CMakeFiles/mcp.dir/mcp_server.cpp.o: /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_server.cpp
|
||||
src/CMakeFiles/mcp.dir/mcp_server.cpp.o: src/CMakeFiles/mcp.dir/compiler_depend.ts
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles --progress-num=$(CMAKE_PROGRESS_5) "Building CXX object src/CMakeFiles/mcp.dir/mcp_server.cpp.o"
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles --progress-num=$(CMAKE_PROGRESS_4) "Building CXX object src/CMakeFiles/mcp.dir/mcp_server.cpp.o"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/src && /Library/Developer/CommandLineTools/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT src/CMakeFiles/mcp.dir/mcp_server.cpp.o -MF CMakeFiles/mcp.dir/mcp_server.cpp.o.d -o CMakeFiles/mcp.dir/mcp_server.cpp.o -c /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_server.cpp
|
||||
|
||||
src/CMakeFiles/mcp.dir/mcp_server.cpp.i: cmake_force
|
||||
|
@ -142,57 +128,39 @@ src/CMakeFiles/mcp.dir/mcp_server.cpp.s: cmake_force
|
|||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/mcp.dir/mcp_server.cpp.s"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/src && /Library/Developer/CommandLineTools/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_server.cpp -o CMakeFiles/mcp.dir/mcp_server.cpp.s
|
||||
|
||||
src/CMakeFiles/mcp.dir/mcp_tools.cpp.o: src/CMakeFiles/mcp.dir/flags.make
|
||||
src/CMakeFiles/mcp.dir/mcp_tools.cpp.o: /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_tools.cpp
|
||||
src/CMakeFiles/mcp.dir/mcp_tools.cpp.o: src/CMakeFiles/mcp.dir/compiler_depend.ts
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles --progress-num=$(CMAKE_PROGRESS_6) "Building CXX object src/CMakeFiles/mcp.dir/mcp_tools.cpp.o"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/src && /Library/Developer/CommandLineTools/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT src/CMakeFiles/mcp.dir/mcp_tools.cpp.o -MF CMakeFiles/mcp.dir/mcp_tools.cpp.o.d -o CMakeFiles/mcp.dir/mcp_tools.cpp.o -c /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_tools.cpp
|
||||
src/CMakeFiles/mcp.dir/mcp_tool.cpp.o: src/CMakeFiles/mcp.dir/flags.make
|
||||
src/CMakeFiles/mcp.dir/mcp_tool.cpp.o: /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_tool.cpp
|
||||
src/CMakeFiles/mcp.dir/mcp_tool.cpp.o: src/CMakeFiles/mcp.dir/compiler_depend.ts
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles --progress-num=$(CMAKE_PROGRESS_5) "Building CXX object src/CMakeFiles/mcp.dir/mcp_tool.cpp.o"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/src && /Library/Developer/CommandLineTools/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT src/CMakeFiles/mcp.dir/mcp_tool.cpp.o -MF CMakeFiles/mcp.dir/mcp_tool.cpp.o.d -o CMakeFiles/mcp.dir/mcp_tool.cpp.o -c /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_tool.cpp
|
||||
|
||||
src/CMakeFiles/mcp.dir/mcp_tools.cpp.i: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/mcp.dir/mcp_tools.cpp.i"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/src && /Library/Developer/CommandLineTools/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_tools.cpp > CMakeFiles/mcp.dir/mcp_tools.cpp.i
|
||||
src/CMakeFiles/mcp.dir/mcp_tool.cpp.i: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/mcp.dir/mcp_tool.cpp.i"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/src && /Library/Developer/CommandLineTools/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_tool.cpp > CMakeFiles/mcp.dir/mcp_tool.cpp.i
|
||||
|
||||
src/CMakeFiles/mcp.dir/mcp_tools.cpp.s: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/mcp.dir/mcp_tools.cpp.s"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/src && /Library/Developer/CommandLineTools/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_tools.cpp -o CMakeFiles/mcp.dir/mcp_tools.cpp.s
|
||||
|
||||
src/CMakeFiles/mcp.dir/mcp_workflow_resource.cpp.o: src/CMakeFiles/mcp.dir/flags.make
|
||||
src/CMakeFiles/mcp.dir/mcp_workflow_resource.cpp.o: /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_workflow_resource.cpp
|
||||
src/CMakeFiles/mcp.dir/mcp_workflow_resource.cpp.o: src/CMakeFiles/mcp.dir/compiler_depend.ts
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles --progress-num=$(CMAKE_PROGRESS_7) "Building CXX object src/CMakeFiles/mcp.dir/mcp_workflow_resource.cpp.o"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/src && /Library/Developer/CommandLineTools/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT src/CMakeFiles/mcp.dir/mcp_workflow_resource.cpp.o -MF CMakeFiles/mcp.dir/mcp_workflow_resource.cpp.o.d -o CMakeFiles/mcp.dir/mcp_workflow_resource.cpp.o -c /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_workflow_resource.cpp
|
||||
|
||||
src/CMakeFiles/mcp.dir/mcp_workflow_resource.cpp.i: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/mcp.dir/mcp_workflow_resource.cpp.i"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/src && /Library/Developer/CommandLineTools/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_workflow_resource.cpp > CMakeFiles/mcp.dir/mcp_workflow_resource.cpp.i
|
||||
|
||||
src/CMakeFiles/mcp.dir/mcp_workflow_resource.cpp.s: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/mcp.dir/mcp_workflow_resource.cpp.s"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/src && /Library/Developer/CommandLineTools/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_workflow_resource.cpp -o CMakeFiles/mcp.dir/mcp_workflow_resource.cpp.s
|
||||
src/CMakeFiles/mcp.dir/mcp_tool.cpp.s: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/mcp.dir/mcp_tool.cpp.s"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/src && /Library/Developer/CommandLineTools/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_tool.cpp -o CMakeFiles/mcp.dir/mcp_tool.cpp.s
|
||||
|
||||
# Object files for target mcp
|
||||
mcp_OBJECTS = \
|
||||
"CMakeFiles/mcp.dir/mcp_agent_resource.cpp.o" \
|
||||
"CMakeFiles/mcp.dir/mcp_client.cpp.o" \
|
||||
"CMakeFiles/mcp.dir/mcp_protocol.cpp.o" \
|
||||
"CMakeFiles/mcp.dir/mcp_message.cpp.o" \
|
||||
"CMakeFiles/mcp.dir/mcp_resource.cpp.o" \
|
||||
"CMakeFiles/mcp.dir/mcp_server.cpp.o" \
|
||||
"CMakeFiles/mcp.dir/mcp_tools.cpp.o" \
|
||||
"CMakeFiles/mcp.dir/mcp_workflow_resource.cpp.o"
|
||||
"CMakeFiles/mcp.dir/mcp_tool.cpp.o"
|
||||
|
||||
# External object files for target mcp
|
||||
mcp_EXTERNAL_OBJECTS =
|
||||
|
||||
src/libmcp.a: src/CMakeFiles/mcp.dir/mcp_agent_resource.cpp.o
|
||||
src/libmcp.a: src/CMakeFiles/mcp.dir/mcp_client.cpp.o
|
||||
src/libmcp.a: src/CMakeFiles/mcp.dir/mcp_protocol.cpp.o
|
||||
src/libmcp.a: src/CMakeFiles/mcp.dir/mcp_message.cpp.o
|
||||
src/libmcp.a: src/CMakeFiles/mcp.dir/mcp_resource.cpp.o
|
||||
src/libmcp.a: src/CMakeFiles/mcp.dir/mcp_server.cpp.o
|
||||
src/libmcp.a: src/CMakeFiles/mcp.dir/mcp_tools.cpp.o
|
||||
src/libmcp.a: src/CMakeFiles/mcp.dir/mcp_workflow_resource.cpp.o
|
||||
src/libmcp.a: src/CMakeFiles/mcp.dir/mcp_tool.cpp.o
|
||||
src/libmcp.a: src/CMakeFiles/mcp.dir/build.make
|
||||
src/libmcp.a: src/CMakeFiles/mcp.dir/link.txt
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles --progress-num=$(CMAKE_PROGRESS_8) "Linking CXX static library libmcp.a"
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/CMakeFiles --progress-num=$(CMAKE_PROGRESS_6) "Linking CXX static library libmcp.a"
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/src && $(CMAKE_COMMAND) -P CMakeFiles/mcp.dir/cmake_clean_target.cmake
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build/src && $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/mcp.dir/link.txt --verbose=$(VERBOSE)
|
||||
|
||||
|
|
|
@ -1,18 +1,14 @@
|
|||
file(REMOVE_RECURSE
|
||||
"CMakeFiles/mcp.dir/mcp_agent_resource.cpp.o"
|
||||
"CMakeFiles/mcp.dir/mcp_agent_resource.cpp.o.d"
|
||||
"CMakeFiles/mcp.dir/mcp_client.cpp.o"
|
||||
"CMakeFiles/mcp.dir/mcp_client.cpp.o.d"
|
||||
"CMakeFiles/mcp.dir/mcp_protocol.cpp.o"
|
||||
"CMakeFiles/mcp.dir/mcp_protocol.cpp.o.d"
|
||||
"CMakeFiles/mcp.dir/mcp_message.cpp.o"
|
||||
"CMakeFiles/mcp.dir/mcp_message.cpp.o.d"
|
||||
"CMakeFiles/mcp.dir/mcp_resource.cpp.o"
|
||||
"CMakeFiles/mcp.dir/mcp_resource.cpp.o.d"
|
||||
"CMakeFiles/mcp.dir/mcp_server.cpp.o"
|
||||
"CMakeFiles/mcp.dir/mcp_server.cpp.o.d"
|
||||
"CMakeFiles/mcp.dir/mcp_tools.cpp.o"
|
||||
"CMakeFiles/mcp.dir/mcp_tools.cpp.o.d"
|
||||
"CMakeFiles/mcp.dir/mcp_workflow_resource.cpp.o"
|
||||
"CMakeFiles/mcp.dir/mcp_workflow_resource.cpp.o.d"
|
||||
"CMakeFiles/mcp.dir/mcp_tool.cpp.o"
|
||||
"CMakeFiles/mcp.dir/mcp_tool.cpp.o.d"
|
||||
"libmcp.a"
|
||||
"libmcp.pdb"
|
||||
)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,2 +1,2 @@
|
|||
/Library/Developer/CommandLineTools/usr/bin/ar qc libmcp.a CMakeFiles/mcp.dir/mcp_agent_resource.cpp.o CMakeFiles/mcp.dir/mcp_client.cpp.o CMakeFiles/mcp.dir/mcp_protocol.cpp.o CMakeFiles/mcp.dir/mcp_resource.cpp.o CMakeFiles/mcp.dir/mcp_server.cpp.o CMakeFiles/mcp.dir/mcp_tools.cpp.o CMakeFiles/mcp.dir/mcp_workflow_resource.cpp.o
|
||||
/Library/Developer/CommandLineTools/usr/bin/ar qc libmcp.a CMakeFiles/mcp.dir/mcp_client.cpp.o CMakeFiles/mcp.dir/mcp_message.cpp.o CMakeFiles/mcp.dir/mcp_resource.cpp.o CMakeFiles/mcp.dir/mcp_server.cpp.o CMakeFiles/mcp.dir/mcp_tool.cpp.o
|
||||
/Library/Developer/CommandLineTools/usr/bin/ranlib libmcp.a
|
||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
@ -1,7 +1,7 @@
|
|||
src/CMakeFiles/mcp.dir/mcp_client.cpp.o: \
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_client.cpp \
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/include/mcp_client.h \
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/include/mcp_protocol.h \
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/include/mcp_message.h \
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/string \
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__algorithm/max.h \
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__algorithm/comp.h \
|
||||
|
@ -1001,6 +1001,7 @@ src/CMakeFiles/mcp.dir/mcp_client.cpp.o: \
|
|||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__chrono/year_month_day.h \
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__chrono/year_month_weekday.h \
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__chrono/literals.h \
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/include/mcp_tool.h \
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/common/httplib.h \
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/arpa/inet.h \
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/netinet/in.h \
|
||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
@ -1,7 +1,7 @@
|
|||
src/CMakeFiles/mcp.dir/mcp_resource.cpp.o: \
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_resource.cpp \
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/include/mcp_resource.h \
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/include/mcp_protocol.h \
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/include/mcp_message.h \
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/string \
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__algorithm/max.h \
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__algorithm/comp.h \
|
||||
|
|
Binary file not shown.
|
@ -1,7 +1,7 @@
|
|||
src/CMakeFiles/mcp.dir/mcp_server.cpp.o: \
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/src/mcp_server.cpp \
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/include/mcp_server.h \
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/include/mcp_protocol.h \
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/include/mcp_message.h \
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/string \
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__algorithm/max.h \
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__algorithm/comp.h \
|
||||
|
@ -1002,7 +1002,7 @@ src/CMakeFiles/mcp.dir/mcp_server.cpp.o: \
|
|||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__chrono/year_month_weekday.h \
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/__chrono/literals.h \
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/include/mcp_resource.h \
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/include/mcp_tools.h \
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/include/mcp_tool.h \
|
||||
/Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/common/httplib.h \
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/arpa/inet.h \
|
||||
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/netinet/in.h \
|
||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
@ -1,9 +1,7 @@
|
|||
CMAKE_PROGRESS_1 = 6
|
||||
CMAKE_PROGRESS_2 = 7
|
||||
CMAKE_PROGRESS_3 = 8
|
||||
CMAKE_PROGRESS_4 = 9
|
||||
CMAKE_PROGRESS_5 = 10
|
||||
CMAKE_PROGRESS_6 = 11
|
||||
CMAKE_PROGRESS_7 = 12
|
||||
CMAKE_PROGRESS_8 = 13
|
||||
CMAKE_PROGRESS_1 = 3
|
||||
CMAKE_PROGRESS_2 = 4
|
||||
CMAKE_PROGRESS_3 = 5
|
||||
CMAKE_PROGRESS_4 = 6
|
||||
CMAKE_PROGRESS_5 = 7
|
||||
CMAKE_PROGRESS_6 = 8
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
8
|
||||
6
|
||||
|
|
|
@ -175,30 +175,6 @@ mcp/fast:
|
|||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build && $(MAKE) $(MAKESILENT) -f src/CMakeFiles/mcp.dir/build.make src/CMakeFiles/mcp.dir/build
|
||||
.PHONY : mcp/fast
|
||||
|
||||
mcp_agent_resource.o: mcp_agent_resource.cpp.o
|
||||
.PHONY : mcp_agent_resource.o
|
||||
|
||||
# target to build an object file
|
||||
mcp_agent_resource.cpp.o:
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build && $(MAKE) $(MAKESILENT) -f src/CMakeFiles/mcp.dir/build.make src/CMakeFiles/mcp.dir/mcp_agent_resource.cpp.o
|
||||
.PHONY : mcp_agent_resource.cpp.o
|
||||
|
||||
mcp_agent_resource.i: mcp_agent_resource.cpp.i
|
||||
.PHONY : mcp_agent_resource.i
|
||||
|
||||
# target to preprocess a source file
|
||||
mcp_agent_resource.cpp.i:
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build && $(MAKE) $(MAKESILENT) -f src/CMakeFiles/mcp.dir/build.make src/CMakeFiles/mcp.dir/mcp_agent_resource.cpp.i
|
||||
.PHONY : mcp_agent_resource.cpp.i
|
||||
|
||||
mcp_agent_resource.s: mcp_agent_resource.cpp.s
|
||||
.PHONY : mcp_agent_resource.s
|
||||
|
||||
# target to generate assembly for a file
|
||||
mcp_agent_resource.cpp.s:
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build && $(MAKE) $(MAKESILENT) -f src/CMakeFiles/mcp.dir/build.make src/CMakeFiles/mcp.dir/mcp_agent_resource.cpp.s
|
||||
.PHONY : mcp_agent_resource.cpp.s
|
||||
|
||||
mcp_client.o: mcp_client.cpp.o
|
||||
.PHONY : mcp_client.o
|
||||
|
||||
|
@ -223,29 +199,29 @@ mcp_client.cpp.s:
|
|||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build && $(MAKE) $(MAKESILENT) -f src/CMakeFiles/mcp.dir/build.make src/CMakeFiles/mcp.dir/mcp_client.cpp.s
|
||||
.PHONY : mcp_client.cpp.s
|
||||
|
||||
mcp_protocol.o: mcp_protocol.cpp.o
|
||||
.PHONY : mcp_protocol.o
|
||||
mcp_message.o: mcp_message.cpp.o
|
||||
.PHONY : mcp_message.o
|
||||
|
||||
# target to build an object file
|
||||
mcp_protocol.cpp.o:
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build && $(MAKE) $(MAKESILENT) -f src/CMakeFiles/mcp.dir/build.make src/CMakeFiles/mcp.dir/mcp_protocol.cpp.o
|
||||
.PHONY : mcp_protocol.cpp.o
|
||||
mcp_message.cpp.o:
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build && $(MAKE) $(MAKESILENT) -f src/CMakeFiles/mcp.dir/build.make src/CMakeFiles/mcp.dir/mcp_message.cpp.o
|
||||
.PHONY : mcp_message.cpp.o
|
||||
|
||||
mcp_protocol.i: mcp_protocol.cpp.i
|
||||
.PHONY : mcp_protocol.i
|
||||
mcp_message.i: mcp_message.cpp.i
|
||||
.PHONY : mcp_message.i
|
||||
|
||||
# target to preprocess a source file
|
||||
mcp_protocol.cpp.i:
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build && $(MAKE) $(MAKESILENT) -f src/CMakeFiles/mcp.dir/build.make src/CMakeFiles/mcp.dir/mcp_protocol.cpp.i
|
||||
.PHONY : mcp_protocol.cpp.i
|
||||
mcp_message.cpp.i:
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build && $(MAKE) $(MAKESILENT) -f src/CMakeFiles/mcp.dir/build.make src/CMakeFiles/mcp.dir/mcp_message.cpp.i
|
||||
.PHONY : mcp_message.cpp.i
|
||||
|
||||
mcp_protocol.s: mcp_protocol.cpp.s
|
||||
.PHONY : mcp_protocol.s
|
||||
mcp_message.s: mcp_message.cpp.s
|
||||
.PHONY : mcp_message.s
|
||||
|
||||
# target to generate assembly for a file
|
||||
mcp_protocol.cpp.s:
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build && $(MAKE) $(MAKESILENT) -f src/CMakeFiles/mcp.dir/build.make src/CMakeFiles/mcp.dir/mcp_protocol.cpp.s
|
||||
.PHONY : mcp_protocol.cpp.s
|
||||
mcp_message.cpp.s:
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build && $(MAKE) $(MAKESILENT) -f src/CMakeFiles/mcp.dir/build.make src/CMakeFiles/mcp.dir/mcp_message.cpp.s
|
||||
.PHONY : mcp_message.cpp.s
|
||||
|
||||
mcp_resource.o: mcp_resource.cpp.o
|
||||
.PHONY : mcp_resource.o
|
||||
|
@ -295,53 +271,29 @@ mcp_server.cpp.s:
|
|||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build && $(MAKE) $(MAKESILENT) -f src/CMakeFiles/mcp.dir/build.make src/CMakeFiles/mcp.dir/mcp_server.cpp.s
|
||||
.PHONY : mcp_server.cpp.s
|
||||
|
||||
mcp_tools.o: mcp_tools.cpp.o
|
||||
.PHONY : mcp_tools.o
|
||||
mcp_tool.o: mcp_tool.cpp.o
|
||||
.PHONY : mcp_tool.o
|
||||
|
||||
# target to build an object file
|
||||
mcp_tools.cpp.o:
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build && $(MAKE) $(MAKESILENT) -f src/CMakeFiles/mcp.dir/build.make src/CMakeFiles/mcp.dir/mcp_tools.cpp.o
|
||||
.PHONY : mcp_tools.cpp.o
|
||||
mcp_tool.cpp.o:
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build && $(MAKE) $(MAKESILENT) -f src/CMakeFiles/mcp.dir/build.make src/CMakeFiles/mcp.dir/mcp_tool.cpp.o
|
||||
.PHONY : mcp_tool.cpp.o
|
||||
|
||||
mcp_tools.i: mcp_tools.cpp.i
|
||||
.PHONY : mcp_tools.i
|
||||
mcp_tool.i: mcp_tool.cpp.i
|
||||
.PHONY : mcp_tool.i
|
||||
|
||||
# target to preprocess a source file
|
||||
mcp_tools.cpp.i:
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build && $(MAKE) $(MAKESILENT) -f src/CMakeFiles/mcp.dir/build.make src/CMakeFiles/mcp.dir/mcp_tools.cpp.i
|
||||
.PHONY : mcp_tools.cpp.i
|
||||
mcp_tool.cpp.i:
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build && $(MAKE) $(MAKESILENT) -f src/CMakeFiles/mcp.dir/build.make src/CMakeFiles/mcp.dir/mcp_tool.cpp.i
|
||||
.PHONY : mcp_tool.cpp.i
|
||||
|
||||
mcp_tools.s: mcp_tools.cpp.s
|
||||
.PHONY : mcp_tools.s
|
||||
mcp_tool.s: mcp_tool.cpp.s
|
||||
.PHONY : mcp_tool.s
|
||||
|
||||
# target to generate assembly for a file
|
||||
mcp_tools.cpp.s:
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build && $(MAKE) $(MAKESILENT) -f src/CMakeFiles/mcp.dir/build.make src/CMakeFiles/mcp.dir/mcp_tools.cpp.s
|
||||
.PHONY : mcp_tools.cpp.s
|
||||
|
||||
mcp_workflow_resource.o: mcp_workflow_resource.cpp.o
|
||||
.PHONY : mcp_workflow_resource.o
|
||||
|
||||
# target to build an object file
|
||||
mcp_workflow_resource.cpp.o:
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build && $(MAKE) $(MAKESILENT) -f src/CMakeFiles/mcp.dir/build.make src/CMakeFiles/mcp.dir/mcp_workflow_resource.cpp.o
|
||||
.PHONY : mcp_workflow_resource.cpp.o
|
||||
|
||||
mcp_workflow_resource.i: mcp_workflow_resource.cpp.i
|
||||
.PHONY : mcp_workflow_resource.i
|
||||
|
||||
# target to preprocess a source file
|
||||
mcp_workflow_resource.cpp.i:
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build && $(MAKE) $(MAKESILENT) -f src/CMakeFiles/mcp.dir/build.make src/CMakeFiles/mcp.dir/mcp_workflow_resource.cpp.i
|
||||
.PHONY : mcp_workflow_resource.cpp.i
|
||||
|
||||
mcp_workflow_resource.s: mcp_workflow_resource.cpp.s
|
||||
.PHONY : mcp_workflow_resource.s
|
||||
|
||||
# target to generate assembly for a file
|
||||
mcp_workflow_resource.cpp.s:
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build && $(MAKE) $(MAKESILENT) -f src/CMakeFiles/mcp.dir/build.make src/CMakeFiles/mcp.dir/mcp_workflow_resource.cpp.s
|
||||
.PHONY : mcp_workflow_resource.cpp.s
|
||||
mcp_tool.cpp.s:
|
||||
cd /Users/hyde/Desktop/workspace/3rdparty/OpenManus/MCP/build && $(MAKE) $(MAKESILENT) -f src/CMakeFiles/mcp.dir/build.make src/CMakeFiles/mcp.dir/mcp_tool.cpp.s
|
||||
.PHONY : mcp_tool.cpp.s
|
||||
|
||||
# Help Target
|
||||
help:
|
||||
|
@ -356,27 +308,21 @@ help:
|
|||
@echo "... list_install_components"
|
||||
@echo "... rebuild_cache"
|
||||
@echo "... mcp"
|
||||
@echo "... mcp_agent_resource.o"
|
||||
@echo "... mcp_agent_resource.i"
|
||||
@echo "... mcp_agent_resource.s"
|
||||
@echo "... mcp_client.o"
|
||||
@echo "... mcp_client.i"
|
||||
@echo "... mcp_client.s"
|
||||
@echo "... mcp_protocol.o"
|
||||
@echo "... mcp_protocol.i"
|
||||
@echo "... mcp_protocol.s"
|
||||
@echo "... mcp_message.o"
|
||||
@echo "... mcp_message.i"
|
||||
@echo "... mcp_message.s"
|
||||
@echo "... mcp_resource.o"
|
||||
@echo "... mcp_resource.i"
|
||||
@echo "... mcp_resource.s"
|
||||
@echo "... mcp_server.o"
|
||||
@echo "... mcp_server.i"
|
||||
@echo "... mcp_server.s"
|
||||
@echo "... mcp_tools.o"
|
||||
@echo "... mcp_tools.i"
|
||||
@echo "... mcp_tools.s"
|
||||
@echo "... mcp_workflow_resource.o"
|
||||
@echo "... mcp_workflow_resource.i"
|
||||
@echo "... mcp_workflow_resource.s"
|
||||
@echo "... mcp_tool.o"
|
||||
@echo "... mcp_tool.i"
|
||||
@echo "... mcp_tool.s"
|
||||
.PHONY : help
|
||||
|
||||
|
||||
|
|
Binary file not shown.
|
@ -5,17 +5,17 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
|||
set(TARGET client_example)
|
||||
add_executable(${TARGET} client_example.cpp)
|
||||
install(TARGETS ${TARGET} RUNTIME)
|
||||
target_link_libraries(${TARGET} PRIVATE mcp ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries(${TARGET} PRIVATE mcp)
|
||||
target_compile_features(${TARGET} PRIVATE cxx_std_17)
|
||||
|
||||
set(TARGET server_example)
|
||||
add_executable(${TARGET} server_example.cpp custom_agent.cpp)
|
||||
add_executable(${TARGET} server_example.cpp)
|
||||
install(TARGETS ${TARGET} RUNTIME)
|
||||
target_link_libraries(${TARGET} PRIVATE mcp ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries(${TARGET} PRIVATE mcp)
|
||||
target_compile_features(${TARGET} PRIVATE cxx_std_17)
|
||||
|
||||
set(TARGET host_example)
|
||||
add_executable(${TARGET} host_example.cpp custom_agent.cpp)
|
||||
install(TARGETS ${TARGET} RUNTIME)
|
||||
target_link_libraries(${TARGET} PRIVATE mcp ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_compile_features(${TARGET} PRIVATE cxx_std_17)
|
||||
# Create a directory for files if it doesn't exist
|
||||
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/files)
|
||||
|
||||
# Copy example files if needed
|
||||
# file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/example_files/ DESTINATION ${CMAKE_BINARY_DIR}/files)
|
|
@ -1,201 +1,92 @@
|
|||
/**
|
||||
* @file client_example.cpp
|
||||
* @brief Example MCP client implementation
|
||||
* @brief Example of an MCP client implementation
|
||||
*
|
||||
* This file demonstrates how to create an MCP client that connects to a server.
|
||||
* Follows the 2024-11-05 basic protocol specification.
|
||||
*/
|
||||
|
||||
#include "mcp_client.h"
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <iomanip>
|
||||
#include <vector>
|
||||
|
||||
// Helper function to print JSON
|
||||
void print_json(const mcp::json& json, int indent = 0) {
|
||||
std::string indent_str(indent, ' ');
|
||||
|
||||
if (json.is_object()) {
|
||||
std::cout << indent_str << "{" << std::endl;
|
||||
for (auto it = json.begin(); it != json.end(); ++it) {
|
||||
std::cout << indent_str << " \"" << it.key() << "\": ";
|
||||
if (it.value().is_object() || it.value().is_array()) {
|
||||
std::cout << std::endl;
|
||||
print_json(it.value(), indent + 2);
|
||||
} else if (it.value().is_string()) {
|
||||
std::cout << "\"" << it.value().get<std::string>() << "\"";
|
||||
} else {
|
||||
std::cout << it.value().dump();
|
||||
}
|
||||
|
||||
if (std::next(it) != json.end()) {
|
||||
std::cout << ",";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
std::cout << indent_str << "}";
|
||||
} else if (json.is_array()) {
|
||||
std::cout << indent_str << "[" << std::endl;
|
||||
for (size_t i = 0; i < json.size(); ++i) {
|
||||
print_json(json[i], indent + 2);
|
||||
if (i < json.size() - 1) {
|
||||
std::cout << ",";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
std::cout << indent_str << "]";
|
||||
} else {
|
||||
std::cout << json.dump();
|
||||
}
|
||||
|
||||
if (indent == 0) {
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
// Create a client to connect to the server
|
||||
// Create a client
|
||||
mcp::client client("localhost", 8080);
|
||||
|
||||
// Set capabilites
|
||||
mcp::json capabilities = {
|
||||
{"roots", {{"listChanged", true}}}
|
||||
};
|
||||
client.set_capabilities(capabilities);
|
||||
|
||||
// Set timeout
|
||||
client.set_timeout(10);
|
||||
|
||||
try {
|
||||
// Get server information
|
||||
std::cout << "Getting server information..." << std::endl;
|
||||
mcp::json server_info = client.get_server_info();
|
||||
std::cout << "Server name: " << server_info["name"].get<std::string>() << std::endl;
|
||||
std::cout << "Server version: " << server_info["version"].get<std::string>() << std::endl;
|
||||
std::cout << std::endl;
|
||||
// Initialize the connection
|
||||
std::cout << "Initializing connection to MCP server..." << std::endl;
|
||||
bool initialized = client.initialize("ExampleClient", mcp::MCP_VERSION);
|
||||
|
||||
if (!initialized) {
|
||||
std::cerr << "Failed to initialize connection to server" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Get server capabilities
|
||||
std::cout << "Getting server capabilities..." << std::endl;
|
||||
mcp::json capabilities = client.get_server_capabilities();
|
||||
std::cout << "Server capabilities: " << capabilities.dump(4) << std::endl;
|
||||
|
||||
// Get available tools
|
||||
std::cout << "Getting available tools..." << std::endl;
|
||||
mcp::json tools = client.get_tools();
|
||||
std::cout << "Available tools: " << tools.size() << std::endl;
|
||||
std::cout << "\nGetting available tools..." << std::endl;
|
||||
auto tools = client.get_tools();
|
||||
std::cout << "Available tools:" << std::endl;
|
||||
for (const auto& tool : tools) {
|
||||
std::cout << "- " << tool["name"].get<std::string>() << ": "
|
||||
<< tool["description"].get<std::string>() << std::endl;
|
||||
std::cout << "- " << tool.name << ": " << tool.description << std::endl;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
// Call the get_time tool
|
||||
std::cout << "Calling get_time tool..." << std::endl;
|
||||
std::cout << "\nCalling get_time tool..." << std::endl;
|
||||
mcp::json time_result = client.call_tool("get_time");
|
||||
std::cout << "Current time: " << time_result["formatted"].get<std::string>() << std::endl;
|
||||
std::cout << std::endl;
|
||||
std::cout << "Current time: " << time_result["current_time"].get<std::string>() << std::endl;
|
||||
|
||||
// Call the echo tool
|
||||
std::cout << "\nCalling echo tool..." << std::endl;
|
||||
mcp::json echo_params = {
|
||||
{"text", "Hello, MCP!"},
|
||||
{"uppercase", true}
|
||||
};
|
||||
mcp::json echo_result = client.call_tool("echo", echo_params);
|
||||
std::cout << "Echo result: " << echo_result["text"].get<std::string>() << std::endl;
|
||||
|
||||
// Call the calculator tool
|
||||
std::cout << "Calling calculator tool..." << std::endl;
|
||||
std::cout << "\nCalling calculator tool..." << std::endl;
|
||||
mcp::json calc_params = {
|
||||
{"operation", "add"},
|
||||
{"a", 42},
|
||||
{"b", 58}
|
||||
{"a", 10},
|
||||
{"b", 5}
|
||||
};
|
||||
mcp::json calc_result = client.call_tool("calculator", calc_params);
|
||||
std::cout << "42 + 58 = " << calc_result["result"].get<int>() << std::endl;
|
||||
std::cout << std::endl;
|
||||
std::cout << "10 + 5 = " << calc_result["result"].get<double>() << std::endl;
|
||||
|
||||
// Call the text_processor tool
|
||||
std::cout << "Calling text_processor tool..." << std::endl;
|
||||
mcp::json text_params = {
|
||||
{"text", "Hello, MCP Protocol!"},
|
||||
{"to_uppercase", true},
|
||||
{"word_count", true}
|
||||
// Access a resource
|
||||
std::cout << "\nAccessing API resource..." << std::endl;
|
||||
mcp::json api_params = {
|
||||
{"endpoint", "hello"},
|
||||
{"name", "MCP Client"}
|
||||
};
|
||||
mcp::json text_result = client.call_tool("text_processor", text_params);
|
||||
std::cout << "Uppercase: " << text_result["uppercase"].get<std::string>() << std::endl;
|
||||
std::cout << "Word count: " << text_result["word_count"].get<int>() << std::endl;
|
||||
std::cout << std::endl;
|
||||
mcp::json api_result = client.access_resource("/api", api_params);
|
||||
std::cout << "API response: " << api_result["message"].get<std::string>() << std::endl;
|
||||
|
||||
// List workflows
|
||||
std::cout << "Listing workflows..." << std::endl;
|
||||
mcp::response workflows_res = client.get("/workflows");
|
||||
if (workflows_res.status_code == 200) {
|
||||
mcp::json workflows = mcp::json::parse(workflows_res.body);
|
||||
std::cout << "Available workflows: " << workflows.size() << std::endl;
|
||||
for (const auto& wf : workflows) {
|
||||
std::cout << "- " << wf["name"].get<std::string>();
|
||||
if (wf.contains("description") && !wf["description"].get<std::string>().empty()) {
|
||||
std::cout << ": " << wf["description"].get<std::string>();
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
} else {
|
||||
std::cout << "Error listing workflows: " << workflows_res.body << std::endl;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
// Execute a workflow
|
||||
if (workflows_res.status_code == 200) {
|
||||
mcp::json workflows = mcp::json::parse(workflows_res.body);
|
||||
for (size_t i = 0; i < workflows.size(); ++i) {
|
||||
std::string workflow_name = workflows[i]["name"].get<std::string>();
|
||||
std::cout << "Executing workflow: " << workflow_name << std::endl;
|
||||
|
||||
mcp::json context = {
|
||||
{"custom_param", "Custom value"}
|
||||
};
|
||||
|
||||
mcp::response wf_exec_res = client.post_json(
|
||||
"/workflows/" + workflow_name + "/execute",
|
||||
{{"context", context}}
|
||||
);
|
||||
|
||||
if (wf_exec_res.status_code == 200) {
|
||||
mcp::json result = mcp::json::parse(wf_exec_res.body);
|
||||
std::cout << "Workflow execution result:" << std::endl;
|
||||
print_json(result);
|
||||
} else {
|
||||
std::cout << "Error executing workflow: " << wf_exec_res.body << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
// List agents
|
||||
std::cout << "Listing agents..." << std::endl;
|
||||
mcp::response agents_res = client.get("/agents");
|
||||
if (agents_res.status_code == 200) {
|
||||
mcp::json agents = mcp::json::parse(agents_res.body);
|
||||
std::cout << "Available agents: " << agents.size() << std::endl;
|
||||
for (const auto& agent : agents) {
|
||||
std::cout << "- " << agent["name"].get<std::string>() << std::endl;
|
||||
}
|
||||
} else {
|
||||
std::cout << "Error listing agents: " << agents_res.body << std::endl;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
// Process request with the echo agent
|
||||
std::cout << "Processing request with echo agent..." << std::endl;
|
||||
mcp::json echo_input = {
|
||||
{"text", "Hello from client!"}
|
||||
};
|
||||
|
||||
mcp::response echo_res = client.post_json("/agents/echo/process", echo_input);
|
||||
if (echo_res.status_code == 200) {
|
||||
mcp::json result = mcp::json::parse(echo_res.body);
|
||||
std::cout << "Echo agent response:" << std::endl;
|
||||
print_json(result);
|
||||
} else {
|
||||
std::cout << "Error processing with echo agent: " << echo_res.body << std::endl;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
// Process request with the workflow runner agent
|
||||
std::cout << "Processing request with workflow runner agent..." << std::endl;
|
||||
mcp::json wf_runner_input = {
|
||||
{"workflow", "time_text_calc"}
|
||||
};
|
||||
|
||||
mcp::response wf_runner_res = client.post_json("/agents/workflow_runner/process", wf_runner_input);
|
||||
if (wf_runner_res.status_code == 200) {
|
||||
mcp::json result = mcp::json::parse(wf_runner_res.body);
|
||||
std::cout << "Workflow runner agent response:" << std::endl;
|
||||
print_json(result);
|
||||
} else {
|
||||
std::cout << "Error processing with workflow runner agent: " << wf_runner_res.body << std::endl;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
} catch (const mcp::mcp_exception& e) {
|
||||
std::cerr << "MCP error: " << e.what() << " (code: " << static_cast<int>(e.code()) << ")" << std::endl;
|
||||
return 1;
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "Error: " << e.what() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cout << "\nClient example completed successfully" << std::endl;
|
||||
return 0;
|
||||
}
|
|
@ -1,223 +0,0 @@
|
|||
/**
|
||||
* @file custom_agent.cpp
|
||||
* @brief Implementation of custom MCP agents
|
||||
*/
|
||||
|
||||
#include "custom_agent.h"
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace examples {
|
||||
|
||||
// echo_agent implementation
|
||||
echo_agent::echo_agent(const std::string& name)
|
||||
: mcp::agent(name) {
|
||||
}
|
||||
|
||||
void echo_agent::initialize(const mcp::json& config) {
|
||||
// Configure the agent from the provided config
|
||||
if (config.contains("uppercase") && config["uppercase"].is_boolean()) {
|
||||
uppercase_enabled_ = config["uppercase"];
|
||||
}
|
||||
|
||||
if (config.contains("prefix") && config["prefix"].is_boolean()) {
|
||||
prefix_enabled_ = config["prefix"];
|
||||
}
|
||||
|
||||
if (config.contains("prefix_text") && config["prefix_text"].is_string()) {
|
||||
prefix_ = config["prefix_text"];
|
||||
}
|
||||
|
||||
// Initialize any resources or state
|
||||
request_count_ = 0;
|
||||
}
|
||||
|
||||
mcp::json echo_agent::process(const mcp::json& input) {
|
||||
request_count_++;
|
||||
|
||||
mcp::json output = {
|
||||
{"request_count", request_count_}
|
||||
};
|
||||
|
||||
// Process the text if provided
|
||||
if (input.contains("text") && input["text"].is_string()) {
|
||||
std::string text = input["text"];
|
||||
|
||||
// Apply uppercase if enabled
|
||||
if (uppercase_enabled_) {
|
||||
std::transform(text.begin(), text.end(), text.begin(), ::toupper);
|
||||
}
|
||||
|
||||
// Apply prefix if enabled
|
||||
if (prefix_enabled_) {
|
||||
text = prefix_ + text;
|
||||
}
|
||||
|
||||
output["processed_text"] = text;
|
||||
}
|
||||
|
||||
// Echo back all input
|
||||
output["original_input"] = input;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
void echo_agent::set_uppercase(bool enable) {
|
||||
uppercase_enabled_ = enable;
|
||||
}
|
||||
|
||||
void echo_agent::set_prefix(bool enable, const std::string& prefix) {
|
||||
prefix_enabled_ = enable;
|
||||
if (!prefix.empty()) {
|
||||
prefix_ = prefix;
|
||||
}
|
||||
}
|
||||
|
||||
// workflow_agent implementation
|
||||
workflow_agent::workflow_agent(const std::string& name)
|
||||
: mcp::agent(name) {
|
||||
}
|
||||
|
||||
void workflow_agent::initialize(const mcp::json& config) {
|
||||
// Clear existing workflows
|
||||
workflows_.clear();
|
||||
|
||||
// Load workflows from config if provided
|
||||
if (config.contains("workflows") && config["workflows"].is_array()) {
|
||||
for (const auto& wf_json : config["workflows"]) {
|
||||
if (wf_json.contains("name") && wf_json.contains("steps") &&
|
||||
wf_json["name"].is_string() && wf_json["steps"].is_array()) {
|
||||
|
||||
std::string wf_name = wf_json["name"];
|
||||
std::string wf_description = wf_json.value("description", "");
|
||||
|
||||
mcp::workflow wf(wf_name, wf_description);
|
||||
|
||||
// Add steps
|
||||
for (const auto& step_json : wf_json["steps"]) {
|
||||
if (step_json.contains("tool_name") && step_json["tool_name"].is_string()) {
|
||||
std::string tool_name = step_json["tool_name"];
|
||||
mcp::json parameters = step_json.value("parameters", mcp::json::object());
|
||||
|
||||
wf.add_tool_call(tool_name, parameters);
|
||||
}
|
||||
}
|
||||
|
||||
workflows_[wf_name] = wf;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mcp::json workflow_agent::process(const mcp::json& input) {
|
||||
// Check if workflow name is provided
|
||||
if (!input.contains("workflow") || !input["workflow"].is_string()) {
|
||||
throw std::runtime_error("Missing required parameter: workflow (string)");
|
||||
}
|
||||
|
||||
std::string workflow_name = input["workflow"];
|
||||
|
||||
// Check if the workflow exists
|
||||
auto it = workflows_.find(workflow_name);
|
||||
if (it == workflows_.end()) {
|
||||
throw std::runtime_error("Workflow not found: " + workflow_name);
|
||||
}
|
||||
|
||||
// Get the context from the input
|
||||
mcp::json context = input.value("context", mcp::json::object());
|
||||
|
||||
// Execute the workflow
|
||||
mcp::json result = execute_workflow(it->second, context);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void workflow_agent::register_workflow(const mcp::workflow& workflow) {
|
||||
workflows_[workflow.name()] = workflow;
|
||||
}
|
||||
|
||||
// chain_agent implementation
|
||||
chain_agent::chain_agent(const std::string& name)
|
||||
: mcp::agent(name) {
|
||||
}
|
||||
|
||||
void chain_agent::initialize(const mcp::json& config) {
|
||||
// Clear existing chain
|
||||
chain_.clear();
|
||||
|
||||
// Load chain from config if provided
|
||||
if (config.contains("chain") && config["chain"].is_array()) {
|
||||
for (const auto& step_json : config["chain"]) {
|
||||
if (step_json.contains("tool") && step_json["tool"].is_string()) {
|
||||
std::string tool_name = step_json["tool"];
|
||||
|
||||
std::map<std::string, std::string> output_to_input_map;
|
||||
|
||||
// Load mappings if provided
|
||||
if (step_json.contains("mappings") && step_json["mappings"].is_object()) {
|
||||
for (auto it = step_json["mappings"].begin(); it != step_json["mappings"].end(); ++it) {
|
||||
if (it.value().is_string()) {
|
||||
output_to_input_map[it.key()] = it.value();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
add_tool(tool_name, output_to_input_map);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mcp::json chain_agent::process(const mcp::json& input) {
|
||||
if (chain_.empty()) {
|
||||
throw std::runtime_error("Chain is empty");
|
||||
}
|
||||
|
||||
mcp::json current_context = input;
|
||||
|
||||
// Execute each step in the chain
|
||||
for (const auto& step : chain_) {
|
||||
// Prepare parameters for this step
|
||||
mcp::json parameters = mcp::json::object();
|
||||
|
||||
// Apply output-to-input mappings
|
||||
for (const auto& [output_path, input_path] : step.output_to_input_map) {
|
||||
// Extract value from the current context
|
||||
if (current_context.contains(output_path)) {
|
||||
// Set the value in the parameters (at the mapped path)
|
||||
parameters[input_path] = current_context[output_path];
|
||||
}
|
||||
}
|
||||
|
||||
// For fields not mapped, take them directly from the input if they exist
|
||||
for (auto it = input.begin(); it != input.end(); ++it) {
|
||||
if (!parameters.contains(it.key())) {
|
||||
parameters[it.key()] = it.value();
|
||||
}
|
||||
}
|
||||
|
||||
// Call the tool
|
||||
mcp::json result = call_tool(step.tool_name, parameters);
|
||||
|
||||
// Update the context with the result
|
||||
for (auto it = result.begin(); it != result.end(); ++it) {
|
||||
current_context[it.key()] = it.value();
|
||||
}
|
||||
}
|
||||
|
||||
return current_context;
|
||||
}
|
||||
|
||||
void chain_agent::add_tool(const std::string& tool_name,
|
||||
const std::map<std::string, std::string>& output_to_input_map) {
|
||||
chain_step step;
|
||||
step.tool_name = tool_name;
|
||||
step.output_to_input_map = output_to_input_map;
|
||||
chain_.push_back(step);
|
||||
}
|
||||
|
||||
void chain_agent::clear_chain() {
|
||||
chain_.clear();
|
||||
}
|
||||
|
||||
} // namespace examples
|
|
@ -1,145 +0,0 @@
|
|||
/**
|
||||
* @file custom_agent.h
|
||||
* @brief Example of a custom MCP agent
|
||||
*/
|
||||
|
||||
#ifndef CUSTOM_AGENT_H
|
||||
#define CUSTOM_AGENT_H
|
||||
|
||||
#include "mcp_tools.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
namespace examples {
|
||||
|
||||
/**
|
||||
* @class echo_agent
|
||||
* @brief A simple agent that echoes back input with optional processing
|
||||
*/
|
||||
class echo_agent : public mcp::agent {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param name The name of the agent
|
||||
*/
|
||||
explicit echo_agent(const std::string& name = "EchoAgent");
|
||||
|
||||
/**
|
||||
* @brief Initialize the agent
|
||||
* @param config Configuration parameters
|
||||
*/
|
||||
void initialize(const mcp::json& config) override;
|
||||
|
||||
/**
|
||||
* @brief Process a request
|
||||
* @param input The input data
|
||||
* @return The processed output
|
||||
*/
|
||||
mcp::json process(const mcp::json& input) override;
|
||||
|
||||
/**
|
||||
* @brief Enable or disable uppercase mode
|
||||
* @param enable If true, text will be converted to uppercase
|
||||
*/
|
||||
void set_uppercase(bool enable);
|
||||
|
||||
/**
|
||||
* @brief Enable or disable prefixing
|
||||
* @param enable If true, text will be prefixed
|
||||
* @param prefix The prefix to add
|
||||
*/
|
||||
void set_prefix(bool enable, const std::string& prefix = "Echo: ");
|
||||
|
||||
private:
|
||||
bool uppercase_enabled_ = false;
|
||||
bool prefix_enabled_ = false;
|
||||
std::string prefix_ = "Echo: ";
|
||||
int request_count_ = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @class workflow_agent
|
||||
* @brief An agent that executes pre-defined workflows
|
||||
*/
|
||||
class workflow_agent : public mcp::agent {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param name The name of the agent
|
||||
*/
|
||||
explicit workflow_agent(const std::string& name = "WorkflowAgent");
|
||||
|
||||
/**
|
||||
* @brief Initialize the agent
|
||||
* @param config Configuration parameters
|
||||
*/
|
||||
void initialize(const mcp::json& config) override;
|
||||
|
||||
/**
|
||||
* @brief Process a request
|
||||
* @param input The input data
|
||||
* @return The processed output
|
||||
*/
|
||||
mcp::json process(const mcp::json& input) override;
|
||||
|
||||
/**
|
||||
* @brief Register a workflow
|
||||
* @param workflow The workflow to register
|
||||
*/
|
||||
void register_workflow(const mcp::workflow& workflow);
|
||||
|
||||
private:
|
||||
std::map<std::string, mcp::workflow> workflows_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @class chain_agent
|
||||
* @brief An agent that chains multiple tools together
|
||||
*/
|
||||
class chain_agent : public mcp::agent {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param name The name of the agent
|
||||
*/
|
||||
explicit chain_agent(const std::string& name = "ChainAgent");
|
||||
|
||||
/**
|
||||
* @brief Initialize the agent
|
||||
* @param config Configuration parameters
|
||||
*/
|
||||
void initialize(const mcp::json& config) override;
|
||||
|
||||
/**
|
||||
* @brief Process a request
|
||||
* @param input The input data
|
||||
* @return The processed output
|
||||
*/
|
||||
mcp::json process(const mcp::json& input) override;
|
||||
|
||||
/**
|
||||
* @brief Add a tool to the chain
|
||||
* @param tool_name The name of the tool to add
|
||||
* @param output_to_input_map Map of output paths to input paths for next tool
|
||||
*/
|
||||
void add_tool(const std::string& tool_name,
|
||||
const std::map<std::string, std::string>& output_to_input_map = {});
|
||||
|
||||
/**
|
||||
* @brief Clear the chain
|
||||
*/
|
||||
void clear_chain();
|
||||
|
||||
private:
|
||||
struct chain_step {
|
||||
std::string tool_name;
|
||||
std::map<std::string, std::string> output_to_input_map;
|
||||
};
|
||||
|
||||
std::vector<chain_step> chain_;
|
||||
};
|
||||
|
||||
} // namespace examples
|
||||
|
||||
#endif // CUSTOM_AGENT_H
|
|
@ -1,429 +0,0 @@
|
|||
/**
|
||||
* @file host_example.cpp
|
||||
* @brief Example MCP host implementation combining server and client capabilities
|
||||
*/
|
||||
|
||||
#include "mcp_server.h"
|
||||
#include "mcp_client.h"
|
||||
#include "mcp_resource.h"
|
||||
#include "mcp_tools.h"
|
||||
#include "mcp_workflow_resource.h"
|
||||
#include "custom_agent.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <atomic>
|
||||
|
||||
/**
|
||||
* @class mcp_host
|
||||
* @brief A host that combines MCP server and client capabilities
|
||||
*
|
||||
* This class provides an example of a host application that can act both
|
||||
* as an MCP server (exposing resources and tools) and an MCP client
|
||||
* (connecting to other MCP servers).
|
||||
*/
|
||||
class mcp_host {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param name Host name
|
||||
* @param host Host address to bind to
|
||||
* @param port Port to listen on
|
||||
*/
|
||||
mcp_host(const std::string& name, const std::string& host = "localhost", int port = 8080)
|
||||
: name_(name), running_(false) {
|
||||
|
||||
// Create the server
|
||||
server_ = std::make_unique<mcp::server>(host, port);
|
||||
server_->set_name(name);
|
||||
|
||||
// Set up workflow resource
|
||||
workflow_resource_ = std::make_shared<mcp::workflow_resource>();
|
||||
server_->register_resource("/workflows", workflow_resource_);
|
||||
|
||||
// Set up agent resource
|
||||
agent_resource_ = std::make_shared<mcp::agent_resource>();
|
||||
server_->register_resource("/agents", agent_resource_);
|
||||
|
||||
// Register host management API
|
||||
host_api_ = std::make_shared<mcp::api_resource>("Host API", "Host management API");
|
||||
|
||||
// Register GET /status endpoint
|
||||
host_api_->register_handler(
|
||||
mcp::http_method::get,
|
||||
"/status",
|
||||
[this](const mcp::request& req) -> mcp::response {
|
||||
mcp::response res;
|
||||
res.set_json_body({
|
||||
{"name", name_},
|
||||
{"running", running_.load()},
|
||||
{"connections", connections_.size()},
|
||||
{"agents", agent_resource_->get_agent_names()},
|
||||
{"workflows", workflow_resource_->get_workflow_names()}
|
||||
});
|
||||
return res;
|
||||
},
|
||||
"Get host status"
|
||||
);
|
||||
|
||||
// Register POST /connect endpoint
|
||||
host_api_->register_handler(
|
||||
mcp::http_method::post,
|
||||
"/connect",
|
||||
[this](const mcp::request& req) -> mcp::response {
|
||||
mcp::response res;
|
||||
try {
|
||||
mcp::json body = req.json_body();
|
||||
|
||||
if (!body.contains("host") || !body["host"].is_string() ||
|
||||
!body.contains("port") || !body["port"].is_number_integer()) {
|
||||
res.set_error(mcp::error_code::invalid_request,
|
||||
"Missing required fields: host (string) and port (integer)");
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string host = body["host"];
|
||||
int port = body["port"];
|
||||
|
||||
std::string connection_id = connect_to_server(host, port);
|
||||
|
||||
res.set_json_body({
|
||||
{"connection_id", connection_id},
|
||||
{"status", "connected"}
|
||||
});
|
||||
|
||||
} catch (const std::exception& e) {
|
||||
res.set_error(mcp::error_code::internal_server_error, e.what());
|
||||
}
|
||||
return res;
|
||||
},
|
||||
"Connect to another MCP server"
|
||||
);
|
||||
|
||||
// Register GET /connections endpoint
|
||||
host_api_->register_handler(
|
||||
mcp::http_method::get,
|
||||
"/connections",
|
||||
[this](const mcp::request& req) -> mcp::response {
|
||||
mcp::response res;
|
||||
mcp::json connections = mcp::json::array();
|
||||
|
||||
std::lock_guard<std::mutex> lock(connections_mutex_);
|
||||
for (const auto& [id, conn] : connections_) {
|
||||
connections.push_back({
|
||||
{"id", id},
|
||||
{"host", conn.host},
|
||||
{"port", conn.port}
|
||||
});
|
||||
}
|
||||
|
||||
res.set_json_body(connections);
|
||||
return res;
|
||||
},
|
||||
"List all connections"
|
||||
);
|
||||
|
||||
// Register DELETE /connections/{id} endpoint
|
||||
host_api_->register_handler(
|
||||
mcp::http_method::delete_,
|
||||
"/connections/:id",
|
||||
[this](const mcp::request& req) -> mcp::response {
|
||||
mcp::response res;
|
||||
|
||||
// Extract connection ID from path
|
||||
std::string path = req.path;
|
||||
size_t pos = path.find_last_of('/');
|
||||
if (pos == std::string::npos) {
|
||||
res.set_error(mcp::error_code::invalid_request, "Invalid path");
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string connection_id = path.substr(pos + 1);
|
||||
|
||||
bool success = disconnect_from_server(connection_id);
|
||||
|
||||
if (success) {
|
||||
res.status_code = 204; // No content
|
||||
} else {
|
||||
res.set_error(mcp::error_code::not_found,
|
||||
"Connection not found: " + connection_id);
|
||||
}
|
||||
|
||||
return res;
|
||||
},
|
||||
"Disconnect from a server"
|
||||
);
|
||||
|
||||
server_->register_resource("/host", host_api_);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~mcp_host() {
|
||||
stop();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Start the host
|
||||
* @param blocking If true, this call blocks until the host stops
|
||||
*/
|
||||
void start(bool blocking = false) {
|
||||
if (running_) {
|
||||
return;
|
||||
}
|
||||
|
||||
running_ = true;
|
||||
|
||||
// Start the server in a separate thread
|
||||
server_thread_ = std::thread([this]() {
|
||||
try {
|
||||
server_->start(true); // Blocking call
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "Server error: " << e.what() << std::endl;
|
||||
running_ = false;
|
||||
}
|
||||
});
|
||||
|
||||
if (blocking) {
|
||||
// Wait for the server to exit
|
||||
if (server_thread_.joinable()) {
|
||||
server_thread_.join();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stop the host
|
||||
*/
|
||||
void stop() {
|
||||
if (!running_) {
|
||||
return;
|
||||
}
|
||||
|
||||
running_ = false;
|
||||
|
||||
// Disconnect from all servers
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(connections_mutex_);
|
||||
connections_.clear();
|
||||
}
|
||||
|
||||
// Stop the server
|
||||
server_->stop();
|
||||
|
||||
// Wait for the server thread to exit
|
||||
if (server_thread_.joinable()) {
|
||||
server_thread_.join();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Register a tool
|
||||
* @param tool The tool to register
|
||||
* @param handler The function to call when the tool is invoked
|
||||
*/
|
||||
void register_tool(const mcp::tool& tool, mcp::tool_handler handler) {
|
||||
server_->register_tool(tool, handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Register a resource
|
||||
* @param path The path to mount the resource at
|
||||
* @param resource The resource to register
|
||||
*/
|
||||
void register_resource(const std::string& path, std::shared_ptr<mcp::resource> resource) {
|
||||
server_->register_resource(path, resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Register an agent
|
||||
* @param agent The agent to register
|
||||
*/
|
||||
void register_agent(std::shared_ptr<mcp::agent> agent) {
|
||||
agent_resource_->register_agent(agent);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Register a workflow
|
||||
* @param workflow The workflow to register
|
||||
*/
|
||||
void register_workflow(const mcp::workflow& workflow) {
|
||||
workflow_resource_->register_workflow(workflow);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Connect to another MCP server
|
||||
* @param host The server host
|
||||
* @param port The server port
|
||||
* @return Connection ID
|
||||
*/
|
||||
std::string connect_to_server(const std::string& host, int port) {
|
||||
// Create a unique connection ID
|
||||
static int next_id = 1;
|
||||
std::string connection_id = "conn_" + std::to_string(next_id++);
|
||||
|
||||
// Create the client
|
||||
auto client = std::make_shared<mcp::client>(host, port);
|
||||
|
||||
// Test the connection by getting server info
|
||||
try {
|
||||
mcp::json server_info = client->get_server_info();
|
||||
std::cout << "Connected to server: " << server_info["name"].get<std::string>()
|
||||
<< " (version " << server_info["version"].get<std::string>() << ")"
|
||||
<< std::endl;
|
||||
} catch (const std::exception& e) {
|
||||
throw std::runtime_error(
|
||||
"Failed to connect to server at " + host + ":" + std::to_string(port) +
|
||||
" - " + e.what()
|
||||
);
|
||||
}
|
||||
|
||||
// Store the connection
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(connections_mutex_);
|
||||
connections_[connection_id] = {host, port, client};
|
||||
}
|
||||
|
||||
return connection_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disconnect from a server
|
||||
* @param connection_id The connection ID
|
||||
* @return True if the connection was found and removed
|
||||
*/
|
||||
bool disconnect_from_server(const std::string& connection_id) {
|
||||
std::lock_guard<std::mutex> lock(connections_mutex_);
|
||||
return connections_.erase(connection_id) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get a client by connection ID
|
||||
* @param connection_id The connection ID
|
||||
* @return The client, or nullptr if not found
|
||||
*/
|
||||
std::shared_ptr<mcp::client> get_client(const std::string& connection_id) {
|
||||
std::lock_guard<std::mutex> lock(connections_mutex_);
|
||||
auto it = connections_.find(connection_id);
|
||||
if (it != connections_.end()) {
|
||||
return it->second.client;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Call a tool on a connected server
|
||||
* @param connection_id The connection ID
|
||||
* @param tool_name The name of the tool to call
|
||||
* @param parameters The parameters to pass to the tool
|
||||
* @return The result of the tool call
|
||||
*/
|
||||
mcp::json call_remote_tool(const std::string& connection_id,
|
||||
const std::string& tool_name,
|
||||
const mcp::json& parameters = mcp::json::object()) {
|
||||
auto client = get_client(connection_id);
|
||||
if (!client) {
|
||||
throw std::runtime_error("Connection not found: " + connection_id);
|
||||
}
|
||||
|
||||
return client->call_tool(tool_name, parameters);
|
||||
}
|
||||
|
||||
private:
|
||||
struct connection {
|
||||
std::string host;
|
||||
int port;
|
||||
std::shared_ptr<mcp::client> client;
|
||||
};
|
||||
|
||||
std::string name_;
|
||||
std::atomic<bool> running_;
|
||||
|
||||
std::unique_ptr<mcp::server> server_;
|
||||
std::thread server_thread_;
|
||||
|
||||
std::shared_ptr<mcp::workflow_resource> workflow_resource_;
|
||||
std::shared_ptr<mcp::agent_resource> agent_resource_;
|
||||
std::shared_ptr<mcp::api_resource> host_api_;
|
||||
|
||||
std::map<std::string, connection> connections_;
|
||||
std::mutex connections_mutex_;
|
||||
};
|
||||
|
||||
// Example tool handler for system information
|
||||
mcp::json system_info_handler(const mcp::json& params) {
|
||||
mcp::json info = {
|
||||
{"hostname", "example-host"},
|
||||
{"platform", "example-platform"},
|
||||
{"uptime_seconds", 3600}
|
||||
};
|
||||
|
||||
// This would be populated with actual system info in a real implementation
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
int main() {
|
||||
// Create the host
|
||||
mcp_host host("Example MCP Host", "localhost", 8081);
|
||||
|
||||
// Register a system info tool
|
||||
mcp::tool system_info_tool = mcp::tool_builder("system_info")
|
||||
.with_description("Get system information")
|
||||
.build();
|
||||
|
||||
host.register_tool(system_info_tool, system_info_handler);
|
||||
|
||||
// Create an example file resource
|
||||
auto file_resource = std::make_shared<mcp::file_resource>("./files");
|
||||
host.register_resource("/files", file_resource);
|
||||
|
||||
// Create a chain agent for processing
|
||||
auto chain_agent_ptr = std::make_shared<examples::chain_agent>("processor");
|
||||
|
||||
// Set up a chain that calls system_info, then does text processing
|
||||
chain_agent_ptr->initialize({
|
||||
{"chain", mcp::json::array({
|
||||
{
|
||||
{"tool", "system_info"}
|
||||
},
|
||||
{
|
||||
{"tool", "text_processor"},
|
||||
{"mappings", {
|
||||
{"hostname", "text"} // Map system_info.hostname to text_processor.text
|
||||
}}
|
||||
}
|
||||
})}
|
||||
});
|
||||
|
||||
host.register_agent(chain_agent_ptr);
|
||||
|
||||
// Create a workflow that combines local and remote tools (when connected)
|
||||
mcp::workflow combined_workflow("combined", "Combined workflow using local and remote tools");
|
||||
combined_workflow.add_tool_call("system_info");
|
||||
|
||||
host.register_workflow(combined_workflow);
|
||||
|
||||
std::cout << "Starting Host on http://localhost:8081" << std::endl;
|
||||
std::cout << "The host combines server and client capabilities." << std::endl;
|
||||
std::cout << "You can interact with it via its API at /host" << std::endl;
|
||||
std::cout << "Press Ctrl+C to stop" << std::endl;
|
||||
|
||||
try {
|
||||
// Start the host in blocking mode
|
||||
host.start(true);
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "Error: " << e.what() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,419 +1,162 @@
|
|||
/**
|
||||
* @file mcp.server.cpp
|
||||
* @brief Example MCP server implementation with custom resources and tools
|
||||
* @file server_example.cpp
|
||||
* @brief Server example based on MCP protocol
|
||||
*
|
||||
* This example demonstrates how to create an MCP server, register tools and resources,
|
||||
* and handle client requests. Follows the 2024-11-05 basic protocol specification.
|
||||
*/
|
||||
|
||||
#include "mcp_server.h"
|
||||
#include "mcp_tool.h"
|
||||
#include "mcp_resource.h"
|
||||
#include "mcp_tools.h"
|
||||
#include "mcp_workflow_resource.h"
|
||||
#include "custom_agent.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <ctime>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <thread>
|
||||
#include <filesystem>
|
||||
#include <algorithm>
|
||||
|
||||
// 添加日志记录功能
|
||||
class Logger {
|
||||
public:
|
||||
enum class LogLevel {
|
||||
DEBUG,
|
||||
INFO,
|
||||
WARNING,
|
||||
ERROR
|
||||
};
|
||||
|
||||
static std::string getCurrentTimestamp() {
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto now_ms = std::chrono::time_point_cast<std::chrono::milliseconds>(now);
|
||||
auto time_t_now = std::chrono::system_clock::to_time_t(now);
|
||||
auto ms = now_ms.time_since_epoch().count() % 1000;
|
||||
|
||||
std::stringstream ss;
|
||||
ss << std::put_time(std::localtime(&time_t_now), "%Y-%m-%d %H:%M:%S");
|
||||
ss << "." << std::setfill('0') << std::setw(3) << ms;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
static std::string getLevelString(LogLevel level) {
|
||||
switch (level) {
|
||||
case LogLevel::DEBUG: return "DEBUG ";
|
||||
case LogLevel::INFO: return "INFO ";
|
||||
case LogLevel::WARNING: return "WARNING ";
|
||||
case LogLevel::ERROR: return "ERROR ";
|
||||
default: return "UNKNOWN ";
|
||||
}
|
||||
}
|
||||
|
||||
static void log(LogLevel level, const std::string& module, const std::string& message) {
|
||||
std::cout << getCurrentTimestamp() << " | "
|
||||
<< getLevelString(level) << " | "
|
||||
<< module << ": "
|
||||
<< message << std::endl;
|
||||
}
|
||||
|
||||
static void debug(const std::string& module, const std::string& message) {
|
||||
log(LogLevel::DEBUG, module, message);
|
||||
}
|
||||
|
||||
static void info(const std::string& module, const std::string& message) {
|
||||
log(LogLevel::INFO, module, message);
|
||||
}
|
||||
|
||||
static void warning(const std::string& module, const std::string& message) {
|
||||
log(LogLevel::WARNING, module, message);
|
||||
}
|
||||
|
||||
static void error(const std::string& module, const std::string& message) {
|
||||
log(LogLevel::ERROR, module, message);
|
||||
}
|
||||
};
|
||||
|
||||
// 创建一个日志记录资源包装器
|
||||
class LoggingResourceWrapper : public mcp::resource {
|
||||
public:
|
||||
LoggingResourceWrapper(std::shared_ptr<mcp::resource> wrapped_resource, const std::string& resource_path)
|
||||
: wrapped_resource_(wrapped_resource), resource_path_(resource_path) {}
|
||||
|
||||
mcp::resource_type type() const override {
|
||||
return wrapped_resource_->type();
|
||||
}
|
||||
|
||||
mcp::json metadata() const override {
|
||||
return wrapped_resource_->metadata();
|
||||
}
|
||||
|
||||
mcp::response handle_request(const mcp::request& req) override {
|
||||
// 记录请求信息
|
||||
std::stringstream ss;
|
||||
ss << "Received " << mcp::http_method_to_string(req.method) << " request to "
|
||||
<< resource_path_ << req.path;
|
||||
|
||||
// 添加查询参数
|
||||
if (!req.query_params.empty()) {
|
||||
ss << " with params: {";
|
||||
bool first = true;
|
||||
for (const auto& [key, value] : req.query_params) {
|
||||
if (!first) ss << ", ";
|
||||
ss << key << ": " << value;
|
||||
first = false;
|
||||
}
|
||||
ss << "}";
|
||||
}
|
||||
|
||||
// 添加请求体信息(如果不是GET请求)
|
||||
if (req.method != mcp::http_method::get && !req.body.empty()) {
|
||||
if (req.body.length() > 1000) {
|
||||
ss << " with body: " << req.body.substr(0, 1000) << "... (truncated)";
|
||||
} else {
|
||||
ss << " with body: " << req.body;
|
||||
}
|
||||
}
|
||||
|
||||
Logger::info("mcp.server.handle_request:", ss.str());
|
||||
|
||||
// 调用包装的资源处理请求
|
||||
mcp::response res = wrapped_resource_->handle_request(req);
|
||||
|
||||
// 记录响应信息
|
||||
std::stringstream res_ss;
|
||||
res_ss << "Response status: " << res.status_code;
|
||||
if (!res.body.empty()) {
|
||||
if (res.body.length() > 1000) {
|
||||
res_ss << ", body: " << res.body.substr(0, 1000) << "... (truncated)";
|
||||
} else {
|
||||
res_ss << ", body: " << res.body;
|
||||
}
|
||||
}
|
||||
|
||||
Logger::info("mcp.server.handle_request:", res_ss.str());
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
mcp::json schema() const override {
|
||||
return wrapped_resource_->schema();
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<mcp::resource> wrapped_resource_;
|
||||
std::string resource_path_;
|
||||
};
|
||||
|
||||
// Example tool handler for getting the current time
|
||||
// Tool handler for getting current time
|
||||
mcp::json get_time_handler(const mcp::json& params) {
|
||||
Logger::info("mcp.server.toolcall:execute", "Executing get_time tool");
|
||||
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto time_t_now = std::chrono::system_clock::to_time_t(now);
|
||||
|
||||
std::stringstream formatted_time;
|
||||
formatted_time << std::put_time(std::localtime(&time_t_now), "%Y-%m-%d %H:%M:%S");
|
||||
std::string time_str = std::ctime(&time_t_now);
|
||||
// Remove trailing newline
|
||||
if (!time_str.empty() && time_str[time_str.length() - 1] == '\n') {
|
||||
time_str.erase(time_str.length() - 1);
|
||||
}
|
||||
|
||||
mcp::json result = {
|
||||
{"timestamp", static_cast<int>(time_t_now)},
|
||||
{"formatted", formatted_time.str()}
|
||||
return {
|
||||
{"current_time", time_str},
|
||||
{"timestamp", static_cast<long long>(std::chrono::duration_cast<std::chrono::seconds>(
|
||||
now.time_since_epoch()).count())}
|
||||
};
|
||||
}
|
||||
|
||||
Logger::info("mcp.server.toolcall:result", "get_time result: " + result.dump());
|
||||
// Echo tool handler
|
||||
mcp::json echo_handler(const mcp::json& params) {
|
||||
mcp::json result = params;
|
||||
|
||||
if (params.contains("text")) {
|
||||
std::string text = params["text"];
|
||||
|
||||
if (params.contains("uppercase") && params["uppercase"].get<bool>()) {
|
||||
std::transform(text.begin(), text.end(), text.begin(), ::toupper);
|
||||
result["text"] = text;
|
||||
}
|
||||
|
||||
if (params.contains("reverse") && params["reverse"].get<bool>()) {
|
||||
std::reverse(text.begin(), text.end());
|
||||
result["text"] = text;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Example tool handler for mathematical calculations
|
||||
// Calculator tool handler
|
||||
mcp::json calculator_handler(const mcp::json& params) {
|
||||
Logger::info("mcp.server.toolcall:execute", "Executing calculator tool with params: " + params.dump());
|
||||
|
||||
if (!params.contains("operation") || !params["operation"].is_string()) {
|
||||
Logger::error("mcp.server.toolcall:execute", "Missing required parameter: operation (string)");
|
||||
throw std::runtime_error("Missing required parameter: operation (string)");
|
||||
if (!params.contains("operation")) {
|
||||
throw mcp::mcp_exception(mcp::error_code::invalid_params, "Missing 'operation' parameter");
|
||||
}
|
||||
|
||||
std::string op = params["operation"];
|
||||
mcp::json result;
|
||||
std::string operation = params["operation"];
|
||||
double result = 0.0;
|
||||
|
||||
if (op == "add") {
|
||||
if (!params.contains("a") || !params["a"].is_number() ||
|
||||
!params.contains("b") || !params["b"].is_number()) {
|
||||
Logger::error("mcp.server.toolcall:execute", "Missing required parameters: a, b (numbers)");
|
||||
throw std::runtime_error("Missing required parameters: a, b (numbers)");
|
||||
if (operation == "add") {
|
||||
if (!params.contains("a") || !params.contains("b")) {
|
||||
throw mcp::mcp_exception(mcp::error_code::invalid_params, "Missing 'a' or 'b' parameter");
|
||||
}
|
||||
|
||||
double a = params["a"];
|
||||
double b = params["b"];
|
||||
Logger::info("mcp.server.toolcall:execute", "Calculating " + std::to_string(a) + " + " + std::to_string(b));
|
||||
result = {{"result", a + b}};
|
||||
}
|
||||
else if (op == "subtract") {
|
||||
if (!params.contains("a") || !params["a"].is_number() ||
|
||||
!params.contains("b") || !params["b"].is_number()) {
|
||||
throw std::runtime_error("Missing required parameters: a, b (numbers)");
|
||||
result = params["a"].get<double>() + params["b"].get<double>();
|
||||
} else if (operation == "subtract") {
|
||||
if (!params.contains("a") || !params.contains("b")) {
|
||||
throw mcp::mcp_exception(mcp::error_code::invalid_params, "Missing 'a' or 'b' parameter");
|
||||
}
|
||||
|
||||
double a = params["a"];
|
||||
double b = params["b"];
|
||||
Logger::info("mcp.server.toolcall:execute", "Calculating " + std::to_string(a) + " - " + std::to_string(b));
|
||||
result = {{"result", a - b}};
|
||||
}
|
||||
else if (op == "multiply") {
|
||||
if (!params.contains("a") || !params["a"].is_number() ||
|
||||
!params.contains("b") || !params["b"].is_number()) {
|
||||
throw std::runtime_error("Missing required parameters: a, b (numbers)");
|
||||
result = params["a"].get<double>() - params["b"].get<double>();
|
||||
} else if (operation == "multiply") {
|
||||
if (!params.contains("a") || !params.contains("b")) {
|
||||
throw mcp::mcp_exception(mcp::error_code::invalid_params, "Missing 'a' or 'b' parameter");
|
||||
}
|
||||
|
||||
double a = params["a"];
|
||||
double b = params["b"];
|
||||
Logger::info("mcp.server.toolcall:execute", "Calculating " + std::to_string(a) + " * " + std::to_string(b));
|
||||
result = {{"result", a * b}};
|
||||
}
|
||||
else if (op == "divide") {
|
||||
if (!params.contains("a") || !params["a"].is_number() ||
|
||||
!params.contains("b") || !params["b"].is_number()) {
|
||||
throw std::runtime_error("Missing required parameters: a, b (numbers)");
|
||||
result = params["a"].get<double>() * params["b"].get<double>();
|
||||
} else if (operation == "divide") {
|
||||
if (!params.contains("a") || !params.contains("b")) {
|
||||
throw mcp::mcp_exception(mcp::error_code::invalid_params, "Missing 'a' or 'b' parameter");
|
||||
}
|
||||
|
||||
double a = params["a"];
|
||||
double b = params["b"];
|
||||
|
||||
if (b == 0) {
|
||||
Logger::error("mcp.server.toolcall:execute", "Division by zero");
|
||||
throw std::runtime_error("Division by zero");
|
||||
if (params["b"].get<double>() == 0.0) {
|
||||
throw mcp::mcp_exception(mcp::error_code::invalid_params, "Division by zero not allowed");
|
||||
}
|
||||
|
||||
Logger::info("mcp.server.toolcall:execute", "Calculating " + std::to_string(a) + " / " + std::to_string(b));
|
||||
result = {{"result", a / b}};
|
||||
}
|
||||
else {
|
||||
Logger::error("mcp.server.toolcall:execute", "Unknown operation: " + op);
|
||||
throw std::runtime_error("Unknown operation: " + op);
|
||||
result = params["a"].get<double>() / params["b"].get<double>();
|
||||
} else {
|
||||
throw mcp::mcp_exception(mcp::error_code::invalid_params, "Unknown operation: " + operation);
|
||||
}
|
||||
|
||||
Logger::info("mcp.server.toolcall:result", "calculator result: " + result.dump());
|
||||
|
||||
return result;
|
||||
return {{"result", result}};
|
||||
}
|
||||
|
||||
// Example tool handler for text processing
|
||||
mcp::json text_processor_handler(const mcp::json& params) {
|
||||
Logger::info("mcp.server.toolcall:execute", "Executing text_processor tool with params: " + params.dump());
|
||||
|
||||
if (!params.contains("text") || !params["text"].is_string()) {
|
||||
Logger::error("mcp.server.toolcall:execute", "Missing required parameter: text (string)");
|
||||
throw std::runtime_error("Missing required parameter: text (string)");
|
||||
}
|
||||
|
||||
std::string text = params["text"];
|
||||
mcp::json result = {
|
||||
{"original_length", text.length()},
|
||||
{"original_text", text}
|
||||
};
|
||||
|
||||
// Process text based on parameters
|
||||
if (params.contains("to_uppercase") && params["to_uppercase"].is_boolean() && params["to_uppercase"]) {
|
||||
std::string uppercase_text = text;
|
||||
std::transform(uppercase_text.begin(), uppercase_text.end(), uppercase_text.begin(), ::toupper);
|
||||
result["uppercase"] = uppercase_text;
|
||||
Logger::info("mcp.server.toolcall:execute", "Converted text to uppercase");
|
||||
}
|
||||
|
||||
if (params.contains("to_lowercase") && params["to_lowercase"].is_boolean() && params["to_lowercase"]) {
|
||||
std::string lowercase_text = text;
|
||||
std::transform(lowercase_text.begin(), lowercase_text.end(), lowercase_text.begin(), ::tolower);
|
||||
result["lowercase"] = lowercase_text;
|
||||
Logger::info("mcp.server.toolcall:execute", "Converted text to lowercase");
|
||||
}
|
||||
|
||||
if (params.contains("reverse") && params["reverse"].is_boolean() && params["reverse"]) {
|
||||
std::string reversed_text = text;
|
||||
std::reverse(reversed_text.begin(), reversed_text.end());
|
||||
result["reversed"] = reversed_text;
|
||||
Logger::info("mcp.server.toolcall:execute", "Reversed text");
|
||||
}
|
||||
|
||||
if (params.contains("word_count") && params["word_count"].is_boolean() && params["word_count"]) {
|
||||
// Simple word count by counting spaces
|
||||
int count = 1;
|
||||
for (char c : text) {
|
||||
if (c == ' ') {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
result["word_count"] = count;
|
||||
Logger::info("mcp.server.toolcall:execute", "Counted words: " + std::to_string(count));
|
||||
}
|
||||
|
||||
Logger::info("mcp.server.toolcall:result", "text_processor result: " + result.dump());
|
||||
|
||||
return result;
|
||||
// Custom API endpoint handler
|
||||
mcp::json hello_handler(const mcp::json& params) {
|
||||
std::string name = params.contains("name") ? params["name"].get<std::string>() : "World";
|
||||
return {{"message", "Hello, " + name + "!"}};
|
||||
}
|
||||
|
||||
int main() {
|
||||
// 创建和配置服务器
|
||||
// Ensure file directory exists
|
||||
std::filesystem::create_directories("./files");
|
||||
|
||||
// Create and configure server
|
||||
mcp::server server("localhost", 8080);
|
||||
server.set_name("MCP Example Server");
|
||||
server.set_cors(true); // Enable CORS for browser clients
|
||||
server.set_server_info("ExampleServer", "2024-11-05");
|
||||
|
||||
Logger::info("mcp.server", "Starting MCP Example Server");
|
||||
// Set server capabilities
|
||||
mcp::json capabilities = {
|
||||
{"tools", {{"listChanged", true}}},
|
||||
{"resources", {{"listChanged", true}}}
|
||||
};
|
||||
server.set_capabilities(capabilities);
|
||||
|
||||
// Create and register tools
|
||||
// Register method handlers
|
||||
server.register_method("ping", [](const mcp::json& params) {
|
||||
return mcp::json{{"pong", true}};
|
||||
});
|
||||
|
||||
// Time tool
|
||||
// Register tools
|
||||
mcp::tool time_tool = mcp::tool_builder("get_time")
|
||||
.with_description("Get the current time")
|
||||
.with_description("Get current time")
|
||||
.build();
|
||||
|
||||
server.register_tool(time_tool, get_time_handler);
|
||||
Logger::info("mcp.server", "Registered get_time tool");
|
||||
mcp::tool echo_tool = mcp::tool_builder("echo")
|
||||
.with_description("Echo input with optional transformations")
|
||||
.with_string_param("text", "Text to echo")
|
||||
.with_boolean_param("uppercase", "Convert to uppercase", false)
|
||||
.with_boolean_param("reverse", "Reverse the text", false)
|
||||
.build();
|
||||
|
||||
// Calculator tool
|
||||
mcp::tool calc_tool = mcp::tool_builder("calculator")
|
||||
.with_description("Perform mathematical calculations")
|
||||
.with_string_param("operation", "Operation to perform: add, subtract, multiply, divide")
|
||||
.with_description("Perform basic calculations")
|
||||
.with_string_param("operation", "Operation to perform (add, subtract, multiply, divide)")
|
||||
.with_number_param("a", "First operand")
|
||||
.with_number_param("b", "Second operand")
|
||||
.build();
|
||||
|
||||
server.register_tool(time_tool, get_time_handler);
|
||||
server.register_tool(echo_tool, echo_handler);
|
||||
server.register_tool(calc_tool, calculator_handler);
|
||||
Logger::info("mcp.server", "Registered calculator tool");
|
||||
|
||||
// Text processor tool
|
||||
mcp::tool text_tool = mcp::tool_builder("text_processor")
|
||||
.with_description("Process and analyze text")
|
||||
.with_string_param("text", "Text to process")
|
||||
.with_boolean_param("to_uppercase", "Convert to uppercase", false)
|
||||
.with_boolean_param("to_lowercase", "Convert to lowercase", false)
|
||||
.with_boolean_param("reverse", "Reverse the text", false)
|
||||
.with_boolean_param("word_count", "Count words", false)
|
||||
.build();
|
||||
|
||||
server.register_tool(text_tool, text_processor_handler);
|
||||
Logger::info("mcp.server", "Registered text_processor tool");
|
||||
|
||||
// Create and register file resource with logging wrapper
|
||||
// Register resources
|
||||
auto file_resource = std::make_shared<mcp::file_resource>("./files");
|
||||
auto logging_file_resource = std::make_shared<LoggingResourceWrapper>(file_resource, "/files");
|
||||
server.register_resource("/files", logging_file_resource);
|
||||
Logger::info("mcp.server", "Registered file resource at /files");
|
||||
server.register_resource("/files", file_resource);
|
||||
|
||||
// Create and register workflow resource with logging wrapper
|
||||
auto workflow_resource = std::make_shared<mcp::workflow_resource>();
|
||||
auto logging_workflow_resource = std::make_shared<LoggingResourceWrapper>(workflow_resource, "/workflows");
|
||||
server.register_resource("/workflows", logging_workflow_resource);
|
||||
Logger::info("mcp.server", "Registered workflow resource at /workflows");
|
||||
auto api_resource = std::make_shared<mcp::api_resource>("API", "Custom API endpoints");
|
||||
api_resource->register_handler("hello", hello_handler, "Say hello");
|
||||
|
||||
// Create and register agent resource with logging wrapper
|
||||
auto agent_resource = std::make_shared<mcp::agent_resource>();
|
||||
auto logging_agent_resource = std::make_shared<LoggingResourceWrapper>(agent_resource, "/agents");
|
||||
server.register_resource("/agents", logging_agent_resource);
|
||||
Logger::info("mcp.server", "Registered agent resource at /agents");
|
||||
server.register_resource("/api", api_resource);
|
||||
|
||||
// Create and register a custom echo agent
|
||||
auto echo_agent_ptr = std::make_shared<examples::echo_agent>("echo");
|
||||
echo_agent_ptr->initialize({
|
||||
{"uppercase", false},
|
||||
{"prefix", true},
|
||||
{"prefix_text", "Server Echo: "}
|
||||
});
|
||||
|
||||
agent_resource->register_agent(echo_agent_ptr);
|
||||
Logger::info("mcp.server", "Registered echo agent");
|
||||
|
||||
// Create a workflow and register it
|
||||
mcp::workflow time_text_workflow("time_with_text", "Get time and process text");
|
||||
mcp::tool_registry::instance().register_tool(time_tool, get_time_handler);
|
||||
mcp::tool_registry::instance().register_tool(text_tool, text_processor_handler);
|
||||
time_text_workflow.add_tool_call("get_time");
|
||||
time_text_workflow.add_tool_call("text_processor", {
|
||||
{"text", "Current time is important!"},
|
||||
{"to_uppercase", true},
|
||||
{"word_count", true}
|
||||
});
|
||||
|
||||
workflow_resource->register_workflow(time_text_workflow);
|
||||
Logger::info("mcp.server", "Registered time_with_text workflow");
|
||||
|
||||
// Create a workflow agent
|
||||
auto workflow_agent_ptr = std::make_shared<examples::workflow_agent>("workflow_runner");
|
||||
mcp::tool_registry::instance().register_tool(calc_tool, calculator_handler);
|
||||
workflow_agent_ptr->initialize({
|
||||
{"workflows", mcp::json::array({
|
||||
{
|
||||
{"name", "time_text_calc"},
|
||||
{"description", "Get time, process text and calculate"},
|
||||
{"steps", mcp::json::array({
|
||||
{{"tool_name", "get_time"}},
|
||||
{{"tool_name", "text_processor"}, {"parameters", {
|
||||
{"text", "Let's do some math!"},
|
||||
{"to_uppercase", true}
|
||||
}}},
|
||||
{{"tool_name", "calculator"}, {"parameters", {
|
||||
{"operation", "add"},
|
||||
{"a", 10},
|
||||
{"b", 20}
|
||||
}}}
|
||||
})}
|
||||
}
|
||||
})}
|
||||
});
|
||||
|
||||
agent_resource->register_agent(workflow_agent_ptr);
|
||||
Logger::info("mcp.server", "Registered workflow_runner agent");
|
||||
|
||||
// Start the server (blocking)
|
||||
std::cout << "Starting server at http://localhost:8080" << std::endl;
|
||||
std::cout << "Press Ctrl+C to stop" << std::endl;
|
||||
|
||||
try {
|
||||
Logger::info("mcp.server", "Server starting...");
|
||||
server.start(true);
|
||||
} catch (const std::exception& e) {
|
||||
Logger::error("mcp.server", std::string("Error: ") + e.what());
|
||||
return 1;
|
||||
}
|
||||
// Start server
|
||||
std::cout << "Starting MCP server at localhost:8080..." << std::endl;
|
||||
std::cout << "Press Ctrl+C to stop the server" << std::endl;
|
||||
server.start(true); // Blocking mode
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,14 +1,16 @@
|
|||
/**
|
||||
* @file mcp_client.h
|
||||
* @brief MCP Client implementation using cpp-httplib
|
||||
* @brief MCP Client implementation
|
||||
*
|
||||
* This file implements the client-side functionality for the Model Context Protocol.
|
||||
* Follows the 2024-11-05 basic protocol specification.
|
||||
*/
|
||||
|
||||
#ifndef MCP_CLIENT_H
|
||||
#define MCP_CLIENT_H
|
||||
|
||||
#include "mcp_protocol.h"
|
||||
#include "mcp_message.h"
|
||||
#include "mcp_tool.h"
|
||||
|
||||
// Include the HTTP library
|
||||
#include "httplib.h"
|
||||
|
@ -27,7 +29,7 @@ namespace mcp {
|
|||
* @brief Client for connecting to MCP servers
|
||||
*
|
||||
* The client class provides functionality to connect to MCP servers,
|
||||
* discover available resources and tools, and make requests to them.
|
||||
* initialize the connection, and send/receive JSON-RPC messages.
|
||||
*/
|
||||
class client {
|
||||
public:
|
||||
|
@ -36,7 +38,7 @@ public:
|
|||
* @param host The server host (e.g., "localhost", "example.com")
|
||||
* @param port The server port
|
||||
*/
|
||||
client(const std::string& host, int port = 8080);
|
||||
client(const std::string& host, int port = 8080, const json& capabilities = json::object());
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
|
@ -44,11 +46,18 @@ public:
|
|||
~client();
|
||||
|
||||
/**
|
||||
* @brief Set authentication credentials
|
||||
* @param username The username
|
||||
* @param password The password
|
||||
* @brief Initialize the connection with the server
|
||||
* @param client_name The name of the client
|
||||
* @param client_version The version of the client
|
||||
* @return True if initialization was successful
|
||||
*/
|
||||
void set_auth(const std::string& username, const std::string& password);
|
||||
bool initialize(const std::string& client_name, const std::string& client_version);
|
||||
|
||||
/**
|
||||
* @brief Set authentication token
|
||||
* @param token The authentication token
|
||||
*/
|
||||
void set_auth_token(const std::string& token);
|
||||
|
||||
/**
|
||||
* @brief Set a request header that will be sent with all requests
|
||||
|
@ -64,102 +73,84 @@ public:
|
|||
void set_timeout(int timeout_seconds);
|
||||
|
||||
/**
|
||||
* @brief Get server information
|
||||
* @return Server information as a JSON object
|
||||
* @throws mcp_exception on error
|
||||
* @brief Set client capabilities
|
||||
* @param capabilities The capabilities of the client
|
||||
*/
|
||||
json get_server_info();
|
||||
void set_capabilities(const json& capabilities);
|
||||
|
||||
/**
|
||||
* @brief Get available tools
|
||||
* @return List of available tools as a JSON array
|
||||
* @brief Send a request and wait for a response
|
||||
* @param method The method to call
|
||||
* @param params The parameters to pass
|
||||
* @return The response
|
||||
* @throws mcp_exception on error
|
||||
*/
|
||||
json get_tools();
|
||||
response send_request(const std::string& method, const json& params = json::object());
|
||||
|
||||
/**
|
||||
* @brief Send a notification (no response expected)
|
||||
* @param method The method to call
|
||||
* @param params The parameters to pass
|
||||
* @throws mcp_exception on error
|
||||
*/
|
||||
void send_notification(const std::string& method, const json& params = json::object());
|
||||
|
||||
/**
|
||||
* @brief Get server capabilities
|
||||
* @return The server capabilities
|
||||
* @throws mcp_exception on error
|
||||
*/
|
||||
json get_server_capabilities();
|
||||
|
||||
/**
|
||||
* @brief Call a tool
|
||||
* @param tool_name The name of the tool to call
|
||||
* @param parameters The parameters to pass to the tool
|
||||
* @return The result of the tool call as a JSON object
|
||||
* @return The result of the tool call
|
||||
* @throws mcp_exception on error
|
||||
*/
|
||||
json call_tool(const std::string& tool_name, const json& parameters = json::object());
|
||||
|
||||
/**
|
||||
* @brief Make a GET request
|
||||
* @param path The path to request
|
||||
* @param query_params Query parameters
|
||||
* @return The response
|
||||
* @brief Get available tools
|
||||
* @return List of available tools
|
||||
* @throws mcp_exception on error
|
||||
*/
|
||||
response get(const std::string& path,
|
||||
const std::map<std::string, std::string>& query_params = {});
|
||||
std::vector<tool> get_tools();
|
||||
|
||||
/**
|
||||
* @brief Make a POST request
|
||||
* @param path The path to request
|
||||
* @param body The request body
|
||||
* @param content_type The content type
|
||||
* @return The response
|
||||
* @brief Get resource metadata
|
||||
* @param resource_path The path to the resource
|
||||
* @return The resource metadata
|
||||
* @throws mcp_exception on error
|
||||
*/
|
||||
response post(const std::string& path,
|
||||
const std::string& body = "",
|
||||
const std::string& content_type = content_type::json);
|
||||
json get_resource_metadata(const std::string& resource_path);
|
||||
|
||||
/**
|
||||
* @brief Make a POST request with JSON body
|
||||
* @param path The path to request
|
||||
* @param json_body The JSON body
|
||||
* @return The response
|
||||
* @throws mcp_exception on error
|
||||
* @brief Get client capabilities
|
||||
* @return The client capabilities
|
||||
*/
|
||||
response post_json(const std::string& path, const json& json_body);
|
||||
json get_capabilities();
|
||||
|
||||
/**
|
||||
* @brief Make a PUT request
|
||||
* @param path The path to request
|
||||
* @param body The request body
|
||||
* @param content_type The content type
|
||||
* @return The response
|
||||
* @brief Access a resource
|
||||
* @param resource_path The path to the resource
|
||||
* @param params Additional parameters for the resource
|
||||
* @return The resource data
|
||||
* @throws mcp_exception on error
|
||||
*/
|
||||
response put(const std::string& path,
|
||||
const std::string& body = "",
|
||||
const std::string& content_type = content_type::json);
|
||||
|
||||
/**
|
||||
* @brief Make a DELETE request
|
||||
* @param path The path to request
|
||||
* @return The response
|
||||
* @throws mcp_exception on error
|
||||
*/
|
||||
response delete_request(const std::string& path);
|
||||
|
||||
/**
|
||||
* @brief Make a generic request
|
||||
* @param method The HTTP method
|
||||
* @param path The path
|
||||
* @param body The request body (for POST, PUT, etc.)
|
||||
* @param headers Additional headers
|
||||
* @param query_params Query parameters
|
||||
* @return The response
|
||||
* @throws mcp_exception on error
|
||||
*/
|
||||
response make_request(http_method method,
|
||||
const std::string& path,
|
||||
const std::string& body = "",
|
||||
const std::map<std::string, std::string>& headers = {},
|
||||
const std::map<std::string, std::string>& query_params = {});
|
||||
json access_resource(const std::string& resource_path, const json& params = json::object());
|
||||
|
||||
private:
|
||||
std::string host_;
|
||||
int port_;
|
||||
std::string auth_header_;
|
||||
std::string auth_token_;
|
||||
int timeout_seconds_ = 30;
|
||||
json capabilities_;
|
||||
|
||||
std::map<std::string, std::string> default_headers_;
|
||||
json server_capabilities_;
|
||||
|
||||
|
||||
// HTTP client
|
||||
std::unique_ptr<httplib::Client> http_client_;
|
||||
|
@ -170,8 +161,8 @@ private:
|
|||
// Initialize the client
|
||||
void init_client();
|
||||
|
||||
// Process response
|
||||
response process_response(const httplib::Result& result);
|
||||
// Send a JSON-RPC request and get the response
|
||||
json send_jsonrpc(const request& req);
|
||||
};
|
||||
|
||||
} // namespace mcp
|
||||
|
|
|
@ -0,0 +1,168 @@
|
|||
/**
|
||||
* @file mcp_message.h
|
||||
* @brief Core definitions for the Model Context Protocol (MCP) framework
|
||||
*
|
||||
* This file contains the core structures and definitions for the MCP protocol.
|
||||
* Implements the 2024-11-05 basic protocol specification.
|
||||
*/
|
||||
|
||||
#ifndef MCP_MESSAGE_H
|
||||
#define MCP_MESSAGE_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
|
||||
// Include the JSON library for parsing and generating JSON
|
||||
#include "json.hpp"
|
||||
|
||||
namespace mcp {
|
||||
|
||||
// Use the nlohmann json library
|
||||
using json = nlohmann::ordered_json;
|
||||
|
||||
// MCP version
|
||||
constexpr const char* MCP_VERSION = "2024-11-05";
|
||||
|
||||
// MCP error codes (JSON-RPC 2.0 standard codes)
|
||||
enum class error_code {
|
||||
parse_error = -32700, // Invalid JSON
|
||||
invalid_request = -32600, // Invalid Request object
|
||||
method_not_found = -32601, // Method not found
|
||||
invalid_params = -32602, // Invalid method parameters
|
||||
internal_error = -32603, // Internal JSON-RPC error
|
||||
server_error_start = -32000, // Server error start
|
||||
server_error_end = -32099 // Server error end
|
||||
};
|
||||
|
||||
// MCP exception class
|
||||
class mcp_exception : public std::runtime_error {
|
||||
public:
|
||||
mcp_exception(error_code code, const std::string& message)
|
||||
: std::runtime_error(message), code_(code) {}
|
||||
|
||||
error_code code() const { return code_; }
|
||||
|
||||
private:
|
||||
error_code code_;
|
||||
};
|
||||
|
||||
// JSON-RPC 2.0 Request
|
||||
struct request {
|
||||
std::string jsonrpc = "2.0";
|
||||
std::string id;
|
||||
std::string method;
|
||||
json params;
|
||||
|
||||
// Create a request
|
||||
static request create(const std::string& method, const json& params = json::object()) {
|
||||
request req;
|
||||
req.jsonrpc = "2.0";
|
||||
req.id = generate_id();
|
||||
req.method = method;
|
||||
req.params = params;
|
||||
return req;
|
||||
}
|
||||
|
||||
// Create a notification (no response expected)
|
||||
static request create_notification(const std::string& method, const json& params = json::object()) {
|
||||
request req;
|
||||
req.jsonrpc = "2.0";
|
||||
req.id = ""; // Empty ID indicates notification
|
||||
req.method = method;
|
||||
req.params = params;
|
||||
return req;
|
||||
}
|
||||
|
||||
// Check if this is a notification
|
||||
bool is_notification() const {
|
||||
return id.empty();
|
||||
}
|
||||
|
||||
// Convert to JSON
|
||||
json to_json() const {
|
||||
json j = {
|
||||
{"jsonrpc", jsonrpc},
|
||||
{"method", method}
|
||||
};
|
||||
|
||||
if (!params.empty()) {
|
||||
j["params"] = params;
|
||||
}
|
||||
|
||||
if (!is_notification()) {
|
||||
j["id"] = id;
|
||||
}
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
private:
|
||||
// Generate a unique ID
|
||||
static std::string generate_id() {
|
||||
static int next_id = 1;
|
||||
return std::to_string(next_id++);
|
||||
}
|
||||
};
|
||||
|
||||
// JSON-RPC 2.0 Response
|
||||
struct response {
|
||||
std::string jsonrpc = "2.0";
|
||||
std::string id;
|
||||
json result;
|
||||
json error;
|
||||
|
||||
// Create a success response
|
||||
static response create_success(const std::string& req_id, const json& result_data = json::object()) {
|
||||
response res;
|
||||
res.jsonrpc = "2.0";
|
||||
res.id = req_id;
|
||||
res.result = result_data;
|
||||
return res;
|
||||
}
|
||||
|
||||
// Create an error response
|
||||
static response create_error(const std::string& req_id, error_code code, const std::string& message, const json& data = json::object()) {
|
||||
response res;
|
||||
res.jsonrpc = "2.0";
|
||||
res.id = req_id;
|
||||
res.error = {
|
||||
{"code", static_cast<int>(code)},
|
||||
{"message", message}
|
||||
};
|
||||
|
||||
if (!data.empty()) {
|
||||
res.error["data"] = data;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// Check if this is an error response
|
||||
bool is_error() const {
|
||||
return !error.empty();
|
||||
}
|
||||
|
||||
// Convert to JSON
|
||||
json to_json() const {
|
||||
json j = {
|
||||
{"jsonrpc", jsonrpc},
|
||||
{"id", id}
|
||||
};
|
||||
|
||||
if (is_error()) {
|
||||
j["error"] = error;
|
||||
} else {
|
||||
j["result"] = result;
|
||||
}
|
||||
|
||||
return j;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mcp
|
||||
|
||||
#endif // MCP_MESSAGE_H
|
|
@ -1,203 +0,0 @@
|
|||
/**
|
||||
* @file mcp_protocol.h
|
||||
* @brief Core definitions for the Model Context Protocol (MCP) framework
|
||||
*
|
||||
* This file contains the core structures, enums, and definitions for the MCP protocol.
|
||||
* MCP connects AI models with data sources and tools in a standardized way.
|
||||
*/
|
||||
|
||||
#ifndef MCP_PROTOCOL_H
|
||||
#define MCP_PROTOCOL_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
|
||||
// Include the JSON library for parsing and generating JSON
|
||||
#include "json.hpp"
|
||||
|
||||
namespace mcp {
|
||||
|
||||
// Use the nlohmann json library
|
||||
using json = nlohmann::ordered_json;
|
||||
|
||||
// MCP version
|
||||
constexpr const char* MCP_VERSION = "1.0.0";
|
||||
|
||||
// MCP error codes
|
||||
enum class error_code {
|
||||
none = 0,
|
||||
invalid_request = 400,
|
||||
unauthorized = 401,
|
||||
forbidden = 403,
|
||||
not_found = 404,
|
||||
method_not_allowed = 405,
|
||||
conflict = 409,
|
||||
payload_too_large = 413,
|
||||
unsupported_media_type = 415,
|
||||
internal_server_error = 500,
|
||||
service_unavailable = 503
|
||||
};
|
||||
|
||||
// MCP exception class
|
||||
class mcp_exception : public std::runtime_error {
|
||||
public:
|
||||
mcp_exception(error_code code, const std::string& message)
|
||||
: std::runtime_error(message), code_(code) {}
|
||||
|
||||
error_code code() const { return code_; }
|
||||
|
||||
private:
|
||||
error_code code_;
|
||||
};
|
||||
|
||||
// Resource Types
|
||||
enum class resource_type {
|
||||
file, // File resource
|
||||
directory, // Directory/folder resource
|
||||
database, // Database resource
|
||||
api, // API endpoints
|
||||
document, // Document resource
|
||||
image, // Image resource
|
||||
custom // Custom resource type
|
||||
};
|
||||
|
||||
// Content Types
|
||||
struct content_type {
|
||||
static constexpr const char* json = "application/json";
|
||||
static constexpr const char* text = "text/plain";
|
||||
static constexpr const char* octet_stream = "application/octet-stream";
|
||||
static constexpr const char* form = "application/x-www-form-urlencoded";
|
||||
static constexpr const char* multipart = "multipart/form-data";
|
||||
static constexpr const char* image_jpeg = "image/jpeg";
|
||||
static constexpr const char* image_png = "image/png";
|
||||
};
|
||||
|
||||
// HTTP Methods
|
||||
enum class http_method {
|
||||
get,
|
||||
post,
|
||||
put,
|
||||
delete_,
|
||||
patch,
|
||||
options,
|
||||
head
|
||||
};
|
||||
|
||||
// Convert HTTP method to string
|
||||
inline std::string http_method_to_string(http_method method) {
|
||||
switch (method) {
|
||||
case http_method::get: return "GET";
|
||||
case http_method::post: return "POST";
|
||||
case http_method::put: return "PUT";
|
||||
case http_method::delete_: return "DELETE";
|
||||
case http_method::patch: return "PATCH";
|
||||
case http_method::options: return "OPTIONS";
|
||||
case http_method::head: return "HEAD";
|
||||
default: return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
// Convert string to HTTP method
|
||||
inline http_method string_to_http_method(const std::string& method_str) {
|
||||
if (method_str == "GET") return http_method::get;
|
||||
if (method_str == "POST") return http_method::post;
|
||||
if (method_str == "PUT") return http_method::put;
|
||||
if (method_str == "DELETE") return http_method::delete_;
|
||||
if (method_str == "PATCH") return http_method::patch;
|
||||
if (method_str == "OPTIONS") return http_method::options;
|
||||
if (method_str == "HEAD") return http_method::head;
|
||||
throw mcp_exception(error_code::method_not_allowed, "Unsupported HTTP method: " + method_str);
|
||||
}
|
||||
|
||||
// MCP Request structure
|
||||
struct request {
|
||||
http_method method;
|
||||
std::string path;
|
||||
std::map<std::string, std::string> headers;
|
||||
std::map<std::string, std::string> query_params;
|
||||
std::string body;
|
||||
|
||||
// Parse JSON body
|
||||
json json_body() const {
|
||||
if (body.empty()) {
|
||||
return json::object();
|
||||
}
|
||||
try {
|
||||
return json::parse(body);
|
||||
} catch (const json::exception& e) {
|
||||
throw mcp_exception(error_code::invalid_request, "Invalid JSON in request body: " + std::string(e.what()));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// MCP Response structure
|
||||
struct response {
|
||||
int status_code = 200;
|
||||
std::map<std::string, std::string> headers;
|
||||
std::string body;
|
||||
|
||||
// Set JSON body
|
||||
void set_json_body(const json& data) {
|
||||
body = data.dump();
|
||||
headers["Content-Type"] = content_type::json;
|
||||
}
|
||||
|
||||
// Set error response
|
||||
void set_error(error_code code, const std::string& message) {
|
||||
status_code = static_cast<int>(code);
|
||||
json error = {
|
||||
{"error", {
|
||||
{"code", status_code},
|
||||
{"message", message}
|
||||
}}
|
||||
};
|
||||
set_json_body(error);
|
||||
}
|
||||
};
|
||||
|
||||
// Base class for MCP resources
|
||||
class resource {
|
||||
public:
|
||||
virtual ~resource() = default;
|
||||
|
||||
// Get resource type
|
||||
virtual resource_type type() const = 0;
|
||||
|
||||
// Get resource metadata
|
||||
virtual json metadata() const = 0;
|
||||
|
||||
// Handle request
|
||||
virtual response handle_request(const request& req) = 0;
|
||||
|
||||
// Get resource schema
|
||||
virtual json schema() const {
|
||||
return json::object(); // Default empty schema
|
||||
}
|
||||
};
|
||||
|
||||
// MCP Tool definition
|
||||
struct tool {
|
||||
std::string name;
|
||||
std::string description;
|
||||
json parameters_schema;
|
||||
|
||||
// Convert to JSON for API documentation
|
||||
json to_json() const {
|
||||
return {
|
||||
{"name", name},
|
||||
{"description", description},
|
||||
{"parameters", parameters_schema}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// Tool handler function type
|
||||
using tool_handler = std::function<json(const json&)>;
|
||||
|
||||
} // namespace mcp
|
||||
|
||||
#endif // MCP_PROTOCOL_H
|
|
@ -3,20 +3,46 @@
|
|||
* @brief Resource implementation for MCP
|
||||
*
|
||||
* This file defines the base resource class and common resource types for the MCP protocol.
|
||||
* Follows the 2024-11-05 basic protocol specification.
|
||||
*/
|
||||
|
||||
#ifndef MCP_RESOURCE_H
|
||||
#define MCP_RESOURCE_H
|
||||
|
||||
#include "mcp_protocol.h"
|
||||
#include "mcp_message.h"
|
||||
|
||||
namespace mcp {
|
||||
|
||||
/**
|
||||
* @class resource
|
||||
* @brief Base class for MCP resources
|
||||
*
|
||||
* The resource class defines the interface for resources that can be
|
||||
* accessed through the MCP protocol.
|
||||
*/
|
||||
class resource {
|
||||
public:
|
||||
virtual ~resource() = default;
|
||||
|
||||
/**
|
||||
* @brief Get resource metadata
|
||||
* @return Metadata as JSON
|
||||
*/
|
||||
virtual json get_metadata() const = 0;
|
||||
|
||||
/**
|
||||
* @brief Access the resource
|
||||
* @param params Parameters for accessing the resource
|
||||
* @return The resource data
|
||||
*/
|
||||
virtual json access(const json& params) const = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @class file_resource
|
||||
* @brief Resource for file system operations
|
||||
*
|
||||
* The file_resource class provides access to files and directories.
|
||||
* The file_resource class provides access to files.
|
||||
*/
|
||||
class file_resource : public resource {
|
||||
public:
|
||||
|
@ -26,91 +52,27 @@ public:
|
|||
*/
|
||||
explicit file_resource(const std::string& base_path);
|
||||
|
||||
/**
|
||||
* @brief Get resource type
|
||||
* @return Resource type
|
||||
*/
|
||||
resource_type type() const override {
|
||||
return resource_type::file;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get resource metadata
|
||||
* @return Metadata as JSON
|
||||
*/
|
||||
json metadata() const override;
|
||||
json get_metadata() const override;
|
||||
|
||||
/**
|
||||
* @brief Handle request
|
||||
* @param req The request
|
||||
* @return The response
|
||||
* @brief Access the resource
|
||||
* @param params Parameters for accessing the resource
|
||||
* @return The resource data
|
||||
*/
|
||||
response handle_request(const request& req) override;
|
||||
|
||||
/**
|
||||
* @brief Get resource schema
|
||||
* @return The schema as JSON
|
||||
*/
|
||||
json schema() const override;
|
||||
json access(const json& params) const override;
|
||||
|
||||
private:
|
||||
std::string base_path_;
|
||||
|
||||
// Helper methods
|
||||
response read_file(const std::string& path);
|
||||
response write_file(const std::string& path, const std::string& content);
|
||||
response delete_file(const std::string& path);
|
||||
response list_directory(const std::string& path);
|
||||
};
|
||||
|
||||
/**
|
||||
* @class directory_resource
|
||||
* @brief Resource for directory operations
|
||||
*
|
||||
* The directory_resource class provides access to directories.
|
||||
*/
|
||||
class directory_resource : public resource {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param base_path The base path for directory operations (for security)
|
||||
*/
|
||||
explicit directory_resource(const std::string& base_path);
|
||||
|
||||
/**
|
||||
* @brief Get resource type
|
||||
* @return Resource type
|
||||
*/
|
||||
resource_type type() const override {
|
||||
return resource_type::directory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get resource metadata
|
||||
* @return Metadata as JSON
|
||||
*/
|
||||
json metadata() const override;
|
||||
|
||||
/**
|
||||
* @brief Handle request
|
||||
* @param req The request
|
||||
* @return The response
|
||||
*/
|
||||
response handle_request(const request& req) override;
|
||||
|
||||
/**
|
||||
* @brief Get resource schema
|
||||
* @return The schema as JSON
|
||||
*/
|
||||
json schema() const override;
|
||||
|
||||
private:
|
||||
std::string base_path_;
|
||||
|
||||
// Helper methods
|
||||
response list_directory(const std::string& path);
|
||||
response create_directory(const std::string& path);
|
||||
response delete_directory(const std::string& path);
|
||||
json read_file(const std::string& path) const;
|
||||
json write_file(const std::string& path, const std::string& content) const;
|
||||
json delete_file(const std::string& path) const;
|
||||
json list_directory(const std::string& path) const;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -121,7 +83,7 @@ private:
|
|||
*/
|
||||
class api_resource : public resource {
|
||||
public:
|
||||
using handler_func = std::function<response(const request&)>;
|
||||
using handler_func = std::function<json(const json&)>;
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
|
@ -130,107 +92,38 @@ public:
|
|||
*/
|
||||
api_resource(const std::string& name, const std::string& description);
|
||||
|
||||
/**
|
||||
* @brief Get resource type
|
||||
* @return Resource type
|
||||
*/
|
||||
resource_type type() const override {
|
||||
return resource_type::api;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get resource metadata
|
||||
* @return Metadata as JSON
|
||||
*/
|
||||
json metadata() const override;
|
||||
json get_metadata() const override;
|
||||
|
||||
/**
|
||||
* @brief Handle request
|
||||
* @param req The request
|
||||
* @return The response
|
||||
* @brief Access the resource
|
||||
* @param params Parameters for accessing the resource
|
||||
* @return The resource data
|
||||
*/
|
||||
response handle_request(const request& req) override;
|
||||
json access(const json& params) const override;
|
||||
|
||||
/**
|
||||
* @brief Get resource schema
|
||||
* @return The schema as JSON
|
||||
*/
|
||||
json schema() const override;
|
||||
|
||||
/**
|
||||
* @brief Register a handler for a specific path and HTTP method
|
||||
* @param method The HTTP method
|
||||
* @param path The path (relative to the resource path)
|
||||
* @brief Register a handler for a specific endpoint
|
||||
* @param endpoint The endpoint name
|
||||
* @param handler The handler function
|
||||
* @param description Description of the endpoint
|
||||
* @param schema Schema of the endpoint parameters/response
|
||||
*/
|
||||
void register_handler(http_method method,
|
||||
const std::string& path,
|
||||
void register_handler(const std::string& endpoint,
|
||||
handler_func handler,
|
||||
const std::string& description = "",
|
||||
const json& schema = json::object());
|
||||
const std::string& description = "");
|
||||
|
||||
private:
|
||||
struct endpoint {
|
||||
struct endpoint_info {
|
||||
handler_func handler;
|
||||
std::string description;
|
||||
json schema;
|
||||
};
|
||||
|
||||
std::string name_;
|
||||
std::string description_;
|
||||
std::map<std::string, std::map<http_method, endpoint>> endpoints_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @class image_resource
|
||||
* @brief Resource for image operations
|
||||
*
|
||||
* The image_resource class provides access to images.
|
||||
*/
|
||||
class image_resource : public resource {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param base_path The base path for image files (for security)
|
||||
*/
|
||||
explicit image_resource(const std::string& base_path);
|
||||
|
||||
/**
|
||||
* @brief Get resource type
|
||||
* @return Resource type
|
||||
*/
|
||||
resource_type type() const override {
|
||||
return resource_type::image;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get resource metadata
|
||||
* @return Metadata as JSON
|
||||
*/
|
||||
json metadata() const override;
|
||||
|
||||
/**
|
||||
* @brief Handle request
|
||||
* @param req The request
|
||||
* @return The response
|
||||
*/
|
||||
response handle_request(const request& req) override;
|
||||
|
||||
/**
|
||||
* @brief Get resource schema
|
||||
* @return The schema as JSON
|
||||
*/
|
||||
json schema() const override;
|
||||
|
||||
private:
|
||||
std::string base_path_;
|
||||
|
||||
// Helper methods
|
||||
response get_image(const std::string& path);
|
||||
response upload_image(const std::string& path, const std::string& content, bool is_base64 = false);
|
||||
response resize_image(const std::string& path, int width, int height);
|
||||
std::map<std::string, endpoint_info> endpoints_;
|
||||
};
|
||||
|
||||
} // namespace mcp
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
/**
|
||||
* @file mcp_server.h
|
||||
* @brief MCP Server implementation using cpp-httplib
|
||||
* @brief MCP Server implementation
|
||||
*
|
||||
* This file implements the server-side functionality for the Model Context Protocol.
|
||||
* Follows the 2024-11-05 basic protocol specification.
|
||||
*/
|
||||
|
||||
#ifndef MCP_SERVER_H
|
||||
#define MCP_SERVER_H
|
||||
|
||||
#include "mcp_protocol.h"
|
||||
#include "mcp_message.h"
|
||||
#include "mcp_resource.h"
|
||||
#include "mcp_tools.h"
|
||||
#include "mcp_tool.h"
|
||||
|
||||
// Include the HTTP library
|
||||
#include "httplib.h"
|
||||
|
@ -22,7 +23,6 @@
|
|||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
|
||||
namespace mcp {
|
||||
|
||||
|
@ -30,8 +30,8 @@ namespace mcp {
|
|||
* @class server
|
||||
* @brief Main MCP server class
|
||||
*
|
||||
* The server class implements an HTTP server that exposes MCP resources
|
||||
* and tools to clients (like AI models or agents).
|
||||
* The server class implements an HTTP server that handles JSON-RPC requests
|
||||
* according to the Model Context Protocol specification.
|
||||
*/
|
||||
class server {
|
||||
public:
|
||||
|
@ -65,6 +65,33 @@ public:
|
|||
*/
|
||||
bool is_running() const;
|
||||
|
||||
/**
|
||||
* @brief Set server information
|
||||
* @param name The name of the server
|
||||
* @param version The version of the server
|
||||
*/
|
||||
void set_server_info(const std::string& name, const std::string& version);
|
||||
|
||||
/**
|
||||
* @brief Set server capabilities
|
||||
* @param capabilities The capabilities of the server
|
||||
*/
|
||||
void set_capabilities(const json& capabilities);
|
||||
|
||||
/**
|
||||
* @brief Register a method handler
|
||||
* @param method The method name
|
||||
* @param handler The function to call when the method is invoked
|
||||
*/
|
||||
void register_method(const std::string& method, std::function<json(const json&)> handler);
|
||||
|
||||
/**
|
||||
* @brief Register a notification handler
|
||||
* @param method The notification method name
|
||||
* @param handler The function to call when the notification is received
|
||||
*/
|
||||
void register_notification(const std::string& method, std::function<void(const json&)> handler);
|
||||
|
||||
/**
|
||||
* @brief Register a resource
|
||||
* @param path The path to mount the resource at
|
||||
|
@ -83,39 +110,20 @@ public:
|
|||
* @brief Get the list of available tools
|
||||
* @return JSON array of available tools
|
||||
*/
|
||||
json get_tools() const;
|
||||
std::vector<tool> get_tools() const;
|
||||
|
||||
/**
|
||||
* @brief Get server information
|
||||
* @return JSON object with server information
|
||||
* @brief Set authentication handler
|
||||
* @param handler Function that takes a token and returns true if valid
|
||||
*/
|
||||
json get_server_info() const;
|
||||
|
||||
// /**
|
||||
// * @brief Set authentication callback
|
||||
// * @param callback Function that takes username and password and returns true if valid
|
||||
// */
|
||||
// void set_auth_callback(std::function<bool(const std::string&, const std::string&)> callback);
|
||||
|
||||
/**
|
||||
* @brief Enable or disable CORS
|
||||
* @param enable True to enable CORS, false to disable
|
||||
* @param allowed_origins Comma-separated list of allowed origins (default "*")
|
||||
*/
|
||||
void set_cors(bool enable, const std::string& allowed_origins = "*");
|
||||
|
||||
/**
|
||||
* @brief Set the server name
|
||||
* @param name The name of the server
|
||||
*/
|
||||
void set_name(const std::string& name);
|
||||
void set_auth_handler(std::function<bool(const std::string&)> handler);
|
||||
|
||||
private:
|
||||
std::string host_;
|
||||
int port_;
|
||||
std::string name_;
|
||||
bool cors_enabled_;
|
||||
std::string allowed_origins_;
|
||||
std::string version_;
|
||||
json capabilities_;
|
||||
|
||||
// The HTTP server
|
||||
std::unique_ptr<httplib::Server> http_server_;
|
||||
|
@ -123,14 +131,20 @@ private:
|
|||
// Server thread (for non-blocking mode)
|
||||
std::unique_ptr<std::thread> server_thread_;
|
||||
|
||||
// Method handlers
|
||||
std::map<std::string, std::function<json(const json&)>> method_handlers_;
|
||||
|
||||
// Notification handlers
|
||||
std::map<std::string, std::function<void(const json&)>> notification_handlers_;
|
||||
|
||||
// Resources map (path -> resource)
|
||||
std::map<std::string, std::shared_ptr<resource>> resources_;
|
||||
|
||||
// Tools map (name -> handler)
|
||||
std::map<std::string, std::pair<tool, tool_handler>> tools_;
|
||||
|
||||
// Authentication callback
|
||||
std::function<bool(const std::string&, const std::string&)> auth_callback_;
|
||||
// Authentication handler
|
||||
std::function<bool(const std::string&)> auth_handler_;
|
||||
|
||||
// Mutex for thread safety
|
||||
mutable std::mutex mutex_;
|
||||
|
@ -138,19 +152,17 @@ private:
|
|||
// Running flag
|
||||
bool running_ = false;
|
||||
|
||||
// Handle incoming requests
|
||||
void handle_request(const httplib::Request& req, httplib::Response& res);
|
||||
// Handle incoming JSON-RPC requests
|
||||
void handle_jsonrpc(const httplib::Request& req, httplib::Response& res);
|
||||
|
||||
// Convert httplib Request to mcp Request
|
||||
request convert_request(const httplib::Request& req);
|
||||
// Process a JSON-RPC request
|
||||
json process_request(const request& req);
|
||||
|
||||
// Apply mcp Response to httplib Response
|
||||
void apply_response(const response& mcp_res, httplib::Response& http_res);
|
||||
|
||||
// Set CORS headers if enabled
|
||||
void set_cors_headers(httplib::Response& res);
|
||||
// Handle initialization request
|
||||
json handle_initialize(const request& req);
|
||||
};
|
||||
|
||||
|
||||
} // namespace mcp
|
||||
|
||||
#endif // MCP_SERVER_H
|
|
@ -1,14 +1,14 @@
|
|||
/**
|
||||
* @file mcp_tools.h
|
||||
* @file mcp_tool.h
|
||||
* @brief Tool definitions and helper functions for MCP
|
||||
*
|
||||
* This file provides tool-related functionality and abstractions for the MCP protocol.
|
||||
*/
|
||||
|
||||
#ifndef MCP_TOOLS_H
|
||||
#define MCP_TOOLS_H
|
||||
#ifndef MCP_TOOL_H
|
||||
#define MCP_TOOL_H
|
||||
|
||||
#include "mcp_protocol.h"
|
||||
#include "mcp_message.h"
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -17,6 +17,25 @@
|
|||
|
||||
namespace mcp {
|
||||
|
||||
// Tool handler function type
|
||||
using tool_handler = std::function<json(const json&)>;
|
||||
|
||||
// MCP Tool definition
|
||||
struct tool {
|
||||
std::string name;
|
||||
std::string description;
|
||||
json parameters_schema;
|
||||
|
||||
// Convert to JSON for API documentation
|
||||
json to_json() const {
|
||||
return {
|
||||
{"name", name},
|
||||
{"description", description},
|
||||
{"parameters", parameters_schema}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @class tool_registry
|
||||
* @brief Registry for MCP tools
|
||||
|
@ -215,186 +234,6 @@ inline tool create_tool(
|
|||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* @class workflow_step
|
||||
* @brief Represents a step in a workflow
|
||||
*
|
||||
* The workflow_step class defines a single step in a workflow, which includes
|
||||
* a tool call or other action to be performed.
|
||||
*/
|
||||
class workflow_step {
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Default constructor
|
||||
*/
|
||||
workflow_step() : id_(""), tool_name_(""), parameters_(json::object()) {}
|
||||
|
||||
/**
|
||||
* @brief Constructor for a tool call step
|
||||
* @param tool_name The name of the tool to call
|
||||
* @param parameters The parameters to pass to the tool
|
||||
*/
|
||||
workflow_step(const std::string& tool_name, const json& parameters = json::object());
|
||||
|
||||
/**
|
||||
* @brief Execute the step
|
||||
* @param context The context to execute in
|
||||
* @return The result of the step execution
|
||||
*/
|
||||
json execute(json& context) const;
|
||||
|
||||
/**
|
||||
* @brief Get the step ID
|
||||
* @return The step ID
|
||||
*/
|
||||
const std::string& id() const { return id_; }
|
||||
|
||||
/**
|
||||
* @brief Get the tool name
|
||||
* @return The tool name
|
||||
*/
|
||||
const std::string& tool_name() const { return tool_name_; }
|
||||
|
||||
/**
|
||||
* @brief Get the parameters
|
||||
* @return The parameters
|
||||
*/
|
||||
const json& parameters() const { return parameters_; }
|
||||
|
||||
private:
|
||||
std::string id_;
|
||||
std::string tool_name_;
|
||||
json parameters_;
|
||||
static int next_id_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @class workflow
|
||||
* @brief Represents a workflow of connected steps
|
||||
*
|
||||
* The workflow class defines a sequence of steps that can be executed in order,
|
||||
* with optional branching based on conditions.
|
||||
*/
|
||||
class workflow {
|
||||
public:
|
||||
/**
|
||||
* @brief Default constructor
|
||||
*/
|
||||
workflow();
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param name The name of the workflow
|
||||
* @param description The description of the workflow
|
||||
*/
|
||||
workflow(const std::string& name, const std::string& description = "");
|
||||
|
||||
/**
|
||||
* @brief Add a step to the workflow
|
||||
* @param step The step to add
|
||||
* @return Reference to this workflow
|
||||
*/
|
||||
workflow& add_step(const workflow_step& step);
|
||||
|
||||
/**
|
||||
* @brief Add a tool call step to the workflow
|
||||
* @param tool_name The name of the tool to call
|
||||
* @param parameters The parameters to pass to the tool
|
||||
* @return Reference to this workflow
|
||||
*/
|
||||
workflow& add_tool_call(const std::string& tool_name, const json& parameters = json::object());
|
||||
|
||||
/**
|
||||
* @brief Execute the workflow
|
||||
* @param initial_context Initial context data
|
||||
* @return The final context after execution
|
||||
*/
|
||||
json execute(const json& initial_context = json::object()) const;
|
||||
|
||||
/**
|
||||
* @brief Get the workflow name
|
||||
* @return The workflow name
|
||||
*/
|
||||
const std::string& name() const { return name_; }
|
||||
|
||||
/**
|
||||
* @brief Get the workflow description
|
||||
* @return The workflow description
|
||||
*/
|
||||
const std::string& description() const { return description_; }
|
||||
|
||||
/**
|
||||
* @brief Get the workflow steps
|
||||
* @return The workflow steps
|
||||
*/
|
||||
const std::vector<workflow_step>& steps() const { return steps_; }
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
std::string description_;
|
||||
std::vector<workflow_step> steps_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @class agent
|
||||
* @brief Base class for MCP agents
|
||||
*
|
||||
* The agent class defines the interface and common functionality for
|
||||
* agents that can use MCP tools and resources.
|
||||
*/
|
||||
class agent {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param name The name of the agent
|
||||
*/
|
||||
explicit agent(const std::string& name);
|
||||
|
||||
/**
|
||||
* @brief Virtual destructor
|
||||
*/
|
||||
virtual ~agent() = default;
|
||||
|
||||
/**
|
||||
* @brief Initialize the agent
|
||||
* @param config Configuration parameters
|
||||
*/
|
||||
virtual void initialize(const json& config) = 0;
|
||||
|
||||
/**
|
||||
* @brief Process a request
|
||||
* @param input The input data
|
||||
* @return The processed output
|
||||
*/
|
||||
virtual json process(const json& input) = 0;
|
||||
|
||||
/**
|
||||
* @brief Get the agent name
|
||||
* @return The agent name
|
||||
*/
|
||||
const std::string& name() const { return name_; }
|
||||
|
||||
/**
|
||||
* @brief Call a tool
|
||||
* @param tool_name The name of the tool to call
|
||||
* @param parameters The parameters to pass to the tool
|
||||
* @return The result of the tool call
|
||||
*/
|
||||
json call_tool(const std::string& tool_name, const json& parameters = json::object());
|
||||
|
||||
/**
|
||||
* @brief Execute a workflow
|
||||
* @param workflow The workflow to execute
|
||||
* @param initial_context Initial context data
|
||||
* @return The final context after execution
|
||||
*/
|
||||
json execute_workflow(const workflow& workflow, const json& initial_context = json::object());
|
||||
|
||||
protected:
|
||||
std::string name_;
|
||||
json context_;
|
||||
};
|
||||
|
||||
} // namespace mcp
|
||||
|
||||
#endif // MCP_TOOLS_H
|
||||
#endif // MCP_TOOL_H
|
|
@ -1,184 +0,0 @@
|
|||
/**
|
||||
* @file mcp_workflow_resource.h
|
||||
* @brief Resource implementation for MCP workflows
|
||||
*
|
||||
* This file defines a resource for managing workflows in the MCP protocol.
|
||||
*/
|
||||
|
||||
#ifndef MCP_WORKFLOW_RESOURCE_H
|
||||
#define MCP_WORKFLOW_RESOURCE_H
|
||||
|
||||
#include "mcp_protocol.h"
|
||||
#include "mcp_resource.h"
|
||||
#include "mcp_tools.h"
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
|
||||
namespace mcp {
|
||||
|
||||
/**
|
||||
* @class workflow_resource
|
||||
* @brief Resource for managing workflows
|
||||
*
|
||||
* The workflow_resource class provides a RESTful interface for creating,
|
||||
* executing, and managing workflows.
|
||||
*/
|
||||
class workflow_resource : public resource {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param name Resource name
|
||||
*/
|
||||
explicit workflow_resource(const std::string& name = "Workflow Manager");
|
||||
|
||||
/**
|
||||
* @brief Get resource type
|
||||
* @return Resource type
|
||||
*/
|
||||
resource_type type() const override {
|
||||
return resource_type::custom;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get resource metadata
|
||||
* @return Metadata as JSON
|
||||
*/
|
||||
json metadata() const override;
|
||||
|
||||
/**
|
||||
* @brief Handle request
|
||||
* @param req The request
|
||||
* @return The response
|
||||
*/
|
||||
response handle_request(const request& req) override;
|
||||
|
||||
/**
|
||||
* @brief Get resource schema
|
||||
* @return The schema as JSON
|
||||
*/
|
||||
json schema() const override;
|
||||
|
||||
/**
|
||||
* @brief Register a workflow
|
||||
* @param workflow The workflow to register
|
||||
*/
|
||||
void register_workflow(const workflow& workflow);
|
||||
|
||||
/**
|
||||
* @brief Unregister a workflow
|
||||
* @param name The name of the workflow
|
||||
* @return True if the workflow was found and unregistered
|
||||
*/
|
||||
bool unregister_workflow(const std::string& name);
|
||||
|
||||
/**
|
||||
* @brief Get a workflow by name
|
||||
* @param name The name of the workflow
|
||||
* @return Pointer to the workflow, or nullptr if not found
|
||||
*/
|
||||
const workflow* get_workflow(const std::string& name) const;
|
||||
|
||||
/**
|
||||
* @brief Get all registered workflows
|
||||
* @return A vector of all registered workflows
|
||||
*/
|
||||
std::vector<std::string> get_workflow_names() const;
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
std::map<std::string, workflow> workflows_;
|
||||
mutable std::mutex mutex_;
|
||||
|
||||
// Handler methods for different operations
|
||||
response list_workflows(const request& req);
|
||||
response get_workflow_details(const request& req, const std::string& workflow_name);
|
||||
response create_workflow(const request& req);
|
||||
response update_workflow(const request& req, const std::string& workflow_name);
|
||||
response delete_workflow(const request& req, const std::string& workflow_name);
|
||||
response execute_workflow(const request& req, const std::string& workflow_name);
|
||||
};
|
||||
|
||||
/**
|
||||
* @class agent_resource
|
||||
* @brief Resource for managing agents
|
||||
*
|
||||
* The agent_resource class provides a RESTful interface for creating
|
||||
* and managing agents that can execute workflows and tools.
|
||||
*/
|
||||
class agent_resource : public resource {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param name Resource name
|
||||
*/
|
||||
explicit agent_resource(const std::string& name = "Agent Manager");
|
||||
|
||||
/**
|
||||
* @brief Get resource type
|
||||
* @return Resource type
|
||||
*/
|
||||
resource_type type() const override {
|
||||
return resource_type::custom;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get resource metadata
|
||||
* @return Metadata as JSON
|
||||
*/
|
||||
json metadata() const override;
|
||||
|
||||
/**
|
||||
* @brief Handle request
|
||||
* @param req The request
|
||||
* @return The response
|
||||
*/
|
||||
response handle_request(const request& req) override;
|
||||
|
||||
/**
|
||||
* @brief Get resource schema
|
||||
* @return The schema as JSON
|
||||
*/
|
||||
json schema() const override;
|
||||
|
||||
/**
|
||||
* @brief Register an agent
|
||||
* @param agent The agent to register
|
||||
*/
|
||||
void register_agent(std::shared_ptr<agent> agent);
|
||||
|
||||
/**
|
||||
* @brief Unregister an agent
|
||||
* @param name The name of the agent
|
||||
* @return True if the agent was found and unregistered
|
||||
*/
|
||||
bool unregister_agent(const std::string& name);
|
||||
|
||||
/**
|
||||
* @brief Get an agent by name
|
||||
* @param name The name of the agent
|
||||
* @return Pointer to the agent, or nullptr if not found
|
||||
*/
|
||||
std::shared_ptr<agent> get_agent(const std::string& name) const;
|
||||
|
||||
/**
|
||||
* @brief Get all registered agents
|
||||
* @return A vector of agent names
|
||||
*/
|
||||
std::vector<std::string> get_agent_names() const;
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
std::map<std::string, std::shared_ptr<agent>> agents_;
|
||||
mutable std::mutex mutex_;
|
||||
|
||||
// Handler methods for different operations
|
||||
response list_agents(const request& req);
|
||||
response get_agent_details(const request& req, const std::string& agent_name);
|
||||
response create_agent(const request& req);
|
||||
response delete_agent(const request& req, const std::string& agent_name);
|
||||
response process_agent_request(const request& req, const std::string& agent_name);
|
||||
};
|
||||
|
||||
} // namespace mcp
|
||||
|
||||
#endif // MCP_WORKFLOW_RESOURCE_H
|
|
@ -1,19 +1,16 @@
|
|||
set(TARGET mcp)
|
||||
|
||||
add_library(${TARGET} STATIC
|
||||
mcp_agent_resource.cpp
|
||||
mcp_client.cpp
|
||||
../include/mcp_client.h
|
||||
mcp_protocol.cpp
|
||||
../include/mcp_protocol.h
|
||||
mcp_message.cpp
|
||||
../include/mcp_message.h
|
||||
mcp_resource.cpp
|
||||
../include/mcp_resource.h
|
||||
mcp_server.cpp
|
||||
../include/mcp_server.h
|
||||
mcp_tools.cpp
|
||||
../include/mcp_tools.h
|
||||
mcp_workflow_resource.cpp
|
||||
../include/mcp_workflow_resource.h
|
||||
mcp_tool.cpp
|
||||
../include/mcp_tool.h
|
||||
)
|
||||
|
||||
target_link_libraries(${TARGET} PUBLIC
|
||||
|
|
|
@ -1,247 +0,0 @@
|
|||
/**
|
||||
* @file mcp_agent_resource.cpp
|
||||
* @brief Implementation of the agent resource for MCP
|
||||
*/
|
||||
|
||||
#include "mcp_workflow_resource.h"
|
||||
|
||||
namespace mcp {
|
||||
|
||||
// agent_resource implementation
|
||||
agent_resource::agent_resource(const std::string& name)
|
||||
: name_(name) {
|
||||
}
|
||||
|
||||
json agent_resource::metadata() const {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
|
||||
json metadata = {
|
||||
{"name", name_},
|
||||
{"description", "Agent management resource"},
|
||||
{"agent_count", agents_.size()},
|
||||
{"agents", json::array()}
|
||||
};
|
||||
|
||||
for (const auto& [name, agent_ptr] : agents_) {
|
||||
metadata["agents"].push_back({
|
||||
{"name", name}
|
||||
});
|
||||
}
|
||||
|
||||
return metadata;
|
||||
}
|
||||
|
||||
response agent_resource::handle_request(const request& req) {
|
||||
// Route the request to the appropriate handler based on the path and method
|
||||
std::string path = req.path;
|
||||
|
||||
// Remove trailing slash if present
|
||||
if (!path.empty() && path.back() == '/') {
|
||||
path.pop_back();
|
||||
}
|
||||
|
||||
// Root path - list all agents
|
||||
if (path.empty() || path == "/") {
|
||||
if (req.method == http_method::get) {
|
||||
return list_agents(req);
|
||||
} else if (req.method == http_method::post) {
|
||||
return create_agent(req);
|
||||
}
|
||||
} else {
|
||||
// Extract agent name from path
|
||||
// The path format is expected to be /<agent_name>/process
|
||||
std::string agent_name;
|
||||
bool is_process = false;
|
||||
|
||||
// Check if the path ends with /process
|
||||
if (path.length() > 8 && path.substr(path.length() - 8) == "/process") {
|
||||
agent_name = path.substr(1, path.length() - 9);
|
||||
is_process = true;
|
||||
} else {
|
||||
agent_name = path.substr(1); // Remove leading slash
|
||||
}
|
||||
|
||||
if (is_process) {
|
||||
// Process agent request
|
||||
if (req.method == http_method::post) {
|
||||
return process_agent_request(req, agent_name);
|
||||
}
|
||||
} else {
|
||||
// Agent-specific operations
|
||||
if (req.method == http_method::get) {
|
||||
return get_agent_details(req, agent_name);
|
||||
} else if (req.method == http_method::delete_) {
|
||||
return delete_agent(req, agent_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we get here, the request is not supported
|
||||
response res;
|
||||
res.set_error(error_code::method_not_allowed,
|
||||
"Method not allowed for this path");
|
||||
return res;
|
||||
}
|
||||
|
||||
json agent_resource::schema() const {
|
||||
return {
|
||||
{"type", "object"},
|
||||
{"properties", {
|
||||
{"name", {
|
||||
{"type", "string"},
|
||||
{"description", "Agent name"}
|
||||
}},
|
||||
{"type", {
|
||||
{"type", "string"},
|
||||
{"description", "Agent type"}
|
||||
}},
|
||||
{"config", {
|
||||
{"type", "object"},
|
||||
{"description", "Agent configuration"}
|
||||
}}
|
||||
}},
|
||||
{"required", {"name", "type"}}
|
||||
};
|
||||
}
|
||||
|
||||
void agent_resource::register_agent(std::shared_ptr<agent> agent) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
agents_[agent->name()] = agent;
|
||||
}
|
||||
|
||||
bool agent_resource::unregister_agent(const std::string& name) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
return agents_.erase(name) > 0;
|
||||
}
|
||||
|
||||
std::shared_ptr<agent> agent_resource::get_agent(const std::string& name) const {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
auto it = agents_.find(name);
|
||||
if (it != agents_.end()) {
|
||||
return it->second;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<std::string> agent_resource::get_agent_names() const {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
std::vector<std::string> names;
|
||||
for (const auto& [name, _] : agents_) {
|
||||
names.push_back(name);
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
response agent_resource::list_agents(const request& req) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
|
||||
json agents_json = json::array();
|
||||
|
||||
for (const auto& [name, agent_ptr] : agents_) {
|
||||
json agent_json = {
|
||||
{"name", name}
|
||||
};
|
||||
agents_json.push_back(agent_json);
|
||||
}
|
||||
|
||||
response res;
|
||||
res.set_json_body(agents_json);
|
||||
return res;
|
||||
}
|
||||
|
||||
response agent_resource::get_agent_details(const request& req,
|
||||
const std::string& agent_name) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
|
||||
auto it = agents_.find(agent_name);
|
||||
if (it == agents_.end()) {
|
||||
response res;
|
||||
res.set_error(error_code::not_found, "Agent not found: " + agent_name);
|
||||
return res;
|
||||
}
|
||||
|
||||
json agent_json = {
|
||||
{"name", it->second->name()}
|
||||
};
|
||||
|
||||
response res;
|
||||
res.set_json_body(agent_json);
|
||||
return res;
|
||||
}
|
||||
|
||||
response agent_resource::create_agent(const request& req) {
|
||||
// This is just a stub implementation since we don't know what kind of agents
|
||||
// the user will want to create. In a real implementation, we would:
|
||||
// 1. Parse the request body to get agent type and config
|
||||
// 2. Create the appropriate agent based on the type
|
||||
// 3. Register the agent
|
||||
|
||||
response res;
|
||||
res.set_error(error_code::not_found,
|
||||
"Agent creation not implemented in this example");
|
||||
return res;
|
||||
}
|
||||
|
||||
response agent_resource::delete_agent(const request& req,
|
||||
const std::string& agent_name) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
|
||||
auto it = agents_.find(agent_name);
|
||||
if (it == agents_.end()) {
|
||||
response res;
|
||||
res.set_error(error_code::not_found, "Agent not found: " + agent_name);
|
||||
return res;
|
||||
}
|
||||
|
||||
agents_.erase(it);
|
||||
|
||||
response res;
|
||||
res.status_code = 204; // No Content
|
||||
return res;
|
||||
}
|
||||
|
||||
response agent_resource::process_agent_request(const request& req,
|
||||
const std::string& agent_name) {
|
||||
// Get the agent
|
||||
std::shared_ptr<agent> agent_ptr;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
|
||||
auto it = agents_.find(agent_name);
|
||||
if (it == agents_.end()) {
|
||||
response res;
|
||||
res.set_error(error_code::not_found, "Agent not found: " + agent_name);
|
||||
return res;
|
||||
}
|
||||
|
||||
agent_ptr = it->second;
|
||||
}
|
||||
|
||||
// Parse the request body
|
||||
json input;
|
||||
try {
|
||||
input = req.json_body();
|
||||
} catch (const mcp_exception& e) {
|
||||
response res;
|
||||
res.set_error(e.code(), e.what());
|
||||
return res;
|
||||
}
|
||||
|
||||
// Process the request with the agent
|
||||
json result;
|
||||
try {
|
||||
result = agent_ptr->process(input);
|
||||
} catch (const std::exception& e) {
|
||||
response res;
|
||||
res.set_error(error_code::internal_server_error,
|
||||
"Agent processing failed: " + std::string(e.what()));
|
||||
return res;
|
||||
}
|
||||
|
||||
// Return the result
|
||||
response res;
|
||||
res.set_json_body(result);
|
||||
return res;
|
||||
}
|
||||
|
||||
} // namespace mcp
|
|
@ -1,6 +1,9 @@
|
|||
/**
|
||||
* @file mcp_client.cpp
|
||||
* @brief Implementation of the MCP client
|
||||
*
|
||||
* This file implements the client-side functionality for the Model Context Protocol.
|
||||
* Follows the 2024-11-05 basic protocol specification.
|
||||
*/
|
||||
|
||||
#include "mcp_client.h"
|
||||
|
@ -8,8 +11,8 @@
|
|||
|
||||
namespace mcp {
|
||||
|
||||
client::client(const std::string& host, int port)
|
||||
: host_(host), port_(port) {
|
||||
client::client(const std::string& host, int port, const json& capabilities)
|
||||
: host_(host), port_(port), capabilities_(capabilities) {
|
||||
|
||||
init_client();
|
||||
}
|
||||
|
@ -28,14 +31,43 @@ void client::init_client() {
|
|||
http_client_->set_write_timeout(timeout_seconds_, 0);
|
||||
}
|
||||
|
||||
void client::set_auth(const std::string& username, const std::string& password) {
|
||||
// Create the basic auth header
|
||||
std::string auth = username + ":" + password;
|
||||
std::string encoded = base64::encode(auth);
|
||||
auth_header_ = "Basic " + encoded;
|
||||
bool client::initialize(const std::string& client_name, const std::string& client_version) {
|
||||
// Create initialization request
|
||||
request req = request::create("initialize", {
|
||||
{"params", {
|
||||
{"protocolVersion", MCP_VERSION},
|
||||
{"capabilities", capabilities_}
|
||||
}},
|
||||
{"clientInfo", {
|
||||
{"name", client_name},
|
||||
{"version", client_version}
|
||||
}}
|
||||
});
|
||||
|
||||
try {
|
||||
// Send the request
|
||||
json result = send_jsonrpc(req);
|
||||
|
||||
// Store server capabilities
|
||||
server_capabilities_ = result["capabilities"];
|
||||
|
||||
// Send initialized notification
|
||||
request notification = request::create_notification("initialized");
|
||||
send_jsonrpc(notification);
|
||||
|
||||
return true;
|
||||
} catch (const std::exception& e) {
|
||||
// Initialization failed
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void client::set_auth_token(const std::string& token) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
auth_token_ = token;
|
||||
|
||||
// Add to default headers
|
||||
set_header("Authorization", auth_header_);
|
||||
set_header("Authorization", "Bearer " + auth_token_);
|
||||
}
|
||||
|
||||
void client::set_header(const std::string& key, const std::string& value) {
|
||||
|
@ -53,173 +85,101 @@ void client::set_timeout(int timeout_seconds) {
|
|||
http_client_->set_write_timeout(timeout_seconds_, 0);
|
||||
}
|
||||
|
||||
json client::get_server_info() {
|
||||
response res = get("/");
|
||||
if (res.status_code != 200) {
|
||||
throw mcp_exception(static_cast<error_code>(res.status_code),
|
||||
"Failed to get server info: " + res.body);
|
||||
}
|
||||
|
||||
try {
|
||||
return json::parse(res.body);
|
||||
} catch (const json::exception& e) {
|
||||
throw mcp_exception(error_code::internal_server_error,
|
||||
"Failed to parse server info: " + std::string(e.what()));
|
||||
}
|
||||
void client::set_capabilities(const json& capabilities) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
capabilities_ = capabilities;
|
||||
}
|
||||
|
||||
json client::get_tools() {
|
||||
response res = get("/tools");
|
||||
if (res.status_code != 200) {
|
||||
throw mcp_exception(static_cast<error_code>(res.status_code),
|
||||
"Failed to get tools: " + res.body);
|
||||
}
|
||||
response client::send_request(const std::string& method, const json& params) {
|
||||
request req = request::create(method, params);
|
||||
json result = send_jsonrpc(req);
|
||||
|
||||
try {
|
||||
return json::parse(res.body);
|
||||
} catch (const json::exception& e) {
|
||||
throw mcp_exception(error_code::internal_server_error,
|
||||
"Failed to parse tools: " + std::string(e.what()));
|
||||
}
|
||||
response res;
|
||||
res.jsonrpc = "2.0";
|
||||
res.id = req.id;
|
||||
res.result = result;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void client::send_notification(const std::string& method, const json& params) {
|
||||
request req = request::create_notification(method, params);
|
||||
send_jsonrpc(req);
|
||||
}
|
||||
|
||||
json client::get_server_capabilities() {
|
||||
return server_capabilities_;
|
||||
}
|
||||
|
||||
json client::call_tool(const std::string& tool_name, const json& parameters) {
|
||||
response res = post_json("/tools/" + tool_name, parameters);
|
||||
if (res.status_code != 200) {
|
||||
throw mcp_exception(static_cast<error_code>(res.status_code),
|
||||
"Tool execution failed: " + res.body);
|
||||
}
|
||||
|
||||
try {
|
||||
return json::parse(res.body);
|
||||
} catch (const json::exception& e) {
|
||||
throw mcp_exception(error_code::internal_server_error,
|
||||
"Failed to parse tool response: " + std::string(e.what()));
|
||||
}
|
||||
return send_request("tools/call", {
|
||||
{"name", tool_name},
|
||||
{"parameters", parameters}
|
||||
}).result;
|
||||
}
|
||||
|
||||
response client::get(const std::string& path,
|
||||
const std::map<std::string, std::string>& query_params) {
|
||||
return make_request(http_method::get, path, "", {}, query_params);
|
||||
}
|
||||
std::vector<tool> client::get_tools() {
|
||||
json tools_json = send_request("tools/list", {}).result;
|
||||
std::vector<tool> tools;
|
||||
|
||||
response client::post(const std::string& path,
|
||||
const std::string& body,
|
||||
const std::string& content_type) {
|
||||
std::map<std::string, std::string> headers;
|
||||
if (!body.empty()) {
|
||||
headers["Content-Type"] = content_type;
|
||||
}
|
||||
return make_request(http_method::post, path, body, headers);
|
||||
}
|
||||
if (tools_json.is_array()) {
|
||||
for (const auto& tool_json : tools_json) {
|
||||
tool t;
|
||||
t.name = tool_json["name"];
|
||||
t.description = tool_json["description"];
|
||||
|
||||
response client::post_json(const std::string& path, const json& json_body) {
|
||||
std::string body = json_body.dump();
|
||||
return post(path, body, content_type::json);
|
||||
}
|
||||
|
||||
response client::put(const std::string& path,
|
||||
const std::string& body,
|
||||
const std::string& content_type) {
|
||||
std::map<std::string, std::string> headers;
|
||||
if (!body.empty()) {
|
||||
headers["Content-Type"] = content_type;
|
||||
}
|
||||
return make_request(http_method::put, path, body, headers);
|
||||
}
|
||||
|
||||
response client::delete_request(const std::string& path) {
|
||||
return make_request(http_method::delete_, path);
|
||||
}
|
||||
|
||||
response client::make_request(http_method method,
|
||||
const std::string& path,
|
||||
const std::string& body,
|
||||
const std::map<std::string, std::string>& headers,
|
||||
const std::map<std::string, std::string>& query_params) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
|
||||
// Prepare the request
|
||||
httplib::Headers req_headers;
|
||||
|
||||
// Add default headers
|
||||
for (const auto& [key, value] : default_headers_) {
|
||||
req_headers.emplace(key, value);
|
||||
}
|
||||
|
||||
// Add custom headers
|
||||
for (const auto& [key, value] : headers) {
|
||||
req_headers.emplace(key, value);
|
||||
}
|
||||
|
||||
// Prepare query parameters
|
||||
std::string path_with_query = path;
|
||||
if (!query_params.empty()) {
|
||||
path_with_query += "?";
|
||||
bool first = true;
|
||||
for (const auto& [key, value] : query_params) {
|
||||
if (!first) {
|
||||
path_with_query += "&";
|
||||
if (tool_json.contains("parameters")) {
|
||||
t.parameters_schema = tool_json["parameters"];
|
||||
}
|
||||
|
||||
// URL encode the key and value
|
||||
auto encode = [](const std::string& s) {
|
||||
std::string encoded;
|
||||
for (char c : s) {
|
||||
if (std::isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') {
|
||||
encoded += c;
|
||||
} else if (c == ' ') {
|
||||
encoded += "+";
|
||||
} else {
|
||||
char buf[4];
|
||||
std::snprintf(buf, sizeof(buf), "%%%02X", static_cast<unsigned char>(c));
|
||||
encoded += buf;
|
||||
}
|
||||
}
|
||||
return encoded;
|
||||
};
|
||||
|
||||
path_with_query += encode(key) + "=" + encode(value);
|
||||
first = false;
|
||||
tools.push_back(t);
|
||||
}
|
||||
}
|
||||
|
||||
// Make the request
|
||||
httplib::Result result;
|
||||
|
||||
switch (method) {
|
||||
case http_method::get:
|
||||
result = http_client_->Get(path_with_query.c_str(), req_headers);
|
||||
break;
|
||||
case http_method::post:
|
||||
result = http_client_->Post(path_with_query.c_str(), req_headers, body, "");
|
||||
break;
|
||||
case http_method::put:
|
||||
result = http_client_->Put(path_with_query.c_str(), req_headers, body, "");
|
||||
break;
|
||||
case http_method::delete_:
|
||||
result = http_client_->Delete(path_with_query.c_str(), req_headers);
|
||||
break;
|
||||
case http_method::patch:
|
||||
result = http_client_->Patch(path_with_query.c_str(), req_headers, body, "");
|
||||
break;
|
||||
case http_method::head:
|
||||
result = http_client_->Head(path_with_query.c_str(), req_headers);
|
||||
break;
|
||||
case http_method::options:
|
||||
result = http_client_->Options(path_with_query.c_str(), req_headers);
|
||||
break;
|
||||
default:
|
||||
throw mcp_exception(error_code::method_not_allowed,
|
||||
"Unsupported HTTP method");
|
||||
}
|
||||
|
||||
// Process the result
|
||||
return process_response(result);
|
||||
return tools;
|
||||
}
|
||||
|
||||
response client::process_response(const httplib::Result& result) {
|
||||
response res;
|
||||
json client::get_resource_metadata(const std::string& resource_path) {
|
||||
return send_request("resources/metadata", {
|
||||
{"path", resource_path}
|
||||
}).result;
|
||||
}
|
||||
|
||||
json client::get_capabilities() {
|
||||
return capabilities_;
|
||||
}
|
||||
|
||||
json client::access_resource(const std::string& resource_path, const json& params) {
|
||||
json request_params = {
|
||||
{"path", resource_path}
|
||||
};
|
||||
|
||||
// Add any additional parameters
|
||||
for (auto it = params.begin(); it != params.end(); ++it) {
|
||||
request_params[it.key()] = it.value();
|
||||
}
|
||||
|
||||
return send_request("resources/access", request_params).result;
|
||||
}
|
||||
|
||||
json client::send_jsonrpc(const request& req) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
|
||||
// Convert request to JSON
|
||||
json req_json = req.to_json();
|
||||
std::string req_body = req_json.dump();
|
||||
|
||||
// Prepare headers
|
||||
httplib::Headers headers;
|
||||
headers.emplace("Content-Type", "application/json");
|
||||
|
||||
// Add default headers
|
||||
for (const auto& [key, value] : default_headers_) {
|
||||
headers.emplace(key, value);
|
||||
}
|
||||
|
||||
// Send the request
|
||||
auto result = http_client_->Post("/jsonrpc", headers, req_body, "application/json");
|
||||
|
||||
if (!result) {
|
||||
// Error occurred
|
||||
|
@ -227,29 +187,46 @@ response client::process_response(const httplib::Result& result) {
|
|||
|
||||
switch (err) {
|
||||
case httplib::Error::Connection:
|
||||
throw mcp_exception(error_code::service_unavailable, "Connection error");
|
||||
throw mcp_exception(error_code::server_error_start, "Connection error");
|
||||
case httplib::Error::Read:
|
||||
throw mcp_exception(error_code::internal_server_error, "Read error");
|
||||
throw mcp_exception(error_code::internal_error, "Read error");
|
||||
case httplib::Error::Write:
|
||||
throw mcp_exception(error_code::internal_server_error, "Write error");
|
||||
throw mcp_exception(error_code::internal_error, "Write error");
|
||||
case httplib::Error::ConnectionTimeout:
|
||||
throw mcp_exception(error_code::service_unavailable, "Timeout error");
|
||||
throw mcp_exception(error_code::server_error_start, "Timeout error");
|
||||
default:
|
||||
throw mcp_exception(error_code::internal_server_error,
|
||||
throw mcp_exception(error_code::internal_error,
|
||||
"HTTP client error: " + std::to_string(static_cast<int>(err)));
|
||||
}
|
||||
}
|
||||
|
||||
// Process successful response
|
||||
res.status_code = result->status;
|
||||
res.body = result->body;
|
||||
|
||||
// Copy headers
|
||||
for (const auto& [key, value] : result->headers) {
|
||||
res.headers[key] = value;
|
||||
// Check if it's a notification (no response expected)
|
||||
if (req.is_notification()) {
|
||||
return json::object();
|
||||
}
|
||||
|
||||
return res;
|
||||
// Parse response
|
||||
try {
|
||||
json res_json = json::parse(result->body);
|
||||
|
||||
// Check for error
|
||||
if (res_json.contains("error")) {
|
||||
int code = res_json["error"]["code"];
|
||||
std::string message = res_json["error"]["message"];
|
||||
|
||||
throw mcp_exception(static_cast<error_code>(code), message);
|
||||
}
|
||||
|
||||
// Return result
|
||||
if (res_json.contains("result")) {
|
||||
return res_json["result"];
|
||||
} else {
|
||||
return json::object();
|
||||
}
|
||||
} catch (const json::exception& e) {
|
||||
throw mcp_exception(error_code::parse_error,
|
||||
"Failed to parse JSON-RPC response: " + std::string(e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mcp
|
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
* @file mcp_protocol.cpp
|
||||
* @brief Implementation of the MCP protocol
|
||||
*
|
||||
* This file implements the core protocol functionality for the MCP protocol.
|
||||
* Follows the 2024-11-05 basic protocol specification.
|
||||
*/
|
||||
|
||||
#include "mcp_message.h"
|
||||
#include <random>
|
||||
#include <sstream>
|
||||
|
||||
namespace mcp {
|
||||
|
||||
// Implementation of any protocol-related functions
|
||||
|
||||
} // namespace mcp
|
|
@ -1,13 +0,0 @@
|
|||
/**
|
||||
* @file mcp_protocol.cpp
|
||||
* @brief Implementation of the Model Context Protocol core functionality
|
||||
*/
|
||||
|
||||
#include "mcp_protocol.h"
|
||||
|
||||
namespace mcp {
|
||||
|
||||
// Currently most functions are implemented as inline in the header
|
||||
// This file will be expanded as needed for non-inline implementations
|
||||
|
||||
} // namespace mcp
|
|
@ -1,6 +1,9 @@
|
|||
/**
|
||||
* @file mcp_resource.cpp
|
||||
* @brief Resource implementation for MCP
|
||||
*
|
||||
* This file implements the resource classes for the Model Context Protocol.
|
||||
* Follows the 2024-11-05 basic protocol specification.
|
||||
*/
|
||||
#include "mcp_resource.h"
|
||||
#include <filesystem>
|
||||
|
@ -18,12 +21,12 @@ file_resource::file_resource(const std::string& base_path)
|
|||
: base_path_(base_path) {
|
||||
// Ensure base path exists
|
||||
if (!fs::exists(base_path_)) {
|
||||
throw mcp_exception(error_code::internal_server_error,
|
||||
throw mcp_exception(error_code::internal_error,
|
||||
"Base path does not exist: " + base_path_);
|
||||
}
|
||||
}
|
||||
|
||||
json file_resource::metadata() const {
|
||||
json file_resource::get_metadata() const {
|
||||
return {
|
||||
{"type", "file_resource"},
|
||||
{"base_path", base_path_},
|
||||
|
@ -31,99 +34,80 @@ json file_resource::metadata() const {
|
|||
};
|
||||
}
|
||||
|
||||
response file_resource::handle_request(const request& req) {
|
||||
// Extract the relative path from the request
|
||||
std::string path = req.path;
|
||||
json file_resource::access(const json& params) const {
|
||||
// Extract the path from the parameters
|
||||
if (!params.contains("path")) {
|
||||
throw mcp_exception(error_code::invalid_params, "Missing 'path' parameter");
|
||||
}
|
||||
|
||||
std::string path = params["path"];
|
||||
|
||||
// Remove trailing slash if present
|
||||
if (!path.empty() && path.back() == '/') {
|
||||
path.pop_back();
|
||||
}
|
||||
|
||||
// Handle different HTTP methods
|
||||
if (req.method == http_method::get) {
|
||||
// Check if the path is a directory or file
|
||||
std::string full_path = base_path_ + path;
|
||||
if (fs::is_directory(full_path)) {
|
||||
// Handle different operations
|
||||
if (params.contains("operation")) {
|
||||
std::string operation = params["operation"];
|
||||
|
||||
if (operation == "read") {
|
||||
return read_file(path);
|
||||
} else if (operation == "write") {
|
||||
if (!params.contains("content")) {
|
||||
throw mcp_exception(error_code::invalid_params, "Missing 'content' parameter for write operation");
|
||||
}
|
||||
return write_file(path, params["content"]);
|
||||
} else if (operation == "delete") {
|
||||
return delete_file(path);
|
||||
} else if (operation == "list") {
|
||||
return list_directory(path);
|
||||
} else {
|
||||
return read_file(path);
|
||||
throw mcp_exception(error_code::invalid_params, "Invalid operation: " + operation);
|
||||
}
|
||||
} else if (req.method == http_method::post || req.method == http_method::put) {
|
||||
// Write file
|
||||
return write_file(path, req.body);
|
||||
} else if (req.method == http_method::delete_) {
|
||||
// Delete file
|
||||
return delete_file(path);
|
||||
}
|
||||
|
||||
// If we get here, the request is not supported
|
||||
response res;
|
||||
res.set_error(error_code::method_not_allowed,
|
||||
"Method not allowed for file resource");
|
||||
return res;
|
||||
// Default to read operation
|
||||
std::string full_path = base_path_ + path;
|
||||
if (fs::is_directory(full_path)) {
|
||||
return list_directory(path);
|
||||
} else {
|
||||
return read_file(path);
|
||||
}
|
||||
}
|
||||
|
||||
json file_resource::schema() const {
|
||||
return {
|
||||
{"type", "object"},
|
||||
{"properties", {
|
||||
{"path", {
|
||||
{"type", "string"},
|
||||
{"description", "Path to the file or directory"}
|
||||
}},
|
||||
{"content", {
|
||||
{"type", "string"},
|
||||
{"description", "File content (for write operations)"}
|
||||
}}
|
||||
}}
|
||||
};
|
||||
}
|
||||
|
||||
response file_resource::read_file(const std::string& path) {
|
||||
json file_resource::read_file(const std::string& path) const {
|
||||
std::string full_path = base_path_ + path;
|
||||
|
||||
// Check if file exists
|
||||
if (!fs::exists(full_path) || !fs::is_regular_file(full_path)) {
|
||||
response res;
|
||||
res.set_error(error_code::not_found, "File not found: " + path);
|
||||
return res;
|
||||
throw mcp_exception(error_code::invalid_params, "File not found: " + path);
|
||||
}
|
||||
|
||||
// Read file content
|
||||
std::ifstream file(full_path, std::ios::binary);
|
||||
if (!file) {
|
||||
response res;
|
||||
res.set_error(error_code::internal_server_error,
|
||||
"Failed to open file: " + path);
|
||||
return res;
|
||||
throw mcp_exception(error_code::internal_error,
|
||||
"Failed to open file: " + path);
|
||||
}
|
||||
|
||||
std::stringstream buffer;
|
||||
buffer << file.rdbuf();
|
||||
|
||||
// Create response
|
||||
response res;
|
||||
res.body = buffer.str();
|
||||
|
||||
// Set content type based on file extension
|
||||
// Get file info
|
||||
std::string content = buffer.str();
|
||||
std::string ext = fs::path(full_path).extension().string();
|
||||
if (ext == ".json") {
|
||||
res.headers["Content-Type"] = content_type::json;
|
||||
} else if (ext == ".txt") {
|
||||
res.headers["Content-Type"] = content_type::text;
|
||||
} else if (ext == ".jpg" || ext == ".jpeg") {
|
||||
res.headers["Content-Type"] = content_type::image_jpeg;
|
||||
} else if (ext == ".png") {
|
||||
res.headers["Content-Type"] = content_type::image_png;
|
||||
} else {
|
||||
res.headers["Content-Type"] = content_type::octet_stream;
|
||||
}
|
||||
|
||||
return res;
|
||||
return {
|
||||
{"path", path},
|
||||
{"content", content},
|
||||
{"size", content.size()},
|
||||
{"extension", ext},
|
||||
{"last_modified", fs::last_write_time(full_path).time_since_epoch().count()}
|
||||
};
|
||||
}
|
||||
|
||||
response file_resource::write_file(const std::string& path, const std::string& content) {
|
||||
json file_resource::write_file(const std::string& path, const std::string& content) const {
|
||||
std::string full_path = base_path_ + path;
|
||||
|
||||
// Create directories if they don't exist
|
||||
|
@ -132,74 +116,57 @@ response file_resource::write_file(const std::string& path, const std::string& c
|
|||
try {
|
||||
fs::create_directories(dir_path);
|
||||
} catch (const std::exception& e) {
|
||||
response res;
|
||||
res.set_error(error_code::internal_server_error,
|
||||
"Failed to create directory: " + std::string(e.what()));
|
||||
return res;
|
||||
throw mcp_exception(error_code::internal_error,
|
||||
"Failed to create directory: " + std::string(e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
// Write file content
|
||||
std::ofstream file(full_path, std::ios::binary);
|
||||
if (!file) {
|
||||
response res;
|
||||
res.set_error(error_code::internal_server_error,
|
||||
"Failed to open file for writing: " + path);
|
||||
return res;
|
||||
throw mcp_exception(error_code::internal_error,
|
||||
"Failed to open file for writing: " + path);
|
||||
}
|
||||
|
||||
file << content;
|
||||
|
||||
// Create response
|
||||
response res;
|
||||
res.set_json_body({
|
||||
return {
|
||||
{"success", true},
|
||||
{"message", "File written successfully"},
|
||||
{"path", path}
|
||||
});
|
||||
|
||||
return res;
|
||||
{"path", path},
|
||||
{"size", content.size()}
|
||||
};
|
||||
}
|
||||
|
||||
response file_resource::delete_file(const std::string& path) {
|
||||
json file_resource::delete_file(const std::string& path) const {
|
||||
std::string full_path = base_path_ + path;
|
||||
|
||||
// Check if file exists
|
||||
if (!fs::exists(full_path)) {
|
||||
response res;
|
||||
res.set_error(error_code::not_found, "File not found: " + path);
|
||||
return res;
|
||||
throw mcp_exception(error_code::invalid_params, "File not found: " + path);
|
||||
}
|
||||
|
||||
// Delete file
|
||||
try {
|
||||
fs::remove(full_path);
|
||||
} catch (const std::exception& e) {
|
||||
response res;
|
||||
res.set_error(error_code::internal_server_error,
|
||||
"Failed to delete file: " + std::string(e.what()));
|
||||
return res;
|
||||
throw mcp_exception(error_code::internal_error,
|
||||
"Failed to delete file: " + std::string(e.what()));
|
||||
}
|
||||
|
||||
// Create response
|
||||
response res;
|
||||
res.set_json_body({
|
||||
return {
|
||||
{"success", true},
|
||||
{"message", "File deleted successfully"},
|
||||
{"path", path}
|
||||
});
|
||||
|
||||
return res;
|
||||
};
|
||||
}
|
||||
|
||||
response file_resource::list_directory(const std::string& path) {
|
||||
json file_resource::list_directory(const std::string& path) const {
|
||||
std::string full_path = base_path_ + path;
|
||||
|
||||
// Check if directory exists
|
||||
if (!fs::exists(full_path) || !fs::is_directory(full_path)) {
|
||||
response res;
|
||||
res.set_error(error_code::not_found, "Directory not found: " + path);
|
||||
return res;
|
||||
throw mcp_exception(error_code::invalid_params, "Directory not found: " + path);
|
||||
}
|
||||
|
||||
// List directory contents
|
||||
|
@ -224,470 +191,67 @@ response file_resource::list_directory(const std::string& path) {
|
|||
entries.push_back(entry_json);
|
||||
}
|
||||
|
||||
// Create response
|
||||
response res;
|
||||
res.set_json_body({
|
||||
return {
|
||||
{"path", path},
|
||||
{"entries", entries}
|
||||
});
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// directory_resource implementation
|
||||
directory_resource::directory_resource(const std::string& base_path)
|
||||
: base_path_(base_path) {
|
||||
// Ensure base path exists
|
||||
if (!fs::exists(base_path_)) {
|
||||
throw mcp_exception(error_code::internal_server_error,
|
||||
"Base path does not exist: " + base_path_);
|
||||
}
|
||||
}
|
||||
|
||||
json directory_resource::metadata() const {
|
||||
return {
|
||||
{"type", "directory_resource"},
|
||||
{"base_path", base_path_},
|
||||
{"description", "Directory resource for managing directories"}
|
||||
};
|
||||
}
|
||||
|
||||
response directory_resource::handle_request(const request& req) {
|
||||
// Extract the relative path from the request
|
||||
std::string path = req.path;
|
||||
|
||||
// Remove trailing slash if present
|
||||
if (!path.empty() && path.back() == '/') {
|
||||
path.pop_back();
|
||||
}
|
||||
|
||||
// Handle different HTTP methods
|
||||
if (req.method == http_method::get) {
|
||||
// List directory
|
||||
return list_directory(path);
|
||||
} else if (req.method == http_method::post) {
|
||||
// Create directory
|
||||
return create_directory(path);
|
||||
} else if (req.method == http_method::delete_) {
|
||||
// Delete directory
|
||||
return delete_directory(path);
|
||||
}
|
||||
|
||||
// If we get here, the request is not supported
|
||||
response res;
|
||||
res.set_error(error_code::method_not_allowed,
|
||||
"Method not allowed for directory resource");
|
||||
return res;
|
||||
}
|
||||
|
||||
json directory_resource::schema() const {
|
||||
return {
|
||||
{"type", "object"},
|
||||
{"properties", {
|
||||
{"path", {
|
||||
{"type", "string"},
|
||||
{"description", "Path to the directory"}
|
||||
}}
|
||||
}}
|
||||
};
|
||||
}
|
||||
|
||||
response directory_resource::list_directory(const std::string& path) {
|
||||
std::string full_path = base_path_ + path;
|
||||
|
||||
// Check if directory exists
|
||||
if (!fs::exists(full_path) || !fs::is_directory(full_path)) {
|
||||
response res;
|
||||
res.set_error(error_code::not_found, "Directory not found: " + path);
|
||||
return res;
|
||||
}
|
||||
|
||||
// List directory contents
|
||||
json entries = json::array();
|
||||
|
||||
for (const auto& entry : fs::directory_iterator(full_path)) {
|
||||
if (entry.is_directory()) {
|
||||
std::string entry_path = entry.path().string();
|
||||
// Convert to relative path
|
||||
entry_path = entry_path.substr(base_path_.length());
|
||||
|
||||
entries.push_back({
|
||||
{"name", entry.path().filename().string()},
|
||||
{"path", entry_path}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Create response
|
||||
response res;
|
||||
res.set_json_body({
|
||||
{"path", path},
|
||||
{"directories", entries}
|
||||
});
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
response directory_resource::create_directory(const std::string& path) {
|
||||
std::string full_path = base_path_ + path;
|
||||
|
||||
// Check if directory already exists
|
||||
if (fs::exists(full_path)) {
|
||||
response res;
|
||||
res.set_error(error_code::conflict, "Directory already exists: " + path);
|
||||
return res;
|
||||
}
|
||||
|
||||
// Create directory
|
||||
try {
|
||||
fs::create_directories(full_path);
|
||||
} catch (const std::exception& e) {
|
||||
response res;
|
||||
res.set_error(error_code::internal_server_error,
|
||||
"Failed to create directory: " + std::string(e.what()));
|
||||
return res;
|
||||
}
|
||||
|
||||
// Create response
|
||||
response res;
|
||||
res.set_json_body({
|
||||
{"success", true},
|
||||
{"message", "Directory created successfully"},
|
||||
{"path", path}
|
||||
});
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
response directory_resource::delete_directory(const std::string& path) {
|
||||
std::string full_path = base_path_ + path;
|
||||
|
||||
// Check if directory exists
|
||||
if (!fs::exists(full_path) || !fs::is_directory(full_path)) {
|
||||
response res;
|
||||
res.set_error(error_code::not_found, "Directory not found: " + path);
|
||||
return res;
|
||||
}
|
||||
|
||||
// Delete directory
|
||||
try {
|
||||
fs::remove_all(full_path);
|
||||
} catch (const std::exception& e) {
|
||||
response res;
|
||||
res.set_error(error_code::internal_server_error,
|
||||
"Failed to delete directory: " + std::string(e.what()));
|
||||
return res;
|
||||
}
|
||||
|
||||
// Create response
|
||||
response res;
|
||||
res.set_json_body({
|
||||
{"success", true},
|
||||
{"message", "Directory deleted successfully"},
|
||||
{"path", path}
|
||||
});
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// api_resource implementation
|
||||
api_resource::api_resource(const std::string& name, const std::string& description)
|
||||
: name_(name), description_(description) {
|
||||
}
|
||||
|
||||
json api_resource::metadata() const {
|
||||
json endpoints_json = json::object();
|
||||
json api_resource::get_metadata() const {
|
||||
json endpoints = json::object();
|
||||
|
||||
for (const auto& [path, methods] : endpoints_) {
|
||||
json methods_json = json::object();
|
||||
|
||||
for (const auto& [method, endpoint] : methods) {
|
||||
methods_json[http_method_to_string(method)] = {
|
||||
{"description", endpoint.description},
|
||||
{"schema", endpoint.schema}
|
||||
};
|
||||
}
|
||||
|
||||
endpoints_json[path] = methods_json;
|
||||
for (const auto& [endpoint, info] : endpoints_) {
|
||||
endpoints[endpoint] = {
|
||||
{"description", info.description}
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
{"type", "api_resource"},
|
||||
{"name", name_},
|
||||
{"description", description_},
|
||||
{"endpoints", endpoints_json}
|
||||
{"endpoints", endpoints}
|
||||
};
|
||||
}
|
||||
|
||||
response api_resource::handle_request(const request& req) {
|
||||
// Extract the relative path from the request
|
||||
std::string path = req.path;
|
||||
|
||||
// Remove trailing slash if present
|
||||
if (!path.empty() && path.back() == '/') {
|
||||
path.pop_back();
|
||||
json api_resource::access(const json& params) const {
|
||||
// Extract the endpoint from the parameters
|
||||
if (!params.contains("endpoint")) {
|
||||
throw mcp_exception(error_code::invalid_params, "Missing 'endpoint' parameter");
|
||||
}
|
||||
|
||||
std::string endpoint = params["endpoint"];
|
||||
|
||||
// Find the endpoint handler
|
||||
auto path_it = endpoints_.find(path);
|
||||
if (path_it == endpoints_.end()) {
|
||||
response res;
|
||||
res.set_error(error_code::not_found, "Endpoint not found: " + path);
|
||||
return res;
|
||||
}
|
||||
|
||||
// Find the method handler
|
||||
auto method_it = path_it->second.find(req.method);
|
||||
if (method_it == path_it->second.end()) {
|
||||
response res;
|
||||
res.set_error(error_code::method_not_allowed,
|
||||
"Method not allowed for this endpoint");
|
||||
return res;
|
||||
auto it = endpoints_.find(endpoint);
|
||||
if (it == endpoints_.end()) {
|
||||
throw mcp_exception(error_code::invalid_params, "Endpoint not found: " + endpoint);
|
||||
}
|
||||
|
||||
// Call the handler
|
||||
try {
|
||||
return method_it->second.handler(req);
|
||||
return it->second.handler(params);
|
||||
} catch (const mcp_exception& e) {
|
||||
response res;
|
||||
res.set_error(e.code(), e.what());
|
||||
return res;
|
||||
throw; // Re-throw MCP exceptions
|
||||
} catch (const std::exception& e) {
|
||||
response res;
|
||||
res.set_error(error_code::internal_server_error,
|
||||
"Internal server error: " + std::string(e.what()));
|
||||
return res;
|
||||
throw mcp_exception(error_code::internal_error,
|
||||
"Error in endpoint handler: " + std::string(e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
json api_resource::schema() const {
|
||||
json schema_json = json::object();
|
||||
|
||||
for (const auto& [path, methods] : endpoints_) {
|
||||
json methods_json = json::object();
|
||||
|
||||
for (const auto& [method, endpoint] : methods) {
|
||||
methods_json[http_method_to_string(method)] = endpoint.schema;
|
||||
}
|
||||
|
||||
schema_json[path] = methods_json;
|
||||
}
|
||||
|
||||
return schema_json;
|
||||
}
|
||||
|
||||
void api_resource::register_handler(http_method method,
|
||||
const std::string& path,
|
||||
void api_resource::register_handler(const std::string& endpoint,
|
||||
handler_func handler,
|
||||
const std::string& description,
|
||||
const json& schema) {
|
||||
endpoint ep;
|
||||
ep.handler = handler;
|
||||
ep.description = description;
|
||||
ep.schema = schema;
|
||||
const std::string& description) {
|
||||
endpoint_info info;
|
||||
info.handler = handler;
|
||||
info.description = description;
|
||||
|
||||
endpoints_[path][method] = ep;
|
||||
endpoints_[endpoint] = info;
|
||||
}
|
||||
|
||||
// image_resource implementation
|
||||
image_resource::image_resource(const std::string& base_path)
|
||||
: base_path_(base_path) {
|
||||
// Ensure base path exists
|
||||
if (!fs::exists(base_path_)) {
|
||||
throw mcp_exception(error_code::internal_server_error,
|
||||
"Base path does not exist: " + base_path_);
|
||||
}
|
||||
}
|
||||
|
||||
json image_resource::metadata() const {
|
||||
return {
|
||||
{"type", "image_resource"},
|
||||
{"base_path", base_path_},
|
||||
{"description", "Image resource for managing images"}
|
||||
};
|
||||
}
|
||||
|
||||
response image_resource::handle_request(const request& req) {
|
||||
// Extract the relative path from the request
|
||||
std::string path = req.path;
|
||||
|
||||
// Remove trailing slash if present
|
||||
if (!path.empty() && path.back() == '/') {
|
||||
path.pop_back();
|
||||
}
|
||||
|
||||
// Check for resize operation
|
||||
bool is_resize = false;
|
||||
int width = 0, height = 0;
|
||||
|
||||
auto resize_pos = path.find("/resize/");
|
||||
if (resize_pos != std::string::npos) {
|
||||
is_resize = true;
|
||||
|
||||
// Extract the original path and resize dimensions
|
||||
std::string resize_params = path.substr(resize_pos + 8);
|
||||
path = path.substr(0, resize_pos);
|
||||
|
||||
// Parse resize parameters (format: width/height)
|
||||
auto dim_pos = resize_params.find('/');
|
||||
if (dim_pos != std::string::npos) {
|
||||
try {
|
||||
width = std::stoi(resize_params.substr(0, dim_pos));
|
||||
height = std::stoi(resize_params.substr(dim_pos + 1));
|
||||
} catch (const std::exception& e) {
|
||||
response res;
|
||||
res.set_error(error_code::invalid_request,
|
||||
"Invalid resize parameters");
|
||||
return res;
|
||||
}
|
||||
} else {
|
||||
response res;
|
||||
res.set_error(error_code::invalid_request,
|
||||
"Invalid resize parameters format (should be width/height)");
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle different HTTP methods
|
||||
if (req.method == http_method::get) {
|
||||
if (is_resize) {
|
||||
return resize_image(path, width, height);
|
||||
} else {
|
||||
return get_image(path);
|
||||
}
|
||||
} else if (req.method == http_method::post || req.method == http_method::put) {
|
||||
// Check if content is base64 encoded
|
||||
bool is_base64 = false;
|
||||
if (req.headers.find("Content-Transfer-Encoding") != req.headers.end() &&
|
||||
req.headers.at("Content-Transfer-Encoding") == "base64") {
|
||||
is_base64 = true;
|
||||
}
|
||||
|
||||
return upload_image(path, req.body, is_base64);
|
||||
}
|
||||
|
||||
// If we get here, the request is not supported
|
||||
response res;
|
||||
res.set_error(error_code::method_not_allowed,
|
||||
"Method not allowed for image resource");
|
||||
return res;
|
||||
}
|
||||
|
||||
json image_resource::schema() const {
|
||||
return {
|
||||
{"type", "object"},
|
||||
{"properties", {
|
||||
{"path", {
|
||||
{"type", "string"},
|
||||
{"description", "Path to the image"}
|
||||
}},
|
||||
{"content", {
|
||||
{"type", "string"},
|
||||
{"description", "Image content (for upload operations)"}
|
||||
}},
|
||||
{"width", {
|
||||
{"type", "integer"},
|
||||
{"description", "Width for resize operation"}
|
||||
}},
|
||||
{"height", {
|
||||
{"type", "integer"},
|
||||
{"description", "Height for resize operation"}
|
||||
}}
|
||||
}}
|
||||
};
|
||||
}
|
||||
|
||||
response image_resource::get_image(const std::string& path) {
|
||||
std::string full_path = base_path_ + path;
|
||||
|
||||
// Check if file exists
|
||||
if (!fs::exists(full_path) || !fs::is_regular_file(full_path)) {
|
||||
response res;
|
||||
res.set_error(error_code::not_found, "Image not found: " + path);
|
||||
return res;
|
||||
}
|
||||
|
||||
// Read file content
|
||||
std::ifstream file(full_path, std::ios::binary);
|
||||
if (!file) {
|
||||
response res;
|
||||
res.set_error(error_code::internal_server_error,
|
||||
"Failed to open image: " + path);
|
||||
return res;
|
||||
}
|
||||
|
||||
std::stringstream buffer;
|
||||
buffer << file.rdbuf();
|
||||
|
||||
// Create response
|
||||
response res;
|
||||
res.body = buffer.str();
|
||||
|
||||
// Set content type based on file extension
|
||||
std::string ext = fs::path(full_path).extension().string();
|
||||
if (ext == ".jpg" || ext == ".jpeg") {
|
||||
res.headers["Content-Type"] = content_type::image_jpeg;
|
||||
} else if (ext == ".png") {
|
||||
res.headers["Content-Type"] = content_type::image_png;
|
||||
} else {
|
||||
res.headers["Content-Type"] = content_type::octet_stream;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
response image_resource::upload_image(const std::string& path, const std::string& content, bool is_base64) {
|
||||
std::string full_path = base_path_ + path;
|
||||
|
||||
// Create directories if they don't exist
|
||||
fs::path dir_path = fs::path(full_path).parent_path();
|
||||
if (!fs::exists(dir_path)) {
|
||||
try {
|
||||
fs::create_directories(dir_path);
|
||||
} catch (const std::exception& e) {
|
||||
response res;
|
||||
res.set_error(error_code::internal_server_error,
|
||||
"Failed to create directory: " + std::string(e.what()));
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
// Write file content
|
||||
std::ofstream file(full_path, std::ios::binary);
|
||||
if (!file) {
|
||||
response res;
|
||||
res.set_error(error_code::internal_server_error,
|
||||
"Failed to open image for writing: " + path);
|
||||
return res;
|
||||
}
|
||||
|
||||
// If content is base64 encoded, decode it
|
||||
if (is_base64) {
|
||||
// Note: In a real implementation, you would decode the base64 content here
|
||||
// For simplicity, we're just writing the raw content
|
||||
file << content;
|
||||
} else {
|
||||
file << content;
|
||||
}
|
||||
|
||||
// Create response
|
||||
response res;
|
||||
res.set_json_body({
|
||||
{"success", true},
|
||||
{"message", "Image uploaded successfully"},
|
||||
{"path", path}
|
||||
});
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
response image_resource::resize_image(const std::string& path, int width, int height) {
|
||||
// Note: In a real implementation, you would use an image processing library
|
||||
// to resize the image. For simplicity, we're just returning an error.
|
||||
response res;
|
||||
res.set_error(error_code::internal_server_error,
|
||||
"Image resizing not implemented in this version");
|
||||
return res;
|
||||
}
|
||||
|
||||
} // namespace mcp
|
||||
} // namespace mcp
|
|
@ -1,6 +1,9 @@
|
|||
/**
|
||||
* @file mcp_server.cpp
|
||||
* @brief Implementation of the MCP server
|
||||
*
|
||||
* This file implements the server-side functionality for the Model Context Protocol.
|
||||
* Follows the 2024-11-05 basic protocol specification.
|
||||
*/
|
||||
|
||||
#include "mcp_server.h"
|
||||
|
@ -8,8 +11,7 @@
|
|||
namespace mcp {
|
||||
|
||||
server::server(const std::string& host, int port)
|
||||
: host_(host), port_(port), name_("MCP Server"),
|
||||
cors_enabled_(false), allowed_origins_("*") {
|
||||
: host_(host), port_(port), name_("MCP Server"), version_(MCP_VERSION) {
|
||||
|
||||
http_server_ = std::make_unique<httplib::Server>();
|
||||
}
|
||||
|
@ -23,47 +25,9 @@ bool server::start(bool blocking) {
|
|||
return true; // Already running
|
||||
}
|
||||
|
||||
// Mount handlers for common paths
|
||||
|
||||
// Root handler - returns server info
|
||||
http_server_->Get("/", [this](const httplib::Request& req, httplib::Response& res) {
|
||||
set_cors_headers(res);
|
||||
json info = get_server_info();
|
||||
res.set_content(info.dump(), "application/json");
|
||||
});
|
||||
|
||||
// Tools listing
|
||||
http_server_->Get("/tools", [this](const httplib::Request& req, httplib::Response& res) {
|
||||
set_cors_headers(res);
|
||||
json tools_json = get_tools();
|
||||
res.set_content(tools_json.dump(), "application/json");
|
||||
});
|
||||
|
||||
// General request handler for all other paths
|
||||
http_server_->set_mount_point("/", "");
|
||||
http_server_->Get(".*", [this](const httplib::Request& req, httplib::Response& res) {
|
||||
this->handle_request(req, res);
|
||||
});
|
||||
|
||||
http_server_->Post(".*", [this](const httplib::Request& req, httplib::Response& res) {
|
||||
this->handle_request(req, res);
|
||||
});
|
||||
|
||||
http_server_->Put(".*", [this](const httplib::Request& req, httplib::Response& res) {
|
||||
this->handle_request(req, res);
|
||||
});
|
||||
|
||||
http_server_->Delete(".*", [this](const httplib::Request& req, httplib::Response& res) {
|
||||
this->handle_request(req, res);
|
||||
});
|
||||
|
||||
http_server_->Patch(".*", [this](const httplib::Request& req, httplib::Response& res) {
|
||||
this->handle_request(req, res);
|
||||
});
|
||||
|
||||
http_server_->Options(".*", [this](const httplib::Request& req, httplib::Response& res) {
|
||||
set_cors_headers(res);
|
||||
res.status = 204; // No content
|
||||
// Set up JSON-RPC endpoint
|
||||
http_server_->Post("/jsonrpc", [this](const httplib::Request& req, httplib::Response& res) {
|
||||
this->handle_jsonrpc(req, res);
|
||||
});
|
||||
|
||||
// Start the server
|
||||
|
@ -109,232 +73,300 @@ bool server::is_running() const {
|
|||
return running_;
|
||||
}
|
||||
|
||||
void server::set_server_info(const std::string& name, const std::string& version) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
name_ = name;
|
||||
version_ = version;
|
||||
}
|
||||
|
||||
void server::set_capabilities(const json& capabilities) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
capabilities_ = capabilities;
|
||||
}
|
||||
|
||||
void server::register_method(const std::string& method, std::function<json(const json&)> handler) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
method_handlers_[method] = handler;
|
||||
}
|
||||
|
||||
void server::register_notification(const std::string& method, std::function<void(const json&)> handler) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
notification_handlers_[method] = handler;
|
||||
}
|
||||
|
||||
void server::register_resource(const std::string& path, std::shared_ptr<resource> resource) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
resources_[path] = resource;
|
||||
|
||||
// Register methods for resource access
|
||||
if (method_handlers_.find("resources/metadata") == method_handlers_.end()) {
|
||||
method_handlers_["resources/metadata"] = [this](const json& params) {
|
||||
if (!params.contains("path")) {
|
||||
throw mcp_exception(error_code::invalid_params, "Missing 'path' parameter");
|
||||
}
|
||||
|
||||
std::string path = params["path"];
|
||||
auto it = resources_.find(path);
|
||||
if (it == resources_.end()) {
|
||||
throw mcp_exception(error_code::invalid_params, "Resource not found: " + path);
|
||||
}
|
||||
|
||||
return it->second->get_metadata();
|
||||
};
|
||||
}
|
||||
|
||||
if (method_handlers_.find("resources/access") == method_handlers_.end()) {
|
||||
method_handlers_["resources/access"] = [this](const json& params) {
|
||||
if (!params.contains("path")) {
|
||||
throw mcp_exception(error_code::invalid_params, "Missing 'path' parameter");
|
||||
}
|
||||
|
||||
std::string path = params["path"];
|
||||
auto it = resources_.find(path);
|
||||
if (it == resources_.end()) {
|
||||
throw mcp_exception(error_code::invalid_params, "Resource not found: " + path);
|
||||
}
|
||||
|
||||
return it->second->access(params);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
void server::register_tool(const tool& tool, tool_handler handler) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
tools_[tool.name] = std::make_pair(tool, handler);
|
||||
|
||||
// Register a POST endpoint for the tool
|
||||
http_server_->Post("/tools/" + tool.name, [this, tool_name = tool.name](
|
||||
const httplib::Request& req, httplib::Response& res) {
|
||||
|
||||
set_cors_headers(res);
|
||||
|
||||
// Check if the tool exists
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
auto it = tools_.find(tool_name);
|
||||
if (it == tools_.end()) {
|
||||
res.status = 404;
|
||||
json error = {
|
||||
{"error", {
|
||||
{"code", 404},
|
||||
{"message", "Tool not found: " + tool_name}
|
||||
}}
|
||||
};
|
||||
res.set_content(error.dump(), "application/json");
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse the request body
|
||||
json params;
|
||||
try {
|
||||
if (!req.body.empty()) {
|
||||
params = json::parse(req.body);
|
||||
// Register methods for tool listing and calling
|
||||
if (method_handlers_.find("tools/list") == method_handlers_.end()) {
|
||||
method_handlers_["tools/list"] = [this](const json& params) {
|
||||
json tools_json = json::array();
|
||||
for (const auto& [name, tool_pair] : tools_) {
|
||||
tools_json.push_back(tool_pair.first.to_json());
|
||||
}
|
||||
} catch (const json::exception& e) {
|
||||
res.status = 400;
|
||||
json error = {
|
||||
{"error", {
|
||||
{"code", 400},
|
||||
{"message", "Invalid JSON: " + std::string(e.what())}
|
||||
}}
|
||||
};
|
||||
res.set_content(error.dump(), "application/json");
|
||||
return;
|
||||
}
|
||||
return tools_json;
|
||||
};
|
||||
}
|
||||
|
||||
// Execute the tool
|
||||
try {
|
||||
json result = it->second.second(params);
|
||||
res.set_content(result.dump(), "application/json");
|
||||
} catch (const std::exception& e) {
|
||||
res.status = 500;
|
||||
json error = {
|
||||
{"error", {
|
||||
{"code", 500},
|
||||
{"message", "Tool execution error: " + std::string(e.what())}
|
||||
}}
|
||||
};
|
||||
res.set_content(error.dump(), "application/json");
|
||||
}
|
||||
});
|
||||
if (method_handlers_.find("tools/call") == method_handlers_.end()) {
|
||||
method_handlers_["tools/call"] = [this](const json& params) {
|
||||
if (!params.contains("name")) {
|
||||
throw mcp_exception(error_code::invalid_params, "Missing 'name' parameter");
|
||||
}
|
||||
|
||||
std::string tool_name = params["name"];
|
||||
auto it = tools_.find(tool_name);
|
||||
if (it == tools_.end()) {
|
||||
throw mcp_exception(error_code::invalid_params, "Tool not found: " + tool_name);
|
||||
}
|
||||
|
||||
json tool_params = params.contains("parameters") ? params["parameters"] : json::object();
|
||||
return it->second.second(tool_params);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
json server::get_tools() const {
|
||||
std::vector<tool> server::get_tools() const {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
json tools_json = json::array();
|
||||
std::vector<tool> tools;
|
||||
|
||||
for (const auto& [name, tool_pair] : tools_) {
|
||||
tools_json.push_back(tool_pair.first.to_json());
|
||||
tools.push_back(tool_pair.first);
|
||||
}
|
||||
|
||||
return tools_json;
|
||||
return tools;
|
||||
}
|
||||
|
||||
json server::get_server_info() const {
|
||||
void server::set_auth_handler(std::function<bool(const std::string&)> handler) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
auth_handler_ = handler;
|
||||
}
|
||||
|
||||
json info = {
|
||||
void server::handle_jsonrpc(const httplib::Request& req, httplib::Response& res) {
|
||||
// Set response headers
|
||||
res.set_header("Content-Type", "application/json");
|
||||
|
||||
// Parse the request
|
||||
json req_json;
|
||||
try {
|
||||
req_json = json::parse(req.body);
|
||||
} catch (const json::exception& e) {
|
||||
// Invalid JSON
|
||||
json error_response = {
|
||||
{"jsonrpc", "2.0"},
|
||||
{"error", {
|
||||
{"code", static_cast<int>(error_code::parse_error)},
|
||||
{"message", "Parse error: " + std::string(e.what())}
|
||||
}},
|
||||
{"id", nullptr}
|
||||
};
|
||||
res.set_content(error_response.dump(), "application/json");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if it's a batch request
|
||||
if (req_json.is_array()) {
|
||||
// Batch request not supported yet
|
||||
json error_response = {
|
||||
{"jsonrpc", "2.0"},
|
||||
{"error", {
|
||||
{"code", static_cast<int>(error_code::invalid_request)},
|
||||
{"message", "Batch requests are not supported"}
|
||||
}},
|
||||
{"id", nullptr}
|
||||
};
|
||||
res.set_content(error_response.dump(), "application/json");
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert to request object
|
||||
request mcp_req;
|
||||
try {
|
||||
mcp_req.jsonrpc = req_json["jsonrpc"];
|
||||
mcp_req.method = req_json["method"];
|
||||
|
||||
if (req_json.contains("id")) {
|
||||
mcp_req.id = req_json["id"];
|
||||
}
|
||||
|
||||
if (req_json.contains("params")) {
|
||||
mcp_req.params = req_json["params"];
|
||||
}
|
||||
} catch (const json::exception& e) {
|
||||
// Invalid request
|
||||
json error_response = {
|
||||
{"jsonrpc", "2.0"},
|
||||
{"error", {
|
||||
{"code", static_cast<int>(error_code::invalid_request)},
|
||||
{"message", "Invalid request: " + std::string(e.what())}
|
||||
}},
|
||||
{"id", nullptr}
|
||||
};
|
||||
res.set_content(error_response.dump(), "application/json");
|
||||
return;
|
||||
}
|
||||
|
||||
// Process the request
|
||||
json result = process_request(mcp_req);
|
||||
res.set_content(result.dump(), "application/json");
|
||||
}
|
||||
|
||||
json server::process_request(const request& req) {
|
||||
// Check if it's a notification
|
||||
if (req.is_notification()) {
|
||||
// Process notification asynchronously
|
||||
std::thread([this, req]() {
|
||||
try {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
auto it = notification_handlers_.find(req.method);
|
||||
if (it != notification_handlers_.end()) {
|
||||
it->second(req.params);
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
// Log error but don't send response
|
||||
std::cerr << "Error processing notification: " << e.what() << std::endl;
|
||||
}
|
||||
}).detach();
|
||||
|
||||
// No response for notifications
|
||||
return json::object();
|
||||
}
|
||||
|
||||
// Handle method call
|
||||
try {
|
||||
// Special case for initialize
|
||||
if (req.method == "initialize") {
|
||||
return handle_initialize(req);
|
||||
}
|
||||
|
||||
// Look for registered method handler
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
auto it = method_handlers_.find(req.method);
|
||||
if (it != method_handlers_.end()) {
|
||||
// Call the handler
|
||||
json result = it->second(req.params);
|
||||
|
||||
// Create success response
|
||||
return response::create_success(req.id, result).to_json();
|
||||
}
|
||||
|
||||
// Method not found
|
||||
return response::create_error(
|
||||
req.id,
|
||||
error_code::method_not_found,
|
||||
"Method not found: " + req.method
|
||||
).to_json();
|
||||
} catch (const mcp_exception& e) {
|
||||
// MCP exception
|
||||
return response::create_error(
|
||||
req.id,
|
||||
e.code(),
|
||||
e.what()
|
||||
).to_json();
|
||||
} catch (const std::exception& e) {
|
||||
// Generic exception
|
||||
return response::create_error(
|
||||
req.id,
|
||||
error_code::internal_error,
|
||||
"Internal error: " + std::string(e.what())
|
||||
).to_json();
|
||||
}
|
||||
}
|
||||
|
||||
json server::handle_initialize(const request& req) {
|
||||
const json& params = req.params;
|
||||
|
||||
// Version negotiation
|
||||
if (!params["params"].contains("protocolVersion") || !params["params"]["protocolVersion"].is_string()) {
|
||||
return response::create_error(
|
||||
req.id,
|
||||
error_code::invalid_params,
|
||||
"Expected string for 'protocolVersion' parameter"
|
||||
).to_json();
|
||||
}
|
||||
|
||||
std::string requested_version = params["params"]["protocolVersion"].get<std::string>();
|
||||
|
||||
if (requested_version != MCP_VERSION) {
|
||||
return response::create_error(
|
||||
req.id,
|
||||
error_code::invalid_params,
|
||||
"Unsupported protocol version",
|
||||
{
|
||||
{"supported", MCP_VERSION},
|
||||
{"requested", req.params["protocolVersion"]}
|
||||
}
|
||||
).to_json();
|
||||
}
|
||||
|
||||
// Extract client info
|
||||
std::string client_name = "UnknownClient";
|
||||
std::string client_version = "UnknownVersion";
|
||||
|
||||
if (params.contains("clientInfo")) {
|
||||
if (params["clientInfo"].contains("name")) {
|
||||
client_name = params["clientInfo"]["name"];
|
||||
}
|
||||
if (params["clientInfo"].contains("version")) {
|
||||
client_version = params["clientInfo"]["version"];
|
||||
}
|
||||
}
|
||||
|
||||
// Log connection
|
||||
// std::cout << "Client connected: " << client_name << " " << client_version << std::endl;
|
||||
|
||||
// Return server info and capabilities
|
||||
json server_info = {
|
||||
{"name", name_},
|
||||
{"version", MCP_VERSION},
|
||||
{"resources", json::array()},
|
||||
{"tools_count", tools_.size()}
|
||||
{"version", version_}
|
||||
};
|
||||
|
||||
// Add resources info
|
||||
for (const auto& [path, resource] : resources_) {
|
||||
json res_info = {
|
||||
{"path", path},
|
||||
{"type", static_cast<int>(resource->type())},
|
||||
{"metadata", resource->metadata()}
|
||||
};
|
||||
info["resources"].push_back(res_info);
|
||||
}
|
||||
json result = {
|
||||
{"protocolVersion", MCP_VERSION},
|
||||
{"capabilities", capabilities_},
|
||||
{"serverInfo", server_info}
|
||||
};
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
void server::set_cors(bool enable, const std::string& allowed_origins) {
|
||||
cors_enabled_ = enable;
|
||||
allowed_origins_ = allowed_origins;
|
||||
}
|
||||
|
||||
void server::set_name(const std::string& name) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
name_ = name;
|
||||
}
|
||||
|
||||
void server::handle_request(const httplib::Request& req, httplib::Response& res) {
|
||||
set_cors_headers(res);
|
||||
|
||||
// Convert the httplib request to our internal request format
|
||||
request mcp_req = convert_request(req);
|
||||
|
||||
// Find a resource that matches the path
|
||||
std::shared_ptr<resource> resource_ptr = nullptr;
|
||||
std::string matched_path;
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
|
||||
// Look for an exact match first
|
||||
auto it = resources_.find(mcp_req.path);
|
||||
if (it != resources_.end()) {
|
||||
resource_ptr = it->second;
|
||||
matched_path = mcp_req.path;
|
||||
} else {
|
||||
// Look for a prefix match
|
||||
for (const auto& [path, res] : resources_) {
|
||||
if (mcp_req.path.find(path) == 0) {
|
||||
// This path is a prefix of the requested path
|
||||
if (matched_path.empty() || path.length() > matched_path.length()) {
|
||||
// Use the longest matching prefix
|
||||
resource_ptr = res;
|
||||
matched_path = path;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle the request
|
||||
response mcp_res;
|
||||
if (resource_ptr) {
|
||||
try {
|
||||
// Adjust the path to be relative to the resource path
|
||||
if (!matched_path.empty() && matched_path != "/") {
|
||||
mcp_req.path = mcp_req.path.substr(matched_path.length());
|
||||
// Ensure the path starts with a slash
|
||||
if (mcp_req.path.empty() || mcp_req.path[0] != '/') {
|
||||
mcp_req.path = "/" + mcp_req.path;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle the request
|
||||
mcp_res = resource_ptr->handle_request(mcp_req);
|
||||
} catch (const mcp_exception& e) {
|
||||
mcp_res.set_error(e.code(), e.what());
|
||||
} catch (const std::exception& e) {
|
||||
mcp_res.set_error(error_code::internal_server_error, e.what());
|
||||
}
|
||||
} else {
|
||||
// No resource found
|
||||
mcp_res.set_error(error_code::not_found, "Resource not found: " + mcp_req.path);
|
||||
}
|
||||
|
||||
// Apply the response
|
||||
apply_response(mcp_res, res);
|
||||
}
|
||||
|
||||
request server::convert_request(const httplib::Request& req) {
|
||||
request mcp_req;
|
||||
|
||||
// Set method
|
||||
mcp_req.method = string_to_http_method(req.method);
|
||||
|
||||
// Set path
|
||||
mcp_req.path = req.path;
|
||||
|
||||
// Set headers
|
||||
for (const auto& [key, value] : req.headers) {
|
||||
mcp_req.headers[key] = value;
|
||||
}
|
||||
|
||||
// Set query parameters
|
||||
for (const auto& [key, value] : req.params) {
|
||||
mcp_req.query_params[key] = value;
|
||||
}
|
||||
|
||||
// Set body
|
||||
mcp_req.body = req.body;
|
||||
|
||||
return mcp_req;
|
||||
}
|
||||
|
||||
void server::apply_response(const response& mcp_res, httplib::Response& http_res) {
|
||||
// Set status code
|
||||
http_res.status = mcp_res.status_code;
|
||||
|
||||
// Set headers
|
||||
for (const auto& [key, value] : mcp_res.headers) {
|
||||
http_res.set_header(key.c_str(), value.c_str());
|
||||
}
|
||||
|
||||
// Set body
|
||||
http_res.body = mcp_res.body;
|
||||
|
||||
// Set content type if not already set
|
||||
if (http_res.get_header_value("Content-Type").empty() && !mcp_res.body.empty()) {
|
||||
// Guess content type based on the response body
|
||||
if (mcp_res.body[0] == '{' || mcp_res.body[0] == '[') {
|
||||
http_res.set_header("Content-Type", "application/json");
|
||||
} else {
|
||||
http_res.set_header("Content-Type", "text/plain");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void server::set_cors_headers(httplib::Response& res) {
|
||||
if (cors_enabled_) {
|
||||
res.set_header("Access-Control-Allow-Origin", allowed_origins_.c_str());
|
||||
res.set_header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS");
|
||||
res.set_header("Access-Control-Allow-Headers", "Content-Type, Authorization");
|
||||
res.set_header("Access-Control-Allow-Credentials", "true");
|
||||
}
|
||||
return response::create_success(req.id, result).to_json();
|
||||
}
|
||||
|
||||
} // namespace mcp
|
|
@ -0,0 +1,164 @@
|
|||
/**
|
||||
* @file mcp_tool.cpp
|
||||
* @brief Implementation of the MCP tools
|
||||
*
|
||||
* This file implements the tool-related functionality for the MCP protocol.
|
||||
* Follows the 2024-11-05 basic protocol specification.
|
||||
*/
|
||||
|
||||
#include "mcp_tool.h"
|
||||
#include <random>
|
||||
#include <sstream>
|
||||
|
||||
namespace mcp {
|
||||
|
||||
// Implementation for tool_registry
|
||||
void tool_registry::register_tool(const tool& tool, tool_handler handler) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
tools_[tool.name] = std::make_pair(tool, handler);
|
||||
}
|
||||
|
||||
bool tool_registry::unregister_tool(const std::string& tool_name) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
return tools_.erase(tool_name) > 0;
|
||||
}
|
||||
|
||||
std::pair<tool, tool_handler>* tool_registry::get_tool(const std::string& tool_name) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
auto it = tools_.find(tool_name);
|
||||
if (it != tools_.end()) {
|
||||
return &(it->second);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<tool> tool_registry::get_all_tools() const {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
std::vector<tool> result;
|
||||
for (const auto& [name, tool_pair] : tools_) {
|
||||
result.push_back(tool_pair.first);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
json tool_registry::call_tool(const std::string& tool_name, const json& parameters) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
|
||||
auto it = tools_.find(tool_name);
|
||||
if (it == tools_.end()) {
|
||||
throw mcp_exception(error_code::method_not_found, "Tool not found: " + tool_name);
|
||||
}
|
||||
|
||||
try {
|
||||
return it->second.second(parameters);
|
||||
} catch (const std::exception& e) {
|
||||
throw mcp_exception(error_code::internal_error,
|
||||
"Tool execution failed: " + std::string(e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
// Implementation for tool_builder
|
||||
tool_builder::tool_builder(const std::string& name)
|
||||
: name_(name) {
|
||||
}
|
||||
|
||||
tool_builder& tool_builder::with_description(const std::string& description) {
|
||||
description_ = description;
|
||||
return *this;
|
||||
}
|
||||
|
||||
tool_builder& tool_builder::add_param(const std::string& name,
|
||||
const std::string& description,
|
||||
const std::string& type,
|
||||
bool required) {
|
||||
json param = {
|
||||
{"type", type},
|
||||
{"description", description}
|
||||
};
|
||||
|
||||
parameters_["properties"][name] = param;
|
||||
|
||||
if (required) {
|
||||
required_params_.push_back(name);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
tool_builder& tool_builder::with_string_param(const std::string& name,
|
||||
const std::string& description,
|
||||
bool required) {
|
||||
return add_param(name, description, "string", required);
|
||||
}
|
||||
|
||||
tool_builder& tool_builder::with_number_param(const std::string& name,
|
||||
const std::string& description,
|
||||
bool required) {
|
||||
return add_param(name, description, "number", required);
|
||||
}
|
||||
|
||||
tool_builder& tool_builder::with_boolean_param(const std::string& name,
|
||||
const std::string& description,
|
||||
bool required) {
|
||||
return add_param(name, description, "boolean", required);
|
||||
}
|
||||
|
||||
tool_builder& tool_builder::with_array_param(const std::string& name,
|
||||
const std::string& description,
|
||||
const std::string& item_type,
|
||||
bool required) {
|
||||
json param = {
|
||||
{"type", "array"},
|
||||
{"description", description},
|
||||
{"items", {
|
||||
{"type", item_type}
|
||||
}}
|
||||
};
|
||||
|
||||
parameters_["properties"][name] = param;
|
||||
|
||||
if (required) {
|
||||
required_params_.push_back(name);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
tool_builder& tool_builder::with_object_param(const std::string& name,
|
||||
const std::string& description,
|
||||
const json& properties,
|
||||
bool required) {
|
||||
json param = {
|
||||
{"type", "object"},
|
||||
{"description", description},
|
||||
{"properties", properties}
|
||||
};
|
||||
|
||||
parameters_["properties"][name] = param;
|
||||
|
||||
if (required) {
|
||||
required_params_.push_back(name);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
tool tool_builder::build() const {
|
||||
tool t;
|
||||
t.name = name_;
|
||||
t.description = description_;
|
||||
|
||||
// Create the parameters schema
|
||||
json schema = parameters_;
|
||||
schema["type"] = "object";
|
||||
|
||||
if (!required_params_.empty()) {
|
||||
schema["required"] = required_params_;
|
||||
}
|
||||
|
||||
t.parameters_schema = schema;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
} // namespace mcp
|
|
@ -1,229 +0,0 @@
|
|||
/**
|
||||
* @file mcp_tools.cpp
|
||||
* @brief Implementation of tool functionality for MCP
|
||||
*/
|
||||
|
||||
#include "mcp_tools.h"
|
||||
#include <random>
|
||||
#include <sstream>
|
||||
|
||||
namespace mcp {
|
||||
|
||||
// Implementation for tool_registry
|
||||
void tool_registry::register_tool(const tool& tool, tool_handler handler) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
tools_[tool.name] = std::make_pair(tool, handler);
|
||||
}
|
||||
|
||||
bool tool_registry::unregister_tool(const std::string& tool_name) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
return tools_.erase(tool_name) > 0;
|
||||
}
|
||||
|
||||
std::pair<tool, tool_handler>* tool_registry::get_tool(const std::string& tool_name) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
auto it = tools_.find(tool_name);
|
||||
if (it != tools_.end()) {
|
||||
return &(it->second);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<tool> tool_registry::get_all_tools() const {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
std::vector<tool> result;
|
||||
for (const auto& [name, tool_pair] : tools_) {
|
||||
result.push_back(tool_pair.first);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
json tool_registry::call_tool(const std::string& tool_name, const json& parameters) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
|
||||
auto it = tools_.find(tool_name);
|
||||
if (it == tools_.end()) {
|
||||
throw mcp_exception(error_code::not_found, "Tool not found: " + tool_name);
|
||||
}
|
||||
|
||||
try {
|
||||
return it->second.second(parameters);
|
||||
} catch (const std::exception& e) {
|
||||
throw mcp_exception(error_code::internal_server_error,
|
||||
"Tool execution failed: " + std::string(e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
// Implementation for tool_builder
|
||||
tool_builder::tool_builder(const std::string& name)
|
||||
: name_(name) {
|
||||
parameters_["type"] = "object";
|
||||
parameters_["properties"] = json::object();
|
||||
}
|
||||
|
||||
tool_builder& tool_builder::with_description(const std::string& description) {
|
||||
description_ = description;
|
||||
return *this;
|
||||
}
|
||||
|
||||
tool_builder& tool_builder::add_param(const std::string& name,
|
||||
const std::string& description,
|
||||
const std::string& type,
|
||||
bool required) {
|
||||
parameters_["properties"][name] = {
|
||||
{"type", type},
|
||||
{"description", description}
|
||||
};
|
||||
|
||||
if (required) {
|
||||
required_params_.push_back(name);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
tool_builder& tool_builder::with_string_param(const std::string& name,
|
||||
const std::string& description,
|
||||
bool required) {
|
||||
return add_param(name, description, "string", required);
|
||||
}
|
||||
|
||||
tool_builder& tool_builder::with_number_param(const std::string& name,
|
||||
const std::string& description,
|
||||
bool required) {
|
||||
return add_param(name, description, "number", required);
|
||||
}
|
||||
|
||||
tool_builder& tool_builder::with_boolean_param(const std::string& name,
|
||||
const std::string& description,
|
||||
bool required) {
|
||||
return add_param(name, description, "boolean", required);
|
||||
}
|
||||
|
||||
tool_builder& tool_builder::with_array_param(const std::string& name,
|
||||
const std::string& description,
|
||||
const std::string& item_type,
|
||||
bool required) {
|
||||
json& prop = parameters_["properties"][name];
|
||||
prop["type"] = "array";
|
||||
prop["description"] = description;
|
||||
prop["items"] = {{"type", item_type}};
|
||||
|
||||
if (required) {
|
||||
required_params_.push_back(name);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
tool_builder& tool_builder::with_object_param(const std::string& name,
|
||||
const std::string& description,
|
||||
const json& properties,
|
||||
bool required) {
|
||||
json& prop = parameters_["properties"][name];
|
||||
prop["type"] = "object";
|
||||
prop["description"] = description;
|
||||
prop["properties"] = properties;
|
||||
|
||||
if (required) {
|
||||
required_params_.push_back(name);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
tool tool_builder::build() const {
|
||||
tool result;
|
||||
result.name = name_;
|
||||
result.description = description_;
|
||||
result.parameters_schema = parameters_;
|
||||
|
||||
// Add required parameters if any
|
||||
if (!required_params_.empty()) {
|
||||
result.parameters_schema["required"] = required_params_;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Initialize the static ID counter for workflow steps
|
||||
int workflow_step::next_id_ = 1;
|
||||
|
||||
// Implementation for workflow_step
|
||||
workflow_step::workflow_step(const std::string& tool_name, const json& parameters)
|
||||
: tool_name_(tool_name), parameters_(parameters) {
|
||||
|
||||
// Generate a unique ID for this step
|
||||
std::stringstream ss;
|
||||
ss << "step_" << next_id_++;
|
||||
id_ = ss.str();
|
||||
}
|
||||
|
||||
json workflow_step::execute(json& context) const {
|
||||
// Call the tool with parameters
|
||||
json result = tool_registry::instance().call_tool(tool_name_, parameters_);
|
||||
|
||||
// Store the result in the context
|
||||
context["results"][id_] = result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Implementation for workflow
|
||||
workflow::workflow(const std::string& name, const std::string& description)
|
||||
: name_(name), description_(description) {
|
||||
}
|
||||
|
||||
workflow::workflow()
|
||||
: name_(""), description_("") {
|
||||
}
|
||||
|
||||
workflow& workflow::add_step(const workflow_step& step) {
|
||||
steps_.push_back(step);
|
||||
return *this;
|
||||
}
|
||||
|
||||
workflow& workflow::add_tool_call(const std::string& tool_name, const json& parameters) {
|
||||
workflow_step step(tool_name, parameters);
|
||||
return add_step(step);
|
||||
}
|
||||
|
||||
json workflow::execute(const json& initial_context) const {
|
||||
json context = initial_context;
|
||||
|
||||
// Initialize the results object if it doesn't exist
|
||||
if (!context.contains("results")) {
|
||||
context["results"] = json::object();
|
||||
}
|
||||
|
||||
// Execute each step
|
||||
for (const workflow_step& step : steps_) {
|
||||
try {
|
||||
step.execute(context);
|
||||
} catch (const std::exception& e) {
|
||||
// Store the error in the context
|
||||
context["errors"][step.id()] = e.what();
|
||||
|
||||
// Still continue with the next steps
|
||||
}
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
// Implementation for agent
|
||||
agent::agent(const std::string& name)
|
||||
: name_(name) {
|
||||
context_ = json::object();
|
||||
}
|
||||
|
||||
json agent::call_tool(const std::string& tool_name, const json& parameters) {
|
||||
return tool_registry::instance().call_tool(tool_name, parameters);
|
||||
}
|
||||
|
||||
json agent::execute_workflow(const workflow& workflow, const json& initial_context) {
|
||||
context_ = workflow.execute(initial_context);
|
||||
return context_;
|
||||
}
|
||||
|
||||
} // namespace mcp
|
|
@ -1,394 +0,0 @@
|
|||
/**
|
||||
* @file mcp_workflow_resource.cpp
|
||||
* @brief Implementation of the workflow resource for MCP
|
||||
*/
|
||||
|
||||
#include "mcp_workflow_resource.h"
|
||||
|
||||
namespace mcp {
|
||||
|
||||
// workflow_resource implementation
|
||||
workflow_resource::workflow_resource(const std::string& name)
|
||||
: name_(name) {
|
||||
}
|
||||
|
||||
json workflow_resource::metadata() const {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
|
||||
json metadata = {
|
||||
{"name", name_},
|
||||
{"description", "Workflow management resource"},
|
||||
{"workflow_count", workflows_.size()},
|
||||
{"workflows", json::array()}
|
||||
};
|
||||
|
||||
for (const auto& [name, wf] : workflows_) {
|
||||
metadata["workflows"].push_back({
|
||||
{"name", name},
|
||||
{"description", wf.description()},
|
||||
{"steps_count", wf.steps().size()}
|
||||
});
|
||||
}
|
||||
|
||||
return metadata;
|
||||
}
|
||||
|
||||
response workflow_resource::handle_request(const request& req) {
|
||||
// Route the request to the appropriate handler based on the path and method
|
||||
std::string path = req.path;
|
||||
|
||||
// Remove trailing slash if present
|
||||
if (!path.empty() && path.back() == '/') {
|
||||
path.pop_back();
|
||||
}
|
||||
|
||||
// Root path - list all workflows
|
||||
if (path.empty() || path == "/") {
|
||||
if (req.method == http_method::get) {
|
||||
return list_workflows(req);
|
||||
} else if (req.method == http_method::post) {
|
||||
return create_workflow(req);
|
||||
}
|
||||
} else {
|
||||
// Extract workflow name from path
|
||||
// The path format is expected to be /<workflow_name>[/execute]
|
||||
std::string workflow_name;
|
||||
bool is_execute = false;
|
||||
|
||||
// Check if the path ends with /execute
|
||||
if (path.length() > 8 && path.substr(path.length() - 8) == "/execute") {
|
||||
workflow_name = path.substr(1, path.length() - 9);
|
||||
is_execute = true;
|
||||
} else {
|
||||
workflow_name = path.substr(1); // Remove leading slash
|
||||
}
|
||||
|
||||
if (is_execute) {
|
||||
// Execute workflow
|
||||
if (req.method == http_method::post) {
|
||||
return execute_workflow(req, workflow_name);
|
||||
}
|
||||
} else {
|
||||
// Workflow-specific operations
|
||||
if (req.method == http_method::get) {
|
||||
return get_workflow_details(req, workflow_name);
|
||||
} else if (req.method == http_method::put) {
|
||||
return update_workflow(req, workflow_name);
|
||||
} else if (req.method == http_method::delete_) {
|
||||
return delete_workflow(req, workflow_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we get here, the request is not supported
|
||||
response res;
|
||||
res.set_error(error_code::method_not_allowed,
|
||||
"Method not allowed for this path");
|
||||
return res;
|
||||
}
|
||||
|
||||
json workflow_resource::schema() const {
|
||||
return {
|
||||
{"type", "object"},
|
||||
{"properties", {
|
||||
{"name", {
|
||||
{"type", "string"},
|
||||
{"description", "Workflow name"}
|
||||
}},
|
||||
{"description", {
|
||||
{"type", "string"},
|
||||
{"description", "Workflow description"}
|
||||
}},
|
||||
{"steps", {
|
||||
{"type", "array"},
|
||||
{"description", "Workflow steps"},
|
||||
{"items", {
|
||||
{"type", "object"},
|
||||
{"properties", {
|
||||
{"tool_name", {
|
||||
{"type", "string"},
|
||||
{"description", "Tool name"}
|
||||
}},
|
||||
{"parameters", {
|
||||
{"type", "object"},
|
||||
{"description", "Tool parameters"}
|
||||
}}
|
||||
}}
|
||||
}}
|
||||
}}
|
||||
}},
|
||||
{"required", {"name", "steps"}}
|
||||
};
|
||||
}
|
||||
|
||||
void workflow_resource::register_workflow(const workflow& workflow) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
workflows_.insert(std::make_pair(workflow.name(), workflow));
|
||||
}
|
||||
|
||||
bool workflow_resource::unregister_workflow(const std::string& name) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
return workflows_.erase(name) > 0;
|
||||
}
|
||||
|
||||
const workflow* workflow_resource::get_workflow(const std::string& name) const {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
auto it = workflows_.find(name);
|
||||
if (it != workflows_.end()) {
|
||||
return &(it->second);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<std::string> workflow_resource::get_workflow_names() const {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
std::vector<std::string> names;
|
||||
for (const auto& [name, _] : workflows_) {
|
||||
names.push_back(name);
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
response workflow_resource::list_workflows(const request& req) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
|
||||
json workflows_json = json::array();
|
||||
|
||||
for (const auto& [name, wf] : workflows_) {
|
||||
json workflow_json = {
|
||||
{"name", name},
|
||||
{"description", wf.description()},
|
||||
{"steps_count", wf.steps().size()}
|
||||
};
|
||||
workflows_json.push_back(workflow_json);
|
||||
}
|
||||
|
||||
response res;
|
||||
res.set_json_body(workflows_json);
|
||||
return res;
|
||||
}
|
||||
|
||||
response workflow_resource::get_workflow_details(const request& req,
|
||||
const std::string& workflow_name) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
|
||||
auto it = workflows_.find(workflow_name);
|
||||
if (it == workflows_.end()) {
|
||||
response res;
|
||||
res.set_error(error_code::not_found, "Workflow not found: " + workflow_name);
|
||||
return res;
|
||||
}
|
||||
|
||||
const workflow& wf = it->second;
|
||||
|
||||
// Convert steps to JSON
|
||||
json steps_json = json::array();
|
||||
for (const auto& step : wf.steps()) {
|
||||
json step_json = {
|
||||
{"id", step.id()},
|
||||
{"tool_name", step.tool_name()},
|
||||
{"parameters", step.parameters()}
|
||||
};
|
||||
steps_json.push_back(step_json);
|
||||
}
|
||||
|
||||
json workflow_json = {
|
||||
{"name", wf.name()},
|
||||
{"description", wf.description()},
|
||||
{"steps", steps_json}
|
||||
};
|
||||
|
||||
response res;
|
||||
res.set_json_body(workflow_json);
|
||||
return res;
|
||||
}
|
||||
|
||||
response workflow_resource::create_workflow(const request& req) {
|
||||
// Parse the request body
|
||||
json body;
|
||||
try {
|
||||
body = req.json_body();
|
||||
} catch (const mcp_exception& e) {
|
||||
response res;
|
||||
res.set_error(e.code(), e.what());
|
||||
return res;
|
||||
}
|
||||
|
||||
// Validate required fields
|
||||
if (!body.contains("name") || !body["name"].is_string() ||
|
||||
!body.contains("steps") || !body["steps"].is_array()) {
|
||||
response res;
|
||||
res.set_error(error_code::invalid_request,
|
||||
"Missing required fields: name (string) and steps (array)");
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string name = body["name"];
|
||||
std::string description = body.value("description", "");
|
||||
|
||||
// Create a new workflow
|
||||
workflow wf(name, description);
|
||||
|
||||
// Add steps
|
||||
for (const auto& step_json : body["steps"]) {
|
||||
if (!step_json.contains("tool_name") || !step_json["tool_name"].is_string()) {
|
||||
response res;
|
||||
res.set_error(error_code::invalid_request,
|
||||
"Each step must have a tool_name (string)");
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string tool_name = step_json["tool_name"];
|
||||
json parameters = step_json.value("parameters", json::object());
|
||||
|
||||
wf.add_tool_call(tool_name, parameters);
|
||||
}
|
||||
|
||||
// Register the workflow
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
|
||||
// Check if a workflow with this name already exists
|
||||
if (workflows_.find(name) != workflows_.end()) {
|
||||
response res;
|
||||
res.set_error(error_code::conflict,
|
||||
"A workflow with this name already exists");
|
||||
return res;
|
||||
}
|
||||
|
||||
workflows_.insert(std::make_pair(name, wf));
|
||||
}
|
||||
|
||||
// Return the created workflow
|
||||
response res;
|
||||
res.status_code = 201; // Created
|
||||
res.set_json_body({
|
||||
{"name", wf.name()},
|
||||
{"description", wf.description()},
|
||||
{"steps_count", wf.steps().size()}
|
||||
});
|
||||
return res;
|
||||
}
|
||||
|
||||
response workflow_resource::update_workflow(const request& req,
|
||||
const std::string& workflow_name) {
|
||||
// Parse the request body
|
||||
json body;
|
||||
try {
|
||||
body = req.json_body();
|
||||
} catch (const mcp_exception& e) {
|
||||
response res;
|
||||
res.set_error(e.code(), e.what());
|
||||
return res;
|
||||
}
|
||||
|
||||
// Check if the workflow exists
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
if (workflows_.find(workflow_name) == workflows_.end()) {
|
||||
response res;
|
||||
res.set_error(error_code::not_found, "Workflow not found: " + workflow_name);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
// Create an updated workflow
|
||||
std::string description = body.value("description", "");
|
||||
workflow wf(workflow_name, description);
|
||||
|
||||
// Add steps if present in the request
|
||||
if (body.contains("steps") && body["steps"].is_array()) {
|
||||
for (const auto& step_json : body["steps"]) {
|
||||
if (!step_json.contains("tool_name") || !step_json["tool_name"].is_string()) {
|
||||
response res;
|
||||
res.set_error(error_code::invalid_request,
|
||||
"Each step must have a tool_name (string)");
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string tool_name = step_json["tool_name"];
|
||||
json parameters = step_json.value("parameters", json::object());
|
||||
|
||||
wf.add_tool_call(tool_name, parameters);
|
||||
}
|
||||
}
|
||||
|
||||
// Update the workflow
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
workflows_.insert(std::make_pair(workflow_name, wf));
|
||||
}
|
||||
|
||||
// Return the updated workflow
|
||||
response res;
|
||||
res.set_json_body({
|
||||
{"name", wf.name()},
|
||||
{"description", wf.description()},
|
||||
{"steps_count", wf.steps().size()}
|
||||
});
|
||||
return res;
|
||||
}
|
||||
|
||||
response workflow_resource::delete_workflow(const request& req,
|
||||
const std::string& workflow_name) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
|
||||
auto it = workflows_.find(workflow_name);
|
||||
if (it == workflows_.end()) {
|
||||
response res;
|
||||
res.set_error(error_code::not_found, "Workflow not found: " + workflow_name);
|
||||
return res;
|
||||
}
|
||||
|
||||
workflows_.erase(it);
|
||||
|
||||
response res;
|
||||
res.status_code = 204; // No Content
|
||||
return res;
|
||||
}
|
||||
|
||||
response workflow_resource::execute_workflow(const request& req,
|
||||
const std::string& workflow_name) {
|
||||
// Parse the request body
|
||||
json context;
|
||||
try {
|
||||
json body = req.json_body();
|
||||
context = body.value("context", json::object());
|
||||
} catch (const mcp_exception& e) {
|
||||
response res;
|
||||
res.set_error(e.code(), e.what());
|
||||
return res;
|
||||
}
|
||||
|
||||
// Get the workflow
|
||||
workflow wf(workflow_name);
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
|
||||
auto it = workflows_.find(workflow_name);
|
||||
if (it == workflows_.end()) {
|
||||
response res;
|
||||
res.set_error(error_code::not_found, "Workflow not found: " + workflow_name);
|
||||
return res;
|
||||
}
|
||||
|
||||
wf = it->second;
|
||||
}
|
||||
|
||||
// Execute the workflow
|
||||
json result;
|
||||
try {
|
||||
result = wf.execute(context);
|
||||
} catch (const std::exception& e) {
|
||||
response res;
|
||||
res.set_error(error_code::internal_server_error,
|
||||
"Workflow execution failed: " + std::string(e.what()));
|
||||
return res;
|
||||
}
|
||||
|
||||
// Return the result
|
||||
response res;
|
||||
res.set_json_body(result);
|
||||
return res;
|
||||
}
|
||||
} // namespace mcp
|
Loading…
Reference in New Issue