Skip to content

Structured tool output + schema #312

Open
@crepererum

Description

@crepererum

Is your feature request related to a problem? Please describe.
Currently it seems that tools that are created via the #[tool] macro can only return unstructured output without a schema:

#[derive(Debug, serde::Deserialize, schemars::JsonSchema)]
struct WeatherRequest {
    #[schemars(description = "longitude")]
    long: f64,

    #[schemars(description = "latitude")]
    lat: f64,
}

#[derive(Debug, serde::Serialize, schemars::JsonSchema)]
struct WeatherResult {
    #[schemars(description = "temperature in degrees Kelvin")]
    temp: f64,

    #[schemars(description = "humidity in percentage")]
    humidity: f64,
}

#[tool_router]
struct WeatherService {
    #[tool(description = "get weather for given location")]
    async fn get_weather(
        &self,
        Parameters(WeatherRequest { lat, long }): Parameters<WeatherRequest>,
    ) -> Result<CallToolResult, McpError> {
        // unstructured result w/o a schema
        Ok(CallToolResult::success(vec![
            Content::json(WeatherResult {
                temp: 4.2,
                humidity: 50.0,
            }).unwrap()
        ]))
    }
}

Describe the solution you'd like
It seems that the macro already reads the input schema from the parameters. Maybe we can directly return a structured result and have the schema registered for that in the tool metadata?

// ... WeatherRequest and WeatherResult as above

#[tool_router]
struct WeatherService {
    #[tool(description = "get weather for given location")]
    async fn get_weather(
        &self,
        Parameters(WeatherRequest { lat, long }): Parameters<WeatherRequest>,
    ) -> Result<WeatherResult, McpError> {
        // structured result w/ a schema
        Ok(WeatherResult {
            temp: 4.2,
            humidity: 50.0,
        })
    }
}

Describe alternatives you've considered
Not supporting structured content or hand-writing the respective code.

Additional context

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions