DRAVR-TRONC
用于构建的轻量级Rust运行时 主控程序 具有可选REST API支持的服务器。提供在几分钟内从零到生产就绪的MCP服务器所需的一切——JSON-RPC 2.0协议、stdio和HTTP传输、承载身份验证、健康检查、CLI解析和结构化跟踪。
为什么选择dravr-tronc?
在Rust中构建MCP服务器意味着每次都要编写相同的样板:JSON-RPC 2.0类型、请求调度、传输层、身份验证中间件、CLI args。dravr-tronc将所有这些提取到一个机箱中,因此您只需编写域逻辑。
- 通用超状态 —
McpServer与任何人合作Send + Sync状态类型 - 两次运输 --stdio(用于编辑器/CLI集成)和HTTP与SSE(用于web客户端)
- 零配置 --合理的默认设置、环境变量驱动的身份验证、即插即用
- 生产就绪 --恒定时间认证、结构化跟踪、健康检查、76次测试
- 最小依赖性 --axum、tokio、serde、clap、跟踪(无框架锁定)
快速开始
[dependencies]
dravr-tronc = "0.3"1.定义你的状态和工具
use std::sync::Arc;
use async_trait::async_trait;
use dravr_tronc::mcp::protocol::{CallToolResult, ToolDefinition};
use dravr_tronc::{McpTool, McpServer, ToolRegistry};
use serde_json::{json, Value};
use tokio::sync::RwLock;
struct AppState {
greeting: String,
}
struct GreetTool;
#[async_trait]
impl McpTool for GreetTool {
fn definition(&self) -> ToolDefinition {
ToolDefinition {
name: "greet".to_owned(),
description: "Greet someone by name".to_owned(),
input_schema: json!({
"type": "object",
"properties": {
"name": { "type": "string" }
},
"required": ["name"]
}),
}
}
async fn execute(&self, state: &Arc>, args: Value) -> CallToolResult {
let name = args.get("name").and_then(|v| v.as_str()).unwrap_or("world");
let greeting = state.read().await.greeting.clone();
CallToolResult::text(format!("{greeting}, {name}!"))
}
}2.把它连接起来
#[tokio::main]
async fn main() -> Result> {
dravr_tronc::server::tracing_init::init("stdio");
let mut registry = ToolRegistry::new();
registry.register(Box::new(GreetTool));
let state = Arc::new(RwLock::new(AppState {
greeting: "Hello".to_owned(),
}));
let server = Arc::new(McpServer::new("my-mcp-server", "0.1.0", registry, state));
// Serve over stdin/stdout (for Claude Desktop, Cursor, etc.)
dravr_tronc::mcp::transport::stdio::run(server).await
}3.或者通过HTTP提供服务
// Serve over HTTP with SSE support
dravr_tronc::mcp::transport::http::serve(server, "127.0.0.1", 3000).await?;4.合并到现有的Axum应用程序中
use dravr_tronc::mcp::transport::http::mcp_router;
let app = axum::Router::new()
.route("/health", axum::routing::get(health_handler))
.route("/api/data", axum::routing::get(data_handler))
.merge(mcp_router(server)) // adds POST /mcp
.layer(axum::middleware::from_fn(|req, next| {
dravr_tronc::server::auth::require_auth("MY_API_KEY", req, next)
}));模块
| 模块 | 目的 |
|---|---|
mcp::protocol | JSON-RPC 2.0类型——请求、响应、错误、MCP初始化/工具/调用 |
mcp::server | 通用 McpServer --分派初始化、工具/列表、工具/调用、ping |
mcp::tool | McpTool 性状+ ToolRegistry --定义和注册工具 |
mcp::transport::stdio | stdin/stdout上以换行符分隔的JSON |
mcp::transport::http Axum POST。 /mcp 带有SSE(流式HTTP)的处理程序 | |
server::auth | 承载令牌中间件——环境变量驱动,恒定时间比较 |
server::health | HealthResponse 带有HTTP状态代码的生成器 |
server::cli | ServerArgs / McpArgs --clap结构 #[command(flatten)] |
server::tracing_init | 跟踪订阅者--stdio为stderr,HTTP为stdout |
error | ErrorResponse 用于REST API+JSON-RPC错误代码常量 |
身份验证中间件
从指定的环境变量中读取API键。如果变量未设置,则所有请求都会通过(开发模式)。用途 subtle::ConstantTimeEq 以防止定时攻击。
// Only enforced when MY_API_KEY env var is set
dravr_tronc::server::auth::require_auth("MY_API_KEY", request, next).await健康检查
use dravr_tronc::server::health::HealthResponse;
let resp = HealthResponse::ok("my-service", "1.0.0")
.with_detail("database", "connected")
.with_detail("cache", "warm");
// Returns 200 for "ok", 503 for "degraded"CLI参数
将共享参数平铺到项目的CLI结构中:
use clap::Parser;
use dravr_tronc::server::cli::McpArgs;
#[derive(Parser)]
struct Cli {
#[command(flatten)]
server: McpArgs, // adds --transport, --host, --port
#[arg(long)]
my_custom_flag: bool,
}推荐项目布局
my-project/
├── src/ # Core domain library
├── crates/my-project-mcp/ # MCP server (library + binary)
│ ├── src/state.rs # Your ServerState
│ ├── src/tools/ # Your McpTool implementations
│ └── src/main.rs # Thin entry point using dravr-tronc
└── crates/my-project-server/ # REST API + MCP unified server (binary)
├── src/router.rs # Axum routes + mcp_router() merge
└── src/main.rs # CLI + transport dispatch许可证
根据以下任一方式获得许可 Apache许可证,版本2.0 或 MIT许可证 由您选择。
