* fix: address PR review - schema_for_output no longer validates or returns Result - Add strip_output() that strips title/description without validating type (Dale #1) - Change schema_for_output to return Arc<JsonObject> instead of Result (Dale #2) - Cache only Arc<JsonObject> success values, not Result (Dale #3) - Remove dead unwrap_or_else panic paths in with_output_schema, ToolBase, and macros - Tighten test assertions from contains to assert_eq on type field (Dale #4) - Update test_schema_for_output_rejects_primitive to accept_primitive (SEP-2106) Co-authored-by: Orca <help@stably.ai> * test(rmcp): add non-object output schema tests for SEP-2106 Add tests verifying schema_for_output accepts non-object types: - test_tool_builder_methods: primitive (i32), array (Vec<String>), option - test_structured_output: tool returning Json<Vec<T>> and Json<i32> - test_json_schema_detection: Json<Vec<T>>, Result<Json<Vec<T>>,E>, Json<String> - tool_traits: ToolBase::output_schema with Vec<AddOutput> output type * test(rmcp): add missing edge case tests from code review Add tests identified during code review: - description stripping for primitive types - composition types (Option<String> with anyOf/oneOf/null) - cache correctness (Arc::ptr_eq for repeated calls) - schema_for_input rejecting array types (not just primitives) - schema_for_output accepting unit type () * feat!: mark schema_for_output return-type change as breaking This introduces SEP-2106: schema_for_output no longer validates or returns Result. The public signature changed, so bump major. * fix: address Dale's PR review - direct schema.get assertions, remove ArrayTool - Replace loose schema_str.contains(...) assertions with direct schema.get("type") equality checks in test_tool_builder_methods.rs and test_structured_output.rs - Remove redundant ArrayTool fixture and its round-trip serde_json::from_str test from tool_traits.rs since schema is already Arc<JsonObject> - Drop dead schema_str variable in test_structured_output.rs --------- Co-authored-by: Brandon Bennett <brandonbennett@macbookair.myfiosgateway.com> Co-authored-by: Orca <help@stably.ai> Co-authored-by: Brandon Bennett <brandonbennett@Pursuits-Air.lan> |
||
|---|---|---|
| .. | ||
| src | ||
| Cargo.toml | ||
| CHANGELOG.md | ||
| README.md | ||
Procedural macros for the RMCP SDK. Most users should depend on rmcp with the macros feature (enabled by default) rather than using this crate directly.
For getting started and full MCP feature documentation, see the main README.
Available Macros
| Macro | Description |
|---|---|
#[tool] |
Mark a function as an MCP tool handler |
#[tool_router] |
Generate a tool router from an impl block (optional server_handler flag elides a separate #[tool_handler] block for tools-only servers) |
#[tool_handler] |
Generate call_tool and list_tools handler methods |
#[prompt] |
Mark a function as an MCP prompt handler |
#[prompt_router] |
Generate a prompt router from an impl block |
#[prompt_handler] |
Generate get_prompt and list_prompts handler methods |
#[task_handler] |
Wire up the task lifecycle on top of an OperationProcessor |
Quick Example
Tools-only server with a single impl block (server_handler expands #[tool_handler] in a second macro pass):
use rmcp::{tool, tool_router};
#[derive(Clone)]
struct MyServer;
#[tool_router(server_handler)]
impl MyServer {
#[tool(description = "Say hello")]
async fn hello(&self) -> String {
"Hello, world!".into()
}
}
If you need custom #[tool_handler(...)] arguments (e.g. instructions, name, or stacked #[prompt_handler] on the same impl ServerHandler), use two blocks instead:
use rmcp::{tool, tool_router, tool_handler, ServerHandler};
#[derive(Clone)]
struct MyServer;
#[tool_router]
impl MyServer {
#[tool(description = "Say hello")]
async fn hello(&self) -> String {
"Hello, world!".into()
}
}
#[tool_handler]
impl ServerHandler for MyServer {}
See the full documentation for detailed usage of each macro.
License
This project is licensed under the terms specified in the repository's LICENSE file.