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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions