Token导航 LogoToken导航TokenDH.com
Tower MCP logo
AI代理未说明官方级别未说明来源级核验

Tower MCP

MCP Server

tower-mcp是一个基于Rust的Tower服务抽象的MCP协议实现库,支持多种传输方式和中间件集成。

工具数

0

提示词数

0

GitHub Stars

6

资源数

0
Rust中间件AI代理

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

作者 / 组织

joshrotenberg

提供方

joshrotenberg

最后核验

2026/5/17 20:22

快速接入

先看主来源和安装命令,再打开仓库或文档;下面只保留这个条目的关键接入事实。

详细介绍

塔mcp

![Crates.io](https://crates.io/crates/tower-mcp) ![Documentation](https://docs.rs/tower-mcp) ![CI](https://github.com/joshrotenberg/tower-mcp/actions/workflows/ci.yml) ![License](https://github.com/joshrotenberg/tower-mcp#license) ![MSRV](https://github.com/joshrotenberg/tower-mcp) ![MCP](https://modelcontextprotocol.io/specification/2025-11-25) ![Conformance](https://github.com/joshrotenberg/tower-mcp/actions/workflows/conformance.yml)

塔本地 模型上下文协议 Rust的(MCP)实现。

概述

tower mcp提供了一种可组合的、中间件友好的方法来构建mcp服务器,该方法使用 服务抽象。与框架风格的MCP实现不同,tower MCP将MCP视为另一种可以通过tower提供服务的协议 Service 特质。

这意味着:

  • 标准塔式中间件(跟踪、度量、速率限制、身份验证)刚刚工作
  • 同一服务可以通过多种传输方式(stdio、HTTP、WebSocket)公开
  • 易于与现有的基于塔式的应用程序(axum、tonic)集成

axum用户熟悉

如果你用过 阿克苏姆,tower-mcp的API会感觉很熟悉:

  • 提取器模式:工具处理程序使用提取器,如 State, Json,以及 Context
  • 路由器组成: McpRouter::merge()McpRouter::nest() 像axum的路由器方法一样工作
  • 每处理程序中间件:通过将Tower图层应用于单个工具、资源或提示 .layer()
  • 建造者模式:工具、资源和提示的构建者流利

为什么选择塔mcp?

优势

Tower原生中间件超时、速率限制、身份验证、跟踪——在整个服务器或单个工具上。任何 tower::Layer 作品。
所有运输stdio、HTTP/SSE(带流恢复)、WebSocket和子进程。相同的路由器,任何传输方式。
过程测试TestClient 允许您测试MCP服务器,而无需生成子进程或打开套接字。
一致性39/39服务器和265/265客户端一致性检查在每个PR上通过CI
能力过滤多租户模式的基于会话的工具/资源/提示可见性。
不需要proc宏生成器模式API,带有可选的基于训练的工具。没有什么隐藏在后面 #[derive].可选 #[tool_fn] / #[prompt_fn] / #[resource_fn] 为方便起见,可使用宏(功能: macros).
异步任务完整的任务生命周期——后台执行、取消、TTL清理、每工具任务支持模式。客户端可以轮询或等待长时间运行的工具结果。
多服务器代理通过每个后端中间件和命名空间隔离,在单个端点后聚合N个后端服务器。
axum生态系统HTTP和WebSocket传输建立在axum之上,因此现有的axum中间件和提取器可以工作

权衡

  • 比基于宏观的方法更老套 对于简单的服务器,虽然可选 macros 该功能显著缩小了这一差距。
  • 需要熟悉塔楼/服务。.layer() 组合模型很强大,但如果你以前没有使用过Tower,它有一个学习曲线。
  • 更重的依赖树 比最小的单一传输实现,特别是 features = ["full"].

快速开始

use tower_mcp::{McpRouter, ToolBuilder, CallToolResult};
use schemars::JsonSchema;
use serde::Deserialize;

// Define your input type - schema is auto-generated
#[derive(Debug, Deserialize, JsonSchema)]
struct GreetInput {
    name: String,
}

// Build a tool with type-safe handler
let greet = ToolBuilder::new("greet")
    .title("Greet")
    .description("Greet someone by name")
    .handler(|input: GreetInput| async move {
        Ok(CallToolResult::text(format!("Hello, {}!", input.name)))
    })
    .build();

// Create router with tools
let router = McpRouter::new()
    .server_info("my-server", "1.0.0")
    .instructions("This server provides greeting functionality")
    .tool(greet);

// The router implements tower::Service and can be composed with middleware

安装

添加到您的 Cargo.toml:

[dependencies]
tower-mcp = "0.9"

功能标志

特性描述
full启用所有可选功能
http支持SSE的HTTP传输(添加axum、hyper)
websocket用于全双工通信的WebSocket传输
childproc用于生成子进程MCP服务器的子进程传输
oauthOAuth 2.1资源服务器支持——JWT验证、受保护的资源元数据(需要 http)
jwks远程密钥集的JWKS端点获取(需要 oauth)
http-client用于连接到远程MCP服务器的HTTP客户端传输
oauth-clientOAuth 2.0客户端令牌获取——客户端凭据授予、自动发现、令牌缓存(需要 http-client)
testing测试工具(TestClient)用于过程测试
dynamic-tools工具、提示和资源的运行时注册/注销
proxy多服务器聚合代理(McpProxy)
macros可选proc宏(#[tool_fn], #[prompt_fn], #[resource_fn], #[resource_template_fn])
resilience再出口塔架弹性断路器、速率限制器和舱壁层
statelessSEP-1442无状态MCP模式(实验)——无会话服务请求

功能示例:

[dependencies]
tower-mcp = { version = "0.9", features = ["full"] }

仅类型

如果你只需要MCP协议类型和错误类型,而不需要tower、tokio或axum-- 使用 tower-mcp-types 直接装箱。 这对于编辑器集成、代码生成器、协议验证器或 您希望在没有运行时的情况下序列化/反序列化MCP消息的任何上下文。

[dependencies]
tower-mcp-types = "0.9"

tower-mcp-types 提供以下所有类型 tower_mcp::protocoltower_mcp::error 依赖性最小(serde, serde_json, thiserror, base64).完整版 tower-mcp 板条箱再出口从 tower-mcp-types,所以没有 如果你两者都用,那就重复。

工具定义

生成器模式(推荐)

use tower_mcp::{ToolBuilder, CallToolResult};
use schemars::JsonSchema;
use serde::Deserialize;

#[derive(Debug, Deserialize, JsonSchema)]
struct AddInput {
    a: i64,
    b: i64,
}

let add = ToolBuilder::new("add")
    .description("Add two numbers")
    .read_only()  // Hint: this tool doesn't modify state
    .handler(|input: AddInput| async move {
        Ok(CallToolResult::text(format!("{}", input.a + input.b)))
    })
    .build();

Proc宏(可选)

启用 features = ["macros"]宏生成构建器代码——您始终可以弹出到构建器模式以进行完全控制。

use tower_mcp::{tool_fn, prompt_fn, resource_fn, resource_template_fn};
use tower_mcp::{CallToolResult, McpRouter};
use tower_mcp::protocol::{GetPromptResult, ReadResourceResult};

#[derive(Debug, Deserialize, JsonSchema)]
struct AddInput { a: i64, b: i64 }

#[tool_fn(description = "Add two numbers")]
async fn add(input: AddInput) -> Result {
    Ok(CallToolResult::text(format!("{}", input.a + input.b)))
}

#[prompt_fn(description = "Greet someone", args(name = "Name to greet"))]
async fn greet(args: HashMap) -> Result {
    let name = args.get("name").cloned().unwrap_or_default();
    Ok(GetPromptResult::user_message(format!("Hello, {name}!")))
}

#[resource_fn(uri = "app://config", description = "App configuration")]
async fn config() -> Result {
    Ok(ReadResourceResult::text("app://config", "debug=true"))
}

// Each macro generates a constructor: add_tool(), greet_prompt(), config_resource()
let router = McpRouter::new()
    .server_info("my-server", "1.0.0")
    .tool(add_tool())
    .prompt(greet_prompt())
    .resource(config_resource());

基于特性(适用于复杂工具)

use tower_mcp::tool::McpTool;
use tower_mcp::{Result, CallToolResult};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::sync::Arc;

struct Calculator {
    precision: u32,
}

#[derive(Debug, Deserialize, JsonSchema)]
struct CalcInput {
    expression: String,
}

impl McpTool for Calculator {
    const NAME: &'static str = "calculate";
    const DESCRIPTION: &'static str = "Evaluate a mathematical expression";

    type Input = CalcInput;
    type Output = f64;

    async fn call(&self, input: Self::Input) -> Result {
        // Your calculation logic here
        Ok(42.0)
    }
}

// Convert to Tool and register
let calc = Calculator { precision: 10 };
let router = McpRouter::new().tool(calc.into_tool());

带提取器的处理程序(状态、上下文、JSON)

使用axum样式的提取器来访问状态、上下文和键入的输入:

use std::sync::Arc;
use tower_mcp::{ToolBuilder, CallToolResult};
use tower_mcp::extract::{State, Context, Json};

#[derive(Clone)]
struct AppState { db_url: String }

let state = Arc::new(AppState { db_url: "postgres://...".into() });

let search = ToolBuilder::new("search")
    .description("Search with progress updates")
    .extractor_handler(state, |
        State(app): State>,
        ctx: Context,
        Json(input): Json,
    | async move {
        // Report progress
        ctx.report_progress(0.5, Some(1.0), Some("Searching...")).await;
        // Use state
        let results = format!("Searched {} for: {}", app.db_url, input.query);
        Ok(CallToolResult::text(results))
    })
    .build();

docs.rs 了解更多模式,包括每个工具的中间件、图标和标题、原始JSON处理程序和输出模式。

资源定义

use tower_mcp::ResourceBuilder;

// Static resource with inline content
let config = ResourceBuilder::new("file:///config.json")
    .name("Configuration")
    .description("Server configuration")
    .json(serde_json::json!({
        "version": "1.0.0",
        "debug": true
    }))
    .build();

// Dynamic resource with handler
let status = ResourceBuilder::new("app:///status")
    .name("Server Status")
    .description("Current server status")
    .handler(|| async {
        Ok("Running".to_string())
    })
    .build();

let router = McpRouter::new()
    .resource(config)
    .resource(status);

快速定义

use tower_mcp::{PromptBuilder, GetPromptResult};

let greet = PromptBuilder::new("greet")
    .description("Generate a greeting")
    .required_arg("name", "Name to greet")
    .optional_arg("style", "Greeting style (formal/casual)")
    .handler(|args| async move {
        let name = args.get("name").map(|s| s.as_str()).unwrap_or("World");
        let style = args.get("style").map(|s| s.as_str()).unwrap_or("casual");

        let text = match style {
            "formal" => format!("Good day, {}. How may I assist you?", name),
            _ => format!("Hey {}!", name),
        };

        // Builder handles message construction
        Ok(GetPromptResult::builder()
            .description("A friendly greeting")
            .user(text)
            .build())
    })
    .build();

let router = McpRouter::new().prompt(greet);

路由器组成

像axum一样组合路由器:

// Merge routers (combines all tools/resources/prompts)
let api_router = McpRouter::new()
    .tool(search_tool)
    .tool(fetch_tool);

let admin_router = McpRouter::new()
    .tool(reset_tool)
    .tool(stats_tool);

let combined = McpRouter::new()
    .merge(api_router)
    .merge(admin_router);

// Nest with prefix (adds prefix to all tool names)
let v1 = McpRouter::new().tool(legacy_tool);
let v2 = McpRouter::new().tool(new_tool);

let versioned = McpRouter::new()
    .nest("v1", v1)   // Tools become "v1_legacy_tool"
    .nest("v2", v2);  // Tools become "v2_new_tool"

多服务器代理

在单个端点后聚合多个后端MCP服务器 McpProxy (特点: proxy).每个后端的工具、资源和提示都有命名空间,以避免冲突:

use tower_mcp::proxy::McpProxy;
use tower_mcp::client::StdioClientTransport;

let proxy = McpProxy::builder("my-proxy", "1.0.0")
    .backend("db", StdioClientTransport::spawn("db-server", &[]).await?)
    .await
    .backend("fs", StdioClientTransport::spawn("fs-server", &[]).await?)
    .await
    .build()
    .await?;

// Tools become db_query, fs_read, etc.
// Serve over any transport.
StdioTransport::new(proxy).run().await?;

每后端Tower中间件适用于单个后端:

use std::time::Duration;
use tower::timeout::TimeoutLayer;

let proxy = McpProxy::builder("proxy", "1.0.0")
    .backend("fast", cache_transport).await
    .backend_layer(TimeoutLayer::new(Duration::from_secs(2)))
    .backend("slow", llm_transport).await
    .backend_layer(TimeoutLayer::new(Duration::from_secs(60)))
    .build().await?;

代理还支持通知转发(后端列表更改事件传播到客户端)、健康检查(proxy.health_check().await),并通过以下方式请求合并 tower-resiliences CoalesceLayer.

后端不需要使用tower mcp构建——代理通过标准mcp(JSON-RPC)进行通信,因此它可以与用任何语言或框架编写的服务器一起工作:Python(FastMCP)、TypeScript、Go或任何使用mcp协议的东西。这使得tower mcp成为多语言mcp部署的自然聚合和中间件层。

proxy 模块文档examples/proxy.rs.

路由器级别状态

使用以下命令在所有处理程序之间共享状态 with_state():

use std::sync::Arc;
use tower_mcp::extract::Extension;

#[derive(Clone)]
struct AppState {
    db: DatabasePool,
    config: Config,
}

let state = Arc::new(AppState { /* ... */ });

// Tools access state via Extension extractor
let tool = ToolBuilder::new("query")
    .extractor_handler(
        (),
        |Extension(app): Extension>, Json(input): Json| async move {
            let result = app.db.query(&input.sql).await?;
            Ok(CallToolResult::text(result))
        },
    )
    .build();

let router = McpRouter::new()
    .with_state(state)  // Makes AppState available to all handlers
    .tool(tool);

运输

Stdio(命令行界面/本地)

use tower_mcp::{McpRouter, StdioTransport};

let router = McpRouter::new()
    .server_info("my-server", "1.0.0")
    .tool(my_tool);

// Serve over stdin/stdout
StdioTransport::new(router).serve().await?;

HTTP与SSE

use tower_mcp::{McpRouter, HttpTransport};

let router = McpRouter::new()
    .server_info("my-server", "1.0.0")
    .tool(my_tool);

let transport = HttpTransport::new(router);
let app = transport.into_router();

// Serve with axum
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000").await?;
axum::serve(listener, app).await?;

使用身份验证中间件

use tower_mcp::auth::extract_api_key;
use axum::middleware;

// Add auth layer to the HTTP transport
let app = transport.into_router()
    .layer(middleware::from_fn(auth_middleware));

MCP中间件

tower mcp在标准tower中间件的基础上提供了三个mcp特定的中间件层:

目标目的
McpTracingLayer所有请求具有请求生命周期跨度的结构化跟踪
ToolCallLoggingLayertools/call带有注释提示的聚焦工具调用审核日志记录
AuditLayer所有请求全面的审计事件(mcp::audit 追踪目标)
use tower::ServiceBuilder;
use tower_mcp::middleware::{AuditLayer, McpTracingLayer};

let transport = StdioTransport::new(router)
    .layer(
        ServiceBuilder::new()
            .layer(McpTracingLayer::new())
            .layer(AuditLayer::new())
            .into_inner(),
    );

标准塔式中间件(超时、速率限制、并发)也通过 .layer() 关于运输工具和个人工具。

测试

塔mcp包括 TestClient (特点: testing)对于进程内服务器测试——无子进程、无网络、无端口管理:

use tower_mcp::TestClient;
use serde_json::json;

let mut client = TestClient::from_router(router);
client.initialize().await;

// List and call tools
let tools = client.list_tools().await;
assert_eq!(tools.len(), 1);

let result = client.call_tool("greet", json!({"name": "World"})).await;
assert_eq!(result.all_text(), "Hello, World!");

// Typed deserialization
let stats: ServerStats = client.call_tool_typed("stats", json!({})).await;

// Assert expected errors
let err = client.call_tool_expect_error("missing", json!({})).await;

TestClient 处理JSON-RPC帧、请求ID和协议初始化。方法对意外错误感到恐慌,保持测试代码简洁。

能力筛选

控制每个会话可以看到哪些工具、资源和提示。这实现了多租户模式,其中不同的客户端根据身份验证声明或会话状态获得不同的功能:

use tower_mcp::CapabilityFilter;

// Hide write tools from sessions that aren't authorized
let router = McpRouter::new()
    .tool(read_tool)
    .tool(write_tool)
    .tool_filter(CapabilityFilter::write_guard(|session| {
        session.get::()
            .map(|r| r.is_admin())
            .unwrap_or(false)
    }));

write_guard 使用工具注释:标记的工具 .read_only() 始终可见,而其他工具仅显示给谓词返回的会话 true.默认情况下,隐藏工具返回“找不到方法”,或配置 DenialBehavior::Unauthorized 在不授予访问权限的情况下披露其存在。

过滤器也适用于资源和提示:

let router = McpRouter::new()
    .resource(public_resource)
    .resource(internal_resource)
    .resource_filter(CapabilityFilter::new(|session, resource: &Resource| {
        !resource.name().contains("internal") || session.get::().is_some()
    }));

建筑

                    +-----------------+
                    |  Your App       |
                    +-----------------+
                           |
                    +-----------------+
                    | Tower Middleware|  <-- tracing, metrics, auth, etc.
                    +-----------------+
                           |
                    +-----------------+
                    | JsonRpcService  |  <-- JSON-RPC 2.0 framing
                    +-----------------+
                           |
                    +-----------------+
                    |   McpRouter     |  <-- Request dispatch
                    +-----------------+
                           |
              +------------+------------+
              |            |            |
         +--------+   +--------+   +--------+
         | Tool 1 |   | Tool 2 |   | Tool N |
         +--------+   +--------+   +--------+

协议遵从

我们跟踪所有MCP规范增强提案(SEP) 。每周工作流同步上游规范存储库的状态。

示例

回购包括23个按主题组织的重点示例:

类别示例
入门getting_started --工具、资源、提示、stdio传输
运输http_server, websocket_server
中间件middleware (运输、每个工具、每个资源、每个提示、警卫), rate_limiting, capability_filtering, tool_selection
认证http_auth, oauth_client, external_api_auth
客户client_cli, http_client, http_sse_client
双向sampling_server, client_handler
动态的dynamic_capabilities --运行时工具/提示/资源注册
高级proxy, resource_templates, structured_output, error_handling, testing
真实的weather_server --外部API集成
tool_macro -- #[tool_fn], #[prompt_fn], #[resource_fn]

克隆仓库和 .mcp.json 自动配置示例服务器:

git clone https://github.com/joshrotenberg/tower-mcp
cd tower-mcp
# Run your MCP agent here - servers will be available automatically

发展

# Format, lint, and test
cargo fmt --all -- --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test --all-features

许可证

麻省理工学院或阿帕奇-2.0

目录标签

目录标签

Rust中间件AI代理Rust库本地部署MCP协议多传输支持协议兼容

接入字段

传输方式(transport,传输协议)

未说明

鉴权方式(authType,认证方式)

oauth

工具数量(toolCount,工具数)

0

资源数量(resourceCount,资源数)

0

提示词数量(promptCount,提示词数)

0

权限和风险

未说明oauth部署方式未说明

接入前请确认传输方式、认证方式和部署位置,并根据实际工具能力限制访问范围。

安装前确认

不要直接授予不必要的文件、网络或账号权限;先核对安装命令和配置内容。

仍需确认:installCommand

来源信息

继续浏览同类 MCP