pub struct Toolset { /* private fields */ }Expand description
Opaque cloneable Toolset over Local, MCP, or downstream behavior.
Clones share admission and cleanup. Dropping a clone alone does not initiate
asynchronous cleanup; explicitly await ToolsetBackend::shutdown.
See crate::ToolsetBackend for a complete example.
Implementations§
Source§impl Toolset
impl Toolset
Sourcepub fn local(registrations: Vec<ToolRegistration>) -> Result<Self, ToolError>
pub fn local(registrations: Vec<ToolRegistration>) -> Result<Self, ToolError>
Builds an in-process Toolset from complete registrations.
§Errors
Returns ToolError::DuplicateName for duplicate names; an empty inventory is valid.
See crate::ToolsetBackend for a complete example.
Sourcepub async fn mcp(config: McpClientConfig) -> Result<Self, ToolError>
pub async fn mcp(config: McpClientConfig) -> Result<Self, ToolError>
Connects one MCP client Toolset and discovers its inventory. This example requires a running MCP service at the configured endpoint.
§Errors
Returns ToolError for invalid connection settings, process startup, transport or initialization failure, malformed inventory, or an elapsed request deadline.
§Examples
use tools_kit::mcp::{McpClientConfig, McpConnectionConfig};
let connection = McpConnectionConfig::StreamableHttp {
endpoint: "http://127.0.0.1:8000/mcp".parse().unwrap(),
headers: Default::default(),
};
let config = McpClientConfig::new(connection);
use tools_kit::{Toolset, ToolsetBackend};
let tools = Toolset::mcp(config).await?;
let inventory = tools.list_tools().await;
let cleanup = tools.shutdown().await;
if let Err(error) = &cleanup {
eprintln!("Cleanup failed: {error}");
}
let _ = inventory?;
cleanup?;
Sourcepub fn from_backend<B: ToolsetBackend>(backend: B) -> Self
pub fn from_backend<B: ToolsetBackend>(backend: B) -> Self
Wraps a downstream Toolset implementation. The associated handler is normalized privately. Concrete callers may instead retain the backend directly; there is no public child normalization constructor.
§Examples
use std::sync::atomic::{AtomicBool, Ordering};
use tools_kit::{ToolError, Toolset, ToolsetBackend, ToolHandlerBackend};
use tools_kit::declaration::{ToolInfo, ToolName};
use tools_kit::execution::{ToolHandlerInput, ToolHandlerOutput};
struct EmptyInventory { closed: AtomicBool }
enum NoHandler {}
impl ToolHandlerBackend for NoHandler {
async fn step(&mut self, _: ToolHandlerInput) -> Result<ToolHandlerOutput, ToolError> {
match *self {}
}
}
impl ToolsetBackend for EmptyInventory {
type Handler = NoHandler;
async fn list_tools(&self) -> Result<Vec<ToolInfo>, ToolError> {
if self.closed.load(Ordering::Acquire) {
return Err(ToolError::Closed { operation: "list_tools".into() });
}
Ok(Vec::new())
}
async fn tool_handler(&self, name: ToolName) -> Result<NoHandler, ToolError> {
if self.closed.load(Ordering::Acquire) {
return Err(ToolError::Closed { operation: "tool_handler".into() });
}
Err(ToolError::UnknownTool { name })
}
async fn shutdown(&self) -> Result<(), ToolError> {
self.closed.store(true, Ordering::Release);
Ok(()) // This empty implementation owns no asynchronous resources.
}
}
let concrete = EmptyInventory { closed: AtomicBool::new(false) };
assert!(concrete.list_tools().await?.is_empty());
let normalized = Toolset::from_backend(concrete);
normalized.shutdown().await?;
assert!(normalized.list_tools().await.is_err());