anyclaw_sdk_tool/lib.rs
1//! Tool SDK for anyclaw.
2//!
3//! Provides the [`Tool`] trait for building MCP-compatible tools and
4//! [`ToolServer`] for serving them over stdio.
5//!
6//! # Stability
7//!
8//! This crate is **unstable** — APIs may change between releases.
9//! Enums marked `#[non_exhaustive]` will have new variants added; match arms must include `_`.
10#![warn(missing_docs)]
11
12/// Error types for tool SDK operations.
13pub mod error;
14/// MCP tool server that dispatches to [`Tool`] implementations.
15// D-03 boundary: Tool I/O is inherently dynamic — JSON Schema input, arbitrary JSON output.
16// All Value usages in server.rs flow from the Tool trait contract being Value-based.
17#[allow(clippy::disallowed_types)]
18pub mod server;
19/// The [`Tool`] trait that tool authors implement.
20// D-03 boundary: Tool I/O uses Value because tool input is defined by a JSON Schema
21// (no fixed Rust type) and tool output is arbitrary JSON. See trait_def.rs doc comments.
22#[allow(clippy::disallowed_types)]
23pub mod trait_def;
24
25pub use error::ToolSdkError;
26pub use server::ToolServer;
27pub use trait_def::{DynTool, Tool};
28
29#[cfg(test)]
30mod tests {
31 use super::*;
32 use rstest::rstest;
33
34 #[rstest]
35 fn when_tool_sdk_error_reexported_then_accessible() {
36 let err = ToolSdkError::ExecutionFailed("test".into());
37 assert!(err.to_string().contains("test"));
38 }
39
40 #[rstest]
41 fn when_tool_trait_reexported_then_accessible() {
42 // Verify Tool trait is usable as a bound through the re-export
43 fn _accepts_tool<T: Tool>(_t: &T) {}
44 }
45
46 #[rstest]
47 fn when_dyn_tool_alias_reexported_then_accessible() {
48 // Verify DynTool is a valid trait object type through the re-export
49 fn _accepts_dyn_tool(_t: &dyn DynTool) {}
50 }
51}