magi-tool 0.0.3

provide tools for Magi AI agents
Documentation
# magi-tool

Tool schema generation and MCP service management for LLM tool calling.

## Features

- **Tool Schema Generation** - Convert Rust types to JSON Schema for LLM tool definitions
- **PegBoard** (optional) - Manage multiple MCP services with automatic tool discovery and namespace conflict resolution
- **Thread-Safe** - Designed for concurrent access in async Rust applications
- **Type-Safe** - Full Rust type safety for tool parameters

### Feature Flags

- `pegboard` (enabled by default) - Includes the PegBoard service manager and rmcp integration
  - Disable with `default-features = false` if you only need tool schema generation

```toml
# Full features (default)
magi-tool = "0.0.1"

# Tool schema generation only (faster compile, smaller binary)
magi-tool = { version = "0.0.1", default-features = false }
```

## Quick Example

```rust
use magi_tool::{get_tool, PegBoard};
use schemars::JsonSchema;
use std::sync::Arc;

#[derive(JsonSchema, serde::Deserialize)]
struct WeatherParams {
    /// The city and state, e.g. San Francisco, CA
    location: String,
    unit: Option<String>,
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create a tool definition
    let tool = get_tool::<WeatherParams, _, _>(
        "get_weather",
        Some("Get the current weather"),
    )?;

    // Or use PegBoard to manage multiple MCP services
    let mut pegboard = PegBoard::new();

    // Automatically discover tools from services
    pegboard.add_service(Some("web".to_string()), web_service).await?;
    pegboard.add_service(Some("fs".to_string()), fs_service).await?;

    // Share across tokio tasks
    let pegboard = Arc::new(pegboard);

    // Get all tools for LLM
    let tools = pegboard.get_all_tools();

    // Execute tool calls from LLM (automatic routing)
    let result = pegboard.call_tool(
        "web-search",
        serde_json::json!({"query": "rust programming"}),
    ).await?;

    println!("Result: {:?}", result.structured_content);

    Ok(())
}
```

## Documentation

See the [`docs/`](./docs) folder for comprehensive documentation:

- **[Getting Started]./docs/README.md** - Overview and quick start
- **[PegBoard Design]./docs/PEGBOARD_DESIGN.md** - Complete API reference and architecture
- **[Tokio Usage]./docs/TOKIO_USAGE.md** - Async patterns and examples
- **[Optional Namespace]./docs/OPTIONAL_NAMESPACE.md** - When and how to use namespaces
- **[Changes]./docs/CHANGES.md** - Implementation history and migration guide

## Key Concepts

### Tool Schema Generation

Generate JSON schemas from Rust types for LLM tool definitions:

```rust
#[derive(JsonSchema, serde::Deserialize)]
struct SearchParams {
    query: String,
    max_results: Option<u32>,
}

let tool = get_tool::<SearchParams, _, _>("search", Some("Search the web"))?;
```

### PegBoard with Namespace Support

Manage multiple MCP services with optional name prefixing:

```rust
// WITH namespace - tools get prefixed to avoid conflicts
pegboard.add_service(Some("web".to_string()), web_service).await?;
// tool "search" becomes "web-search"

// WITHOUT namespace - use original names
pegboard.add_service(None, calculator_service).await?;
// tool "add" stays "add"
```

### Automatic Tool Discovery

PegBoard calls `list_tools()` on each service automatically:

```rust
// Register service - tools are discovered automatically
let count = pegboard.add_service(Some("fs".to_string()), service).await?;
println!("Discovered {} tools", count);
```

## Testing

```bash
cargo test -p magi-tool
```

## License

See workspace root for license information.