2 releases

Uses new Rust 2024

0.4.1 Mar 10, 2026
0.4.0 Mar 10, 2026

#2014 in Asynchronous


Used in 6 crates

MIT/Apache

180KB
3.5K SLoC

skg-tool

Tool interface and registry for skelegent agents

crates.io docs.rs license

Overview

skg-tool defines the ToolDyn trait and ToolRegistry that operators use to expose callable functions to models. Tools are described via JSON Schema, called with a serde_json::Value input, and return a serde_json::Value result. Any tool source (local function, MCP server, HTTP endpoint) implements ToolDyn.

Exports

  • ToolDyn — object-safe trait: name(), description(), input_schema(), call(input), maybe_streaming(), concurrency_hint()
  • ToolRegistrynew(), register(Arc<dyn ToolDyn>), get(name), iter(), len(), is_empty()
  • ToolDynStreaming — optional streaming trait: call_streaming(input, on_chunk)
  • ToolConcurrencyHintShared | Exclusive (default)
  • AliasedTool — wraps a ToolDyn under a different name: new(alias, inner), inner()
  • ToolErrorNotFound, ExecutionFailed, InvalidInput, Other

Usage

[dependencies]
skg-tool = "0.4"
serde_json = "1"

Implementing a tool

use skg_tool::{ToolDyn, ToolError};
use serde_json::{json, Value};
use std::future::Future;
use std::pin::Pin;

pub struct UppercaseTool;

impl ToolDyn for UppercaseTool {
    fn name(&self) -> &str { "uppercase" }

    fn description(&self) -> &str { "Convert text to uppercase" }

    fn input_schema(&self) -> Value {
        json!({
            "type": "object",
            "properties": {
                "text": { "type": "string" }
            },
            "required": ["text"]
        })
    }

    fn call(
        &self,
        input: Value,
    ) -> Pin<Box<dyn Future<Output = Result<Value, ToolError>> + Send + '_>> {
        Box::pin(async move {
            let text = input["text"]
                .as_str()
                .ok_or_else(|| ToolError::InvalidInput("missing text".into()))?;
            Ok(json!({ "result": text.to_uppercase() }))
        })
    }
}

Registering and calling tools

use skg_tool::ToolRegistry;
use std::sync::Arc;

let mut registry = ToolRegistry::new();
registry.register(Arc::new(UppercaseTool));

if let Some(tool) = registry.get("uppercase") {
    let result = tool.call(serde_json::json!({"text": "hello"})).await?;
}

Part of the skelegent workspace

skelegent is a composable async agentic AI framework for Rust.

Dependencies

~1–2MB
~40K SLoC