Rust MCP 服务端开发实战:基于 awesome-copilot 的 rust-mcp-development 插件与 rmcp SDK 全流程指南
导读
本篇文章聚焦 awesome-copilot 仓库中的 rust-mcp-development 插件,讲解如何借助官方 rmcp Rust SDK 构建高性能、类型安全的 Model Context Protocol(MCP)服务端。你将掌握插件提供的 /rust-mcp-development:rust-mcp-server-generator 斜杠命令与 rust-mcp-expert 智能体、rmcp-macros 过程宏工具链、四种传输方式(Stdio / SSE / Streamable HTTP / 自定义传输)、工具(Tools)、提示词(Prompts)、资源(Resources)三大能力实现,以及从单元测试到跨平台部署的完整落地路径。
插件是什么:一份集成化的 Rust MCP 开发工具箱
rust-mcp-development 是 Awesome Copilot 社区插件体系中面向 Rust 语言的一款开发工具箱。它的目标非常聚焦:帮助开发者使用官方 rmcp SDK 快速构建高性能 MCP 服务端,核心技术栈为 Rust 的 async/await 异步模型、过程宏声明式开发以及强类型参数校验。
插件的元信息记录在 plugin.json 中,其声明如下:
{
"name": "rust-mcp-development",
"description": "Build high-performance Model Context Protocol servers in Rust using the official rmcp SDK with async/await, procedural macros, and type-safe implementations.",
"version": "1.0.0",
"license": "MIT",
"keywords": ["rust", "mcp", "model-context-protocol", "server-development", "sdk", "tokio", "async", "macros", "rmcp"],
"extensions": {
"com.github.awesome-copilot": {
"agents": ["./agents/rust-mcp-expert.md"],
"skills": ["./skills/rust-mcp-server-generator/"]
}
}
}
从 extensions 字段可以清晰地看到插件的组成结构:它打包了一个 Agent(rust-mcp-expert) 和一个 Skill(rust-mcp-server-generator),分别对应"专家问答与代码指导"和"一键生成完整项目"两种使用场景。
安装方式
使用 Copilot CLI 安装:
copilot plugin install rust-mcp-development@awesome-copilot
安装完成后即可在对话中使用插件的斜杠命令,并激活对应的智能体。
插件内置能力清单
插件在 Copilot 会话中暴露一个斜杠命令:
| 命令 | 说明 |
|---|---|
/rust-mcp-development:rust-mcp-server-generator |
使用官方 rmcp SDK 生成一个完整的 Rust MCP Server 项目,包含工具、提示词、资源和测试 |
以及一个专家智能体:
| 智能体 | 说明 |
|---|---|
rust-mcp-expert |
基于 rmcp SDK 与 tokio 异步运行时,为 Rust MCP 服务端开发提供专家级辅助(定义见 agents/rust-mcp-expert.agent.md) |
项目初始化:Cargo 依赖与工程结构
添加依赖
在 Cargo.toml 中加入核心依赖(对应 instructions/rust-mcp-server.instructions.md 的推荐配置):
[dependencies]
rmcp = { version = "0.8.1", features = ["server"] }
tokio = { version = "1", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
anyhow = "1.0"
tracing = "0.1"
tracing-subscriber = "0.3"
启用宏支持时追加:
[dependencies]
rmcp-macros = "0.8"
schemars = { version = "0.8", features = ["derive"] }
需要说明的要点:
rmcp是官方 Rust MCP SDK(插件说明中标注 v0.8+),开启serverfeature 后提供Server、ServerHandler等服务端组件;rmcp-macros提供#[tool]、#[tool_router]、#[tool_handler]三个核心过程宏;schemars::JsonSchema负责为工具参数自动生成 JSON Schema,供客户端(如 Copilot)做参数校验与自动补全;anyhow用于应用层错误上下文链,tracing/tracing-subscriber用于可观测性日志。
如果项目需要 HTTP 传输,插件生成的脚手架还提供可选的 HTTP feature(见 skills/rust-mcp-server-generator/SKILL.md):
axum = { version = "0.7", optional = true }
tower-http = { version = "0.5", features = ["cors"], optional = true }
[features]
default = []
http = ["dep:axum", "dep:tower-http"]
推荐的项目目录结构
无论是手写还是由生成器产出,官方推荐的工程布局如下:
my-mcp-server/
├── Cargo.toml
├── src/
│ ├── main.rs # 服务端入口
│ ├── handler.rs # ServerHandler 实现
│ ├── tools/
│ │ ├── mod.rs
│ │ ├── calculator.rs
│ │ └── greeter.rs
│ ├── prompts/
│ │ ├── mod.rs
│ │ └── code_review.rs
│ ├── resources/
│ │ ├── mod.rs
│ │ └── data.rs
│ └── state.rs
└── tests/
└── integration_tests.rs
这种分层把"入口、处理器、工具、提示词、资源、共享状态、集成测试"拆分为独立模块,职责清晰、便于并行开发与测试。
服务端骨架:main 入口与 ServerHandler 实现
基本服务端搭建
使用 Stdio 传输的最小服务端入口如下:
use rmcp::{
protocol::ServerCapabilities,
server::{Server, ServerHandler},
transport::StdioTransport,
};
use tokio::signal;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
tracing_subscriber::fmt().init();
let handler = MyServerHandler::new();
let transport = StdioTransport::new();
let server = Server::builder()
.with_handler(handler)
.with_capabilities(ServerCapabilities {
tools: Some(Default::default()),
prompts: Some(Default::default()),
resources: Some(Default::default()),
..Default::default()
})
.build(transport)?;
server.run(signal::ctrl_c()).await?;
Ok(())
}
其中 ServerCapabilities 是向客户端声明的能力开关:tools、prompts、resources 分别对应 MCP 协议的三类核心能力,按需启用即可。server.run(signal::ctrl_c()) 让服务在收到 Ctrl+C 信号后优雅退出。
ServerHandler 的实现骨架
ServerHandler 是服务端的核心 trait,需要实现 list_tools / call_tool(以及可选的提示词、资源相关方法)。在接入工具路由后,典型实现如下:
use rmcp::{
model::*,
protocol::*,
server::{RequestContext, ServerHandler, RoleServer, ToolRouter},
ErrorData,
};
pub struct MyServerHandler {
tool_router: ToolRouter,
}
#[async_trait::async_trait]
impl ServerHandler for MyServerHandler {
async fn list_tools(
&self,
_request: Option<PaginatedRequestParam>,
_context: RequestContext<RoleServer>,
) -> Result<ListToolsResult, ErrorData> {
let items = self.tool_router.list_all();
Ok(ListToolsResult::with_all_items(items))
}
async fn call_tool(
&self,
request: CallToolRequestParam,
context: RequestContext<RoleServer>,
) -> Result<CallToolResult, ErrorData> {
let tcc = ToolCallContext::new(self, request, context);
self.tool_router.call(tcc).await
}
}
从源码结构看,ToolRouter 承担了"工具注册表 + 分发器"的双重职责:list_all() 汇总所有已注册工具,call() 则根据请求中的工具名完成参数解析与调用。
工具开发:过程宏驱动的声明式实现
使用 #[tool] 宏定义工具
rmcp-macros 的 #[tool] 宏是开发工具的最快路径。以下是一个带类型化参数的算术工具(与 agents/rust-mcp-expert.agent.md 示例一致):
use rmcp::tool;
use rmcp::model::Parameters;
use serde::{Deserialize, Serialize};
use schemars::JsonSchema;
#[derive(Debug, Deserialize, JsonSchema)]
pub struct CalculateParams {
pub a: f64,
pub b: f64,
pub operation: String,
}
#[tool(
name = "calculate",
description = "Performs basic arithmetic operations",
annotations(read_only_hint = true, idempotent_hint = true)
)]
pub async fn calculate(params: Parameters<CalculateParams>) -> Result<f64, String> {
let p = params.inner();
match p.operation.as_str() {
"add" => Ok(p.a + p.b),
"subtract" => Ok(p.a - p.b),
"multiply" => Ok(p.a * p.b),
"divide" if p.b != 0.0 => Ok(p.a / p.b),
"divide" => Err("Division by zero".to_string()),
_ => Err(format!("Unknown operation: {}", p.operation)),
}
}
要点解读:
Parameters<T>包装:params.inner()取出反序列化后的T;T同时派生Deserialize与JsonSchema,保证"反序列化 + Schema 生成"一条龙;- 返回值即工具结果:
Result<f64, String>的Ok会被封装为正常工具结果,Err则映射为工具错误,无需手写 JSON 拼装; - 注解(annotations):
read_only_hint、idempotent_hint向客户端声明工具的副作用语义,帮助大模型决定是否调用以及如何调用。
工具注解的完整取值
注解可以组合表达工具的调用语义(见 instructions/rust-mcp-server.instructions.md):
// 破坏性操作:明确声明 destructive + 非只读 + 非幂等
#[tool(
name = "delete_file",
annotations(
destructive_hint = true,
read_only_hint = false,
idempotent_hint = false
)
)]
pub async fn delete_file(params: Parameters<DeleteParams>) -> Result<(), String> { /* ... */ }
// 只读查询:read_only + idempotent + open_world
#[tool(
name = "search_data",
annotations(
read_only_hint = true,
idempotent_hint = true,
open_world_hint = true
)
)]
pub async fn search_data(params: Parameters<SearchParams>) -> Vec<String> { /* ... */ }
返回富内容(Rich Content)
工具不仅可返回字符串,还能返回结构化的多段内容:
use rmcp::model::{ToolResponseContent, TextContent, ImageContent};
#[tool]
async fn analyze_code(params: Parameters<CodeParams>) -> ToolResponseContent {
ToolResponseContent::from(vec![
TextContent::text(format!("Analysis of {}:", params.inner().filename)),
TextContent::text("No issues found."),
])
}
ToolResponseContent 支持 TextContent、ImageContent 等 MCP 内容类型,为向客户端返回文本、图片等多媒体结果提供了统一出口。
使用 #[tool_router] 与 #[tool_handler] 组织多个工具
当工具数量增多时,可以用 #[tool_router] 将一组工具聚合到同一实现类型上:
use rmcp::{tool_router, tool_handler};
use rmcp::server::{ServerHandler, ToolRouter};
pub struct MyHandler {
state: ServerState,
tool_router: ToolRouter,
}
#[tool_router]
impl MyHandler {
#[tool(name = "greet", description = "Greets a user")]
async fn greet(params: Parameters<GreetParams>) -> String {
format!("Hello, {}!", params.inner().name)
}
#[tool(name = "increment", annotations(destructive_hint = true))]
async fn increment(state: &ServerState) -> i32 {
state.increment().await
}
pub fn new() -> Self {
Self {
state: ServerState::new(),
tool_router: Self::tool_router(),
}
}
}
#[tool_handler]
impl ServerHandler for MyHandler {
// Prompt 与 Resource 处理器...
}
从宏的实现逻辑可以推断:#[tool_router] 会在 impl 块内扫描所有 #[tool] 标记的方法,自动生成 tool_router() 构造函数;#[tool_handler] 则把宏生成的路由逻辑嫁接到 ServerHandler trait 实现上。值得注意的细节是,工具方法可以直接接收 &ServerState 参数,宏会将其解释为从处理器实例借用共享状态。
Prompt 与 Resource:补齐 MCP 三大能力
提示词处理器(Prompts)
提示词能力由 list_prompts 与 get_prompt 两个方法承载:
async fn list_prompts(
&self,
_request: Option<PaginatedRequestParam>,
_context: RequestContext<RoleServer>,
) -> Result<ListPromptsResult, ErrorData> {
let prompts = vec![
Prompt {
name: "code-review".to_string(),
description: Some("Review code for best practices".to_string()),
arguments: Some(vec![
PromptArgument {
name: "language".to_string(),
description: Some("Programming language".to_string()),
required: Some(true),
},
PromptArgument {
name: "code".to_string(),
description: Some("Code to review".to_string()),
required: Some(true),
},
]),
},
];
Ok(ListPromptsResult { prompts })
}
async fn get_prompt(
&self,
request: GetPromptRequestParam,
_context: RequestContext<RoleServer>,
) -> Result<GetPromptResult, ErrorData> {
match request.name.as_str() {
"code-review" => {
let args = request.arguments.as_ref()
.ok_or_else(|| ErrorData::invalid_params("arguments required"))?;
let language = args.get("language")
.ok_or_else(|| ErrorData::invalid_params("language required"))?;
let code = args.get("code")
.ok_or_else(|| ErrorData::invalid_params("code required"))?;
Ok(GetPromptResult {
description: Some(format!("Code review for {}", language)),
messages: vec![
PromptMessage::user(format!(
"Review this {} code for best practices:\n\n{}",
language, code
)),
],
})
}
_ => Err(ErrorData::invalid_params("Unknown prompt")),
}
}
模式小结:list_prompts 负责声明可用的提示词模板及其参数;get_prompt 按名称取出模板,把客户端传入的 arguments 注入到 PromptMessage 中。参数缺失时统一使用 ErrorData::invalid_params 返回协议级错误。
资源处理器(Resources)
资源能力通过 list_resources / read_resource 实现,资源以 URI 寻址,携带 MIME 类型:
async fn list_resources(
&self,
_request: Option<PaginatedRequestParam>,
_context: RequestContext<RoleServer>,
) -> Result<ListResourcesResult, ErrorData> {
let resources = vec![
Resource {
uri: "file:///config/settings.json".to_string(),
name: "Server Settings".to_string(),
description: Some("Server configuration".to_string()),
mime_type: Some("application/json".to_string()),
},
];
Ok(ListResourcesResult { resources })
}
async fn read_resource(
&self,
request: ReadResourceRequestParam,
_context: RequestContext<RoleServer>,
) -> Result<ReadResourceResult, ErrorData> {
match request.uri.as_str() {
"file:///config/settings.json" => {
let settings = self.load_settings().await
.map_err(|e| ErrorData::internal_error(e.to_string()))?;
let json = serde_json::to_string_pretty(&settings)
.map_err(|e| ErrorData::internal_error(e.to_string()))?;
Ok(ReadResourceResult {
contents: vec![
ResourceContents::text(json)
.with_uri(request.uri)
.with_mime_type("application/json"),
],
})
}
_ => Err(ErrorData::invalid_params("Unknown resource")),
}
}
ResourceContents::text(...).with_uri(...).with_mime_type(...) 的链式调用表明内容载体与 URI、MIME 元数据可以灵活组合,同一资源可返回文本或二进制(如图片)内容。
传输层:Stdio、SSE、Streamable HTTP 与自定义传输
MCP 服务端支持多种传输方式,插件文档与指令文档给出了完整示例:
Stdio(CLI 集成首选)
use rmcp::transport::StdioTransport;
let transport = StdioTransport::new();
let server = Server::builder()
.with_handler(handler)
.build(transport)?;
server.run(signal::ctrl_c()).await?;
Stdio 通过标准输入输出通信,是最适合本地 CLI 工具与桌面客户端(如 Claude Desktop)的传输方式。
SSE(Server-Sent Events)
use rmcp::transport::SseServerTransport;
use std::net::SocketAddr;
let addr: SocketAddr = "127.0.0.1:8000".parse()?;
let transport = SseServerTransport::new(addr);
let server = Server::builder()
.with_handler(handler)
.build(transport)?;
server.run(signal::ctrl_c()).await?;
SSE 基于 HTTP 长连接单向推送,适用于远程部署场景。
Streamable HTTP(配合 Axum)
use rmcp::transport::StreamableHttpTransport;
use axum::{Router, routing::post};
let transport = StreamableHttpTransport::new();
let app = Router::new()
.route("/mcp", post(transport.handler()));
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000").await?;
axum::serve(listener, app).await?;
这是现代 MCP 推荐的方式:借助 axum 路由将 /mcp 端点交给 StreamableHttpTransport::handler(),支持请求-响应与流式响应两种模式,天然适配 HTTPS、负载均衡等基础设施。
自定义传输(TCP / Unix Socket / WebSocket)
use rmcp::transport::Transport;
use tokio::net::TcpListener;
// TCP、Unix Socket、WebSocket 的自定义实现可参考 SDK 的 examples/transport/ 目录
Transport trait 是 rmcp 对传输层的抽象,接入新协议只需实现该 trait,服务端业务逻辑无需改动。
状态管理与错误处理
基于 Arc + RwLock 的共享状态
MCP 服务端通常要处理并发的工具调用,官方推荐 Arc<RwLock<T>> 作为共享状态容器:
use std::sync::Arc;
use tokio::sync::RwLock;
use std::collections::HashMap;
#[derive(Clone)]
pub struct ServerState {
counter: Arc<RwLock<i32>>,
cache: Arc<RwLock<HashMap<String, String>>>,
}
impl ServerState {
pub fn new() -> Self {
Self {
counter: Arc::new(RwLock::new(0)),
cache: Arc::new(RwLock::new(HashMap::new())),
}
}
pub async fn increment(&self) -> i32 {
let mut counter = self.counter.write().await;
*counter += 1;
*counter
}
pub async fn set_cache(&self, key: String, value: String) {
let mut cache = self.cache.write().await;
cache.insert(key, value);
}
pub async fn get_cache(&self, key: &str) -> Option<String> {
let cache = self.cache.read().await;
cache.get(key).cloned()
}
}
设计要点:#[derive(Clone)] 使状态可以跨任务克隆共享;读多写少的场景用 RwLock(读锁可并发),写多读少则改用 Mutex;要求更高的并发哈希表场景可评估 DashMap。
双层错误模型:anyhow 与 ErrorData
指令文档明确了错误处理的分工:
- 应用层错误用
anyhow:负责文件读取、JSON 解析等内部操作,借助.context()提供上下文信息;
use anyhow::{Context, Result};
async fn load_config() -> Result<Config> {
let content = tokio::fs::read_to_string("config.json")
.await
.context("Failed to read config file")?;
let config: Config = serde_json::from_str(&content)
.context("Failed to parse config")?;
Ok(config)
}
- 协议层错误用
ErrorData:凡是返回给 MCP 客户端的错误必须转换为ErrorData,常用构造方法有ErrorData::invalid_params(...)(参数非法)与ErrorData::internal_error(...)(服务端内部错误)。
async fn call_tool(
&self,
request: CallToolRequestParam,
context: RequestContext<RoleServer>,
) -> Result<CallToolResult, ErrorData> {
if request.name.is_empty() {
return Err(ErrorData::invalid_params("Tool name cannot be empty"));
}
let result = self.execute_tool(&request.name, request.arguments)
.await
.map_err(|e| ErrorData::internal_error(e.to_string()))?;
Ok(CallToolResult {
content: vec![TextContent::text(result)],
is_error: Some(false),
})
}
进阶能力:进度通知与 OAuth 鉴权
进度通知
长耗时操作(如大文件处理)应通过 context.notify_progress(...) 向客户端推送进度:
use rmcp::model::ProgressNotification;
#[tool]
async fn process_large_file(
params: Parameters<ProcessParams>,
context: RequestContext<RoleServer>,
) -> Result<String, String> {
let total = 100;
for i in 0..=total {
// Do work...
if i % 10 == 0 {
context.notify_progress(ProgressNotification {
progress: i,
total: Some(total),
}).await.ok();
}
}
Ok("Processing complete".to_string())
}
这里的关键是工具方法可以额外注入 context: RequestContext<RoleServer> 参数,宏会自动注入运行时上下文。
OAuth 集成
面向外部访问的服务端可启用 OAuth:
use rmcp::oauth::{OAuthConfig, OAuthProvider};
let oauth_config = OAuthConfig {
authorization_endpoint: "https://auth.example.com/authorize".to_string(),
token_endpoint: "https://auth.example.com/token".to_string(),
client_id: env::var("CLIENT_ID")?,
client_secret: env::var("CLIENT_SECRET")?,
scopes: vec!["read".to_string(), "write".to_string()],
};
let oauth_provider = OAuthProvider::new(oauth_config);
// 完整实现可参考 SDK examples/servers/complex_auth_sse.rs
注意 client_id / client_secret 应从环境变量注入,避免硬编码泄密。
测试策略:单元测试与集成测试
工具单元测试
直接以 tokio::test 驱动工具函数(见 instructions/rust-mcp-server.instructions.md):
#[cfg(test)]
mod tests {
use super::*;
use rmcp::model::Parameters;
#[tokio::test]
async fn test_calculate_add() {
let params = Parameters::new(CalculateParams {
a: 5.0,
b: 3.0,
operation: "add".to_string(),
});
let result = calculate(params).await.unwrap();
assert_eq!(result, 8.0);
}
#[tokio::test]
async fn test_divide_by_zero() {
let params = Parameters::new(CalculateParams {
a: 5.0,
b: 0.0,
operation: "divide".to_string(),
});
assert!(calculate(params).await.is_err());
}
}
处理器集成测试
对 ServerHandler 层做端到端验证,例如断言工具列表内容:
#[tokio::test]
async fn test_server_list_tools() {
let handler = MyServerHandler::new();
let context = RequestContext::default();
let result = handler.list_tools(None, context).await.unwrap();
assert!(!result.tools.is_empty());
assert!(result.tools.iter().any(|t| t.name == "calculate"));
}
由 rust-mcp-server-generator 生成的脚手架还会附赠覆盖 list_tools、call_tool、list_prompts、list_resources 的完整集成测试模板(见 skills/rust-mcp-server-generator/SKILL.md),生成后直接 cargo test 即可运行。
性能优化建议
专家智能体总结了四条可落地的性能建议:
- 按场景选锁:读多写少用
RwLock,写多读少用Mutex,高并发哈希表考虑DashMap; - 缩短持锁时间:不要在持有锁的临界区内执行异步操作,先克隆数据再释放锁:
// 推荐:锁内克隆,锁外处理
let value = {
let data = self.data.read().await;
data.clone()
};
process(value).await;
// 不推荐:锁内 await,锁持有时间过长
let data = self.data.read().await;
process(&*data).await;
- 使用有缓冲通道:
tokio::sync::mpsc::channel(100)提升生产者-消费者吞吐; - 批量并行处理:用
futures::future::join_all并发执行独立任务:
async fn batch_process(&self, items: Vec<Item>) -> Vec<Result<(), Error>> {
use futures::future::join_all;
join_all(items.into_iter().map(|item| self.process(item))).await
}
日志与可观测性
用 tracing 统一埋点,服务启动时初始化订阅器:
fn init_logging() {
tracing_subscriber::fmt()
.with_max_level(tracing::Level::DEBUG)
.with_target(false)
.with_thread_ids(true)
.init();
}
#[tool]
async fn my_tool(params: Parameters<MyParams>) -> String {
debug!("Tool called with params: {:?}", params);
info!("Processing request");
// Tool logic...
info!("Request completed");
"Done".to_string()
}
运行时可借助环境变量动态调整级别:RUST_LOG=debug cargo run。
部署:跨平台编译、Docker 与客户端接入
发布版二进制与跨平台编译
# 原生发布构建
cargo build --release --target x86_64-unknown-linux-gnu
cargo build --release --target x86_64-pc-windows-msvc
cargo build --release --target x86_64-apple-darwin
# 使用 cross 交叉编译(无需目标平台工具链)
cargo install cross
cross build --release --target aarch64-unknown-linux-gnu
Docker 多阶段构建
FROM rust:1.75 as builder
WORKDIR /app
COPY Cargo.toml Cargo.lock ./
COPY src ./src
RUN cargo build --release
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/*
COPY --from=builder /app/target/release/my-mcp-server /usr/local/bin/
CMD ["my-mcp-server"]
第二阶段仅保留运行所需的最小系统镜像与 ca-certificates(保证 TLS 访问正常),符合镜像瘦身的最佳实践。
在 MCP 客户端中注册服务端
以 Claude Desktop 为例,在配置中注册 Stdio 类型的服务端:
{
"mcpServers": {
"my-rust-server": {
"command": "/path/to/target/release/my-mcp-server",
"args": []
}
}
}
对于支持 HTTP 的服务端,command / args 亦可替换为 SSE 或 Streamable HTTP 的 URL 配置。
一键生成:/rust-mcp-development:rust-mcp-server-generator 实战
如果不想从零手写,可以直接在 Copilot 会话中调用插件的斜杠命令生成完整项目。生成器(skills/rust-mcp-server-generator/SKILL.md)会先向用户收集五项需求:
- 项目名称(如
my-mcp-server); - 服务端描述(如 "A weather data MCP server");
- 传输类型(stdio、sse、http 或全部);
- 要包含的工具(如 "weather lookup"、"forecast"、"alerts");
- 是否包含提示词与资源。
随后生成覆盖 Cargo.toml、.gitignore、README.md、src/main.rs、src/handler.rs、src/state.rs、src/tools/、src/prompts/、src/resources/ 与 tests/integration_test.rs 的完整工程,其中 Cargo.toml 已按 feature 开关组织 http 传输依赖,main.rs 默认使用 Stdio 传输,handler.rs 通过 #[tool_router] 与 #[tool_handler] 组装工具、提示词与资源。生成后依次执行:
cd {project-name}
cargo build
cargo test
cargo run
即可完成从生成到运行验证的闭环。
核心原则速览
结合 agents/rust-mcp-expert.agent.md 的总结,开发时应坚持以下原则:
- 类型安全优先:所有工具参数都派生
JsonSchema; - 全异步:所有处理器必须为 async,绝不阻塞 tokio 运行时;
- 正确错误处理:统一使用
Result类型与ErrorData协议错误; - 测试覆盖:工具配单元测试,处理器配集成测试;
- 文档完备:所有公开项添加 doc 注释;
- 性能意识:关注并发模型与锁竞争;
- 符合 Rust 惯例:遵循所有权、生命周期与 async 的惯用法。
参考资源(仓库内)
- 插件入口与能力清单:plugins/rust-mcp-development/README.md
- 插件元信息与依赖关系:plugins/rust-mcp-development/plugin.json
- 专家智能体完整提示词(含全部代码示例):agents/rust-mcp-expert.agent.md
- 开发最佳实践指令(自动应用于
**/*.rs):instructions/rust-mcp-server.instructions.md - 项目生成器 SKILL(含完整脚手架模板):skills/rust-mcp-server-generator/SKILL.md
- 插件市场总览与安装方式:docs/README.plugins.md
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0632
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
video-shotcraftAI宣传片skill,使用 Remotion 制作电影级产品视频:提供106 张镜头配方卡和可复用的视频魔板。适用于 Claude Code 与 Codex以及所有其他智能体Markdown00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python09
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00