MCP服务器组件

一个实现模型上下文协议(MCP)服务器的ESP32组件,为AI应用提供与ESP32设备集成的标准化方式。

  • by 0x1abin
  • C
  • 本地部署
  • 4 星标
  • 更新于
在 GitHub 查看 0x1abin/esp-mcp-server

使用说明

ESP32 MCP服务器组件

中文文档 | 英语

ESP32组件实现了 模型上下文协议(MCP) 服务器,为AI应用程序与ESP32设备集成提供了一种标准化的方式。此组件使您的ESP32能够公开AI代理和应用程序可以发现和使用的工具和资源。

🌟 特性

  • 🚀 简单API:用于注册工具和资源的干净、直观的界面
  • 🔧 动态注册:在运行时注册工具和资源
  • 📦 模块化设计:独立组件,易于集成到现有项目中
  • 🌐 HTTP传输:JSON-RPC 2.0通过HTTP实现最大兼容性
  • 🔄 URI跟URI模板:支持参数化资源URI(例如。, sensor://{type}/{id})
  • 📊 实时监控:内置服务器统计和运行状况监控
  • 🛡️ 内存安全:自动内存管理和清理
  • ✅ 架构验证:使用JSON模式进行内置参数验证(类似于Zod)
  • 🎯 符合MCP标准:完全符合MCP规范2025-06-18

🏗️ 建筑

ESP32 MCP服务器遵循标准MCP架构:

┌─────────────────┐    HTTP/JSON-RPC    ┌─────────────────┐
│   MCP Client    │ ◄─────────────────► │  ESP32 MCP      │
│  (AI Agent)     │                     │    Server       │
└─────────────────┘                     └─────────────────┘
                                               │
                                        ┌─────────────────┐
                                        │   Your ESP32    │
                                        │   Application   │
                                        │  (Tools & Data) │
                                        └─────────────────┘

📦 安装

使用ESP组件注册表(推荐)

idf.py add-dependency "0x1abin/esp_mcp_server"

手动安装

  1. 将此存储库克隆到项目的 components 目录:
cd your_project/components
git clone https://github.com/0x1abin/esp-mcp-server.git esp_mcp_server
  1. 将组件包含在您的主组件中 CMakeLists.txt:
idf_component_register(
    SRCS "main.c"
    INCLUDE_DIRS "."
    REQUIRES esp_mcp_server
)

🚀 快速开始

基本服务器设置

#include "esp_mcp_server.h"

// Tool handler function
static cJSON* echo_tool_handler(const cJSON *arguments, void *user_data) {
    cJSON *message = cJSON_GetObjectItem(arguments, "message");
    
    cJSON *result = cJSON_CreateObject();
    cJSON *content_array = cJSON_CreateArray();
    cJSON *content = cJSON_CreateObject();
    
    cJSON_AddStringToObject(content, "type", "text");
    cJSON_AddStringToObject(content, "text", message->valuestring);
    
    cJSON_AddItemToArray(content_array, content);
    cJSON_AddItemToObject(result, "content", content_array);
    
    return result;
}

void app_main(void) {
    // Initialize WiFi (using ESP-IDF examples common)
    ESP_ERROR_CHECK(nvs_flash_init());
    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());
    ESP_ERROR_CHECK(example_connect());
    
    // Configure MCP server
    esp_mcp_server_config_t config = ESP_MCP_SERVER_DEFAULT_CONFIG();
    config.port = 80;
    config.server_name = "ESP32 MCP Server";
    config.server_version = "1.0.0";
    
    // Initialize server
    esp_mcp_server_handle_t server;
    ESP_ERROR_CHECK(esp_mcp_server_init(&config, &server));
    
    // Create input schema for validation
    cJSON *schema = schema_builder_create_object();
    schema_builder_add_string(schema, "message", "Message to echo", true);
    
    // Register echo tool
    esp_mcp_tool_config_t tool_config = {
        .name = "echo",
        .description = "Echoes back the provided message",
        .input_schema = schema,
        .handler = echo_tool_handler,
        .user_data = NULL
    };
    ESP_ERROR_CHECK(esp_mcp_server_register_tool(server, &tool_config));
    
    // Start the server
    ESP_ERROR_CHECK(esp_mcp_server_start(server));
    
    ESP_LOGI("MAIN", "MCP Server started on port %d", config.port);
}

GPIO控制高级示例

// GPIO control tool with schema validation
static cJSON* gpio_control_handler(const cJSON *arguments, void *user_data) {
    cJSON *pin = cJSON_GetObjectItem(arguments, "pin");
    cJSON *state = cJSON_GetObjectItem(arguments, "state");
    
    // SDK layer guarantees parameters are validated
    int gpio_num = pin->valueint;
    bool gpio_state = cJSON_IsTrue(state);
    
    gpio_set_level(gpio_num, gpio_state ? 1 : 0);
    
    cJSON *result = cJSON_CreateObject();
    cJSON *content_array = cJSON_CreateArray();
    cJSON *content = cJSON_CreateObject();
    
    cJSON_AddStringToObject(content, "type", "text");
    
    char response[100];
    snprintf(response, sizeof(response), "GPIO %d set to %s", 
             gpio_num, gpio_state ? "HIGH" : "LOW");
    cJSON_AddStringToObject(content, "text", response);
    
    cJSON_AddItemToArray(content_array, content);
    cJSON_AddItemToObject(result, "content", content_array);
    
    return result;
}

// Register GPIO control tool with schema validation
cJSON *gpio_schema = schema_builder_create_object();
schema_builder_add_integer(gpio_schema, "pin", "GPIO pin number", 0, 39, true);
schema_builder_add_boolean(gpio_schema, "state", "GPIO state (true=HIGH, false=LOW)", true);

esp_mcp_tool_config_t gpio_tool = {
    .name = "gpio_control",
    .description = "Control ESP32 GPIO pins",
    .input_schema = gpio_schema,
    .handler = gpio_control_handler,
    .user_data = NULL
};
ESP_ERROR_CHECK(esp_mcp_server_register_tool(server, &gpio_tool));

🔧 api参考

服务器生命周期

// Initialize server (does not start HTTP server)
esp_err_t esp_mcp_server_init(const esp_mcp_server_config_t *config, 
                              esp_mcp_server_handle_t *server_handle);

// Start HTTP server after registering tools/resources
esp_err_t esp_mcp_server_start(esp_mcp_server_handle_t server_handle);

// Stop HTTP server (can be restarted later)
esp_err_t esp_mcp_server_stop(esp_mcp_server_handle_t server_handle);

// Cleanup and free all resources
esp_err_t esp_mcp_server_deinit(esp_mcp_server_handle_t server_handle);

工具注册

// Register a tool with optional schema validation
esp_err_t esp_mcp_server_register_tool(esp_mcp_server_handle_t server_handle, 
                                       const esp_mcp_tool_config_t *tool_config);

// Tool handler signature
typedef cJSON* (*esp_mcp_tool_handler_t)(const cJSON *arguments, void *user_data);

资源注册

// Register a resource
esp_err_t esp_mcp_server_register_resource(esp_mcp_server_handle_t server_handle, 
                                           const esp_mcp_resource_config_t *resource_config);

// Resource handler signature
typedef char* (*esp_mcp_resource_handler_t)(const char *uri, void *user_data);

架构验证(内置Zod-like API)

// Create schema objects
cJSON* schema_builder_create_object(void);

// Add typed fields with validation
esp_err_t schema_builder_add_string(cJSON *schema, const char *name, 
                                   const char *description, bool required);
esp_err_t schema_builder_add_integer(cJSON *schema, const char *name, 
                                    const char *description, int min, int max, bool required);
esp_err_t schema_builder_add_boolean(cJSON *schema, const char *name, 
                                    const char *description, bool required);

🎯 MCP协议支持

该组件完全实现了MCP规范:

  • 工具:执行带有副作用的操作(返回JSON)
  • 资源:提供数据内容(返回字符串/二进制)
  • 提示:可重复使用的模板(计划中)
  • JSON-RPC 2.0:完全符合协议
  • 错误处理:标准错误代码和消息
  • 架构验证:输入参数验证

支持的MCP方法

方法 描述 状态
initialize 服务器初始化和能力协商 ✅
tools/list 列出可用工具 ✅
tools/call 执行工具 ✅
resources/list 列出可用资源 ✅
resources/read 读取资源内容 ✅
ping 健康检查 ✅

📊 例子

该组件包括一个综合示例 examples/simple/ 这表明:

  • WiFi连接设置
  • MCP服务器初始化和配置
  • 带有模式验证的工具注册
  • 使用URI模板进行资源注册
  • GPIO控制集成
  • ADC读取功能
  • 实时服务器统计

运行示例

cd examples/simple
idf.py set-target esp32
idf.py menuconfig  # Configure WiFi credentials
idf.py build flash monitor

🔧 配置选项

typedef struct {
    uint16_t port;                    // HTTP server port (default: 8080)
    const char *server_name;          // Server identification
    const char *server_version;       // Server version
    size_t max_connections;           // Max concurrent connections
    size_t stack_size;                // HTTP server stack size
    int task_priority;                // HTTP server task priority
} esp_mcp_server_config_t;

// Default configuration macro
#define ESP_MCP_SERVER_DEFAULT_CONFIG() { \
    .port = 8080, \
    .server_name = "ESP32 MCP Server", \
    .server_version = "1.0.0", \
    .max_connections = 4, \
    .stack_size = 8192, \
    .task_priority = 5 \
}

🛡️ 安全考虑

  • 参数验证:所有工具输入都根据JSON模式进行验证
  • 内存安全:自动清理JSON对象和字符串
  • 错误处理:使用标准HTTP/JSON-RPC代码进行全面的错误报告
  • 资源限制:可配置的连接限制和超时

🧪 测试

使用任何兼容MCP的客户端测试您的MCP服务器:

# Using curl to test tools/list
curl -X POST http://your-esp32-ip/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'

# Using curl to call a tool
curl -X POST http://your-esp32-ip/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"echo","arguments":{"message":"Hello World"}}}'

🤝 贡献

欢迎投稿!请随时提交拉取请求。对于重大更改,请先打开一个问题来讨论您想要更改的内容。

📄 许可证

此项目根据MIT许可证获得许可-请参阅 许可证 文件以获取详细信息。

🔗 相关项目

📞 支持


由以下材料制成❤️ ESP32和AI社区