Skip to content

Reduce boilerplate: derive/default ServerHandler for simple tool servers #711

@sco3

Description

@sco3

Is your feature request related to a problem? Please describe.

Problem

Building a minimal stateless tool server requires a ServerHandler
implementation that contains no real logic — just static metadata:

#[tool_handler]
impl ServerHandler for TimeServer {
    fn get_info(&self) -> ServerInfo {
        ServerInfo {
            protocol_version: ProtocolVersion::V_2025_03_26,
            capabilities: ServerCapabilities::builder().enable_tools().build(),
            server_info: Implementation::new("time-server", "0.1.0"),
            instructions: None,
        }
    }
}

Describe the solution you'd like
Option A — attribute macro on the impl block:

#[tool_router]
#[mcp(name = "time-server", version = "0.1.0")]
impl TimeServer {
    #[tool(description = "Get current time")]
    async fn get_time(&self) -> Result<CallToolResult, McpError> { ... }
}
// No ServerHandler impl needed

Describe alternatives you've considered
Option B — derive macro with Cargo.toml defaults (like clap):

#[derive(McpServer)]
struct TimeServer;

Option C — provide a default get_info() that reads
env!("CARGO_PKG_NAME") and env!("CARGO_PKG_VERSION").

Additional context
Any of these would reduce the minimal server to just
the struct + tool definitions.

Quarkus MCP (Java) requires only annotated methods — no boilerplate:
That's the entire server. No handler trait, no capabilities declaration,
no server info struct. The framework infers everything:

* Name/version from project metadata
* Capabilities from which annotations are present
* Protocol version from the library version
public class PlantUmlTool {

    @Tool(description = "Renders a PlantUML string into a SVG image.")
    public ImageContent renderDiagram(
        @ToolArg(
            description = "The PlantUML source code (starting with @startuml and ending with @enduml)."
        ) String source
    ) throws Exception {

        // removed code

        return new ImageContent(base64Image, "image/svg+xml");
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions