Crate turbomcp_macros

Crate turbomcp_macros 

Source
Expand description

§TurboMCP Macros

Zero-overhead procedural macros for ergonomic MCP server development, providing compile-time code generation for MCP protocol handlers with graceful shutdown support.

§Features

§Core Macros

  • #[server] - Convert structs into MCP servers with transport methods and graceful shutdown
  • #[tool] - Mark methods as MCP tool handlers with automatic schema generation
  • #[prompt] - Mark methods as MCP prompt handlers with template support
  • #[resource] - Mark methods as MCP resource handlers with URI templates

§Advanced Features (Enhanced in 1.0.3)

  • Roots Configuration - Declarative filesystem roots in #[server] macro: root = "file:///path:Name"
  • Compile-Time Routing - Zero-cost compile-time router generation (experimental)
  • Enhanced Context System - Improved async handling and error propagation
  • Server Attributes - Support for name, version, description, and roots in server macro

§Helper Macros

  • mcp_error! - Ergonomic error creation with formatting
  • mcp_text! - Text content creation helpers
  • tool_result! - Tool result formatting
  • elicit! - High-level elicitation macro for interactive user input

§Usage

§Basic Server with Tools

use turbomcp::prelude::*;

#[derive(Clone)]
struct Calculator {
    operations: std::sync::Arc<std::sync::atomic::AtomicU64>,
}

#[server(
    name = "calculator-server",
    version = "1.0.0",
    description = "A mathematical calculator service",
    root = "file:///workspace:Project Workspace",
    root = "file:///tmp:Temporary Files"
)]
impl Calculator {
    #[tool("Add two numbers")]
    async fn add(&self, ctx: Context, a: i32, b: i32) -> McpResult<i32> {
        ctx.info(&format!("Adding {} + {}", a, b)).await?;
        self.operations.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
        Ok(a + b)
    }
     
    #[tool("Divide two numbers")]
    async fn divide(&self, a: f64, b: f64) -> McpResult<f64> {
        if b == 0.0 {
            return Err(mcp_error!("Cannot divide by zero"));
        }
        Ok(a / b)
    }

    #[resource("calc://history/{operation}")]
    async fn history(&self, operation: String) -> McpResult<String> {
        Ok(format!("History for {} operations", operation))
    }

    #[prompt("Generate report for {operation} with {count} operations")]
    async fn report(&self, operation: String, count: i32) -> McpResult<String> {
        Ok(format!("Generated report for {} ({} operations)", operation, count))
    }
}

§Elicitation Support (New in 1.0.3)

use turbomcp::prelude::*;
use turbomcp::elicitation_api::{string, boolean, ElicitationResult};

#[derive(Clone)]
struct InteractiveServer;

#[server]
impl InteractiveServer {
    #[tool("Configure with user input")]
    async fn configure(&self, ctx: Context) -> McpResult<String> {
        let result = elicit!("Configure your preferences")
            .field("theme", string()
                .enum_values(vec!["light", "dark"])
                .build())
            .field("auto_save", boolean()
                .description("Enable auto-save")
                .build())
            .send(&ctx.request)
            .await?;

        match result {
            ElicitationResult::Accept(data) => {
                let theme = data.get::<String>("theme")?;
                Ok(format!("Configured with {} theme", theme))
            }
            _ => Err(mcp_error!("Configuration cancelled"))
        }
    }
}

Macros§

elicit
Ergonomic elicitation macro for server-initiated user input
mcp_error
Helper macro for creating MCP errors
mcp_text
Helper macro for creating MCP ContentBlock structures (advanced usage)
tool_result
Helper macro for creating CallToolResult structures (advanced usage)

Attribute Macros§

completion
Marks a method as a completion handler for argument autocompletion
elicitation
Marks a method as an elicitation handler for gathering user input
ping
Marks a method as a ping handler for connection health monitoring
prompt
Marks a method as a prompt handler
resource
Marks a method as a resource handler
server
Marks an impl block as a TurboMCP server (idiomatic Rust)
template
Marks a method as a resource template handler
tool
Marks a method as a tool handler