使用说明

项目简介

MCP Daemon 是一个使用 Rust 语言实现的 Model Context Protocol (MCP) 标准的后端开发框架。它提供了一套构建 MCP 服务器所需的库和工具,使得开发者能够方便地创建能够向 LLM 客户端(如大型语言模型应用)提供结构化上下文信息和外部功能的应用后端。

主要功能点

  • MCP 协议实现: 提供了符合 MCP 规范的 JSON-RPC 消息格式定义和处理逻辑。
  • 服务器框架: 提供 'Server' 特性(Trait)和相关结构,用户实现此特性即可定义自己的 MCP 服务器行为。
  • 资源 (Resources) 托管: 支持定义和提供数据资源,LLM 客户端可以请求读取资源内容。
  • 工具 (Tools) 注册与调用: 支持注册可供 LLM 调用的外部工具,处理工具调用请求并返回结果。
  • Prompt 模板 (Prompts) 定义: 支持定义 Prompt 模板,用于指导 LLM 的交互模式。
  • 多种传输协议: 内建支持通过 Stdio、WebSocket 和 HTTP/2 (支持 TLS 和 CORS) 等多种传输协议与客户端通信。
  • 会话管理: 处理客户端连接、初始化流程和请求/响应的会话状态。
  • 能力声明: 支持服务器在初始化时向客户端声明其支持的功能(如资源、工具、Prompt 等)。
  • 错误处理: 提供标准化的错误处理机制,符合 JSON-RPC 规范。

安装步骤

要将 MCP Daemon 作为库集成到你的 Rust 项目中,请在项目的 'Cargo.toml' 文件中添加以下依赖:

[dependencies]
mcp_daemon = "0.3.0" # 或使用最新版本

或者使用 Cargo 命令行工具添加:

cargo add mcp_daemon

如果你需要 HTTP/2 的 ACME (Let's Encrypt) 支持,可以启用 'acme' 特性:

[dependencies]
mcp_daemon = { version = "0.3.0", features = ["acme"] }

服务器配置(MCP客户端使用)

LLM 客户端需要配置如何启动并连接到你的 MCP 服务器。典型的配置信息通常通过一个 JSON 对象传递,包含服务器的名称、启动命令及其参数、以及通信方式等。以下是一个常见的 JSON 配置结构示例及其字段说明(请根据你的实际服务器实现调整 'command' 和 'args'):

{
  "name": "你的 MCP 服务器名称",
  "description": "你的 MCP 服务器的简要描述",
  "command": "你的服务器可执行文件路径",
  "args": ["参数1", "参数2", "..."],
  "transport": {
    "type": "stdio" // 或 "websocket", "http2" 等
    // 如果是网络传输,可能还需要地址和端口信息
    // "address": "127.0.0.1:8080"
  },
  // 其他特定于客户端的配置项
}
  • 'name' (string): MCP 服务器的友好名称,用于在客户端界面显示。
  • 'description' (string): 对 MCP 服务器功能的简要描述,有助于 LLM 理解其用途。
  • 'command' (string): 启动 MCP 服务器进程的可执行文件路径。这通常是你使用 'cargo build' 构建的 Rust 可执行文件。
  • 'args' (array of string): 传递给服务器进程的命令行参数列表。
  • 'transport' (object): 定义客户端与服务器通信使用的传输协议和地址。
    • 'type' (string): 传输协议类型,常见的有 "stdio"(标准输入输出)、"websocket"、"http2" 等。
    • 'address' (string, 可选): 如果是网络传输,指定服务器监听的地址和端口(例如 "127.0.0.1:8080")。

LLM 客户端会读取此配置,执行 'command' 命令启动你的服务器,并使用指定的 'transport' 方式进行 JSON-RPC 通信。

基本使用方法

作为 MCP Daemon 库的用户,你需要编写代码实现 'mcp_daemon::server::Server' 特性。这个特性定义了 MCP 服务器必须响应的方法(如处理资源请求、工具调用等)。

MCP Daemon 提供了 '#[server]', '#[prompt]', '#[resource]', '#[tool]' 等属性宏来简化 'Server' 特性的实现,特别是 'prompts/', 'resources/', 'tools/*' 相关的方法。

  1. 定义你的服务器状态结构

    struct MyMcpServer {
        // 在这里定义你的服务器需要维护的状态,例如数据库连接、配置等
    }
  2. 实现 'Server' 特性

    use mcp_daemon::server::{server, Server, DefaultServer, RequestContext, SessionData};
    use mcp_daemon::schema::*;
    use mcp_daemon::Result;
    use std::sync::Arc;
    
    struct MyMcpServer;
    
    #[server] // 使用属性宏简化实现
    impl Server for MyMcpServer {
        // 实现 DefaultServer trait 提供的基本方法
        fn server_info(&self) -> Implementation {
             Implementation::from_compile_time_env()
         }
    
         fn instructions(&self) -> Option<String> {
             Some("这是一个示例 MCP 服务器,提供打招呼 Prompt 和一个计数工具。".to_string())
         }
    
        // 使用属性宏定义 Prompt
        /// LLM 可以使用这个 Prompt 来进行基本的问候
        #[prompt]
        async fn hello_prompt(&self) -> Result<GetPromptResult> {
            Ok("您好!我是示例 MCP 服务器。".into()) // 使用 Into 转换简化返回
        }
    
        // 使用属性宏定义 Tool
        /// LLM 可以调用这个工具来增加内部计数器并回显消息
        #[tool]
        async fn increment_counter(&self,
            /// LLM 需要提供的消息参数
            message: String,
        ) -> Result<CallToolResult> {
            // 在实际应用中,你可以在这里访问服务器状态,执行外部操作等
            println!("接收到工具调用,消息: {}", message);
            // 返回工具执行结果
            Ok(format!("工具执行成功,接收到消息: {}", message).into()) // 使用 Into 转换简化返回
        }
    
        // 如果需要,手动实现其他方法,例如 resource/* 或覆盖默认实现
        // async fn resources_list(...) -> Result<Response> { ... }
    }
  3. 选择传输协议并运行服务器

    通常情况下,MCP 服务器通过标准输入输出 (Stdio) 与 LLM 客户端通信。使用 'serve_stdio' 函数即可运行你的服务器。

    use mcp_daemon::server::serve_stdio;
    use mcp_daemon::Result;
    
    #[tokio::main] // 需要 tokio 运行时
    async fn main() -> Result<()> {
        let server = MyMcpServer;
        // 启动服务器监听 Stdio
        serve_stdio(server).await?;
        Ok(())
    }

    如果需要使用 WebSocket 或 HTTP/2 传输,可以参考库中的示例代码 ('examples' 目录) 来设置监听和连接处理。

通过以上步骤,你就创建了一个基本的 MCP 服务器,可以被兼容的 LLM 客户端连接并交互。

信息

分类

AI与计算