Skip to main content

Toolcase

Type-safe, extensible tool framework for AI agents.

Features

  • Async-first with sync compatibility
  • Type-safe parameters via Pydantic generics
  • Monadic error handling with Result[T, E] types
  • Multi-framework converters (OpenAI, Anthropic, Google)
  • MCP protocol & HTTP server for Cursor/Claude Desktop
  • Middleware pipeline (logging, retry, timeout, rate limiting, circuit breaker)
  • Agentic primitives (router, fallback, race, gate, escalation)
  • Structured concurrency with TaskGroup and CancelScope
  • Distributed tracing (OTLP, Datadog, Honeycomb, Zipkin)
  • Caching with TTL (memory, Redis, Memcached)
  • Dependency injection with scoped lifecycle
  • Streaming with SSE, WebSocket, JSON Lines adapters

Installation

pip install toolcase

# Optional integrations
pip install toolcase[mcp]        # MCP protocol (Cursor, Claude Desktop)
pip install toolcase[http]       # HTTP REST server
pip install toolcase[langchain]  # LangChain tools
pip install toolcase[redis]      # Redis cache backend
pip install toolcase[otel]       # OpenTelemetry exporters
pip install toolcase[all]        # Everything

Quick Start

from toolcase import tool, init_tools

@tool(description="Search the web")
async def search(query: str, limit: int = 5) -> str:
    return f"Found {limit} results for: {query}"

registry = init_tools(search)  # Registers discovery tool + your tools
result = await registry.execute("search", {"query": "python", "limit": 3})

Class-Based Tools

from pydantic import BaseModel, Field
from toolcase import BaseTool, ToolMetadata

class SearchParams(BaseModel):
    query: str = Field(..., description="Search query")
    limit: int = Field(default=5, ge=1, le=20)

class SearchTool(BaseTool[SearchParams]):
    metadata = ToolMetadata(name="search", description="Search the web", category="search")
    params_schema = SearchParams

    async def _async_run(self, params: SearchParams) -> str:
        return f"Found {params.limit} results for: {params.query}"

Core Concepts

Middleware Pipeline

from toolcase import LoggingMiddleware, RetryMiddleware, TimeoutMiddleware

registry.use(LoggingMiddleware())
registry.use(RetryMiddleware(max_retries=3))
registry.use(TimeoutMiddleware(30.0))

Monadic Error Handling

from toolcase import Ok, Err, Result, try_tool_operation

def _run_result(self, params) -> Result[str, ToolError]:
    return (
        self._validate(params)
        .flat_map(lambda p: self._fetch(p))
        .map(lambda d: self._format(d))
    )

# Auto-wrap exceptions
result = try_tool_operation("my_tool", lambda: risky_call())
match result:
    case Ok(value): print(value)
    case Err(error): print(error.message)

See docs/MONADIC_ERRORS.md for complete guide.

Agentic Composition

from toolcase import router, fallback, race, gate, Route

smart_search = router(Route(lambda p: "code" in p["query"], code_search), default=web_search)
resilient = fallback(primary_api, backup_api, cache)  # Try until success
fastest = race(api_a, api_b, timeout=5.0)             # First success wins
premium = gate(lambda ctx: ctx.get("is_premium"), expensive_tool)

Multi-Framework Export

from toolcase.foundation.formats import to_openai, to_anthropic, to_google

openai_tools = to_openai(registry)      # OpenAI function calling
anthropic_tools = to_anthropic(registry) # Anthropic tool_use
gemini_tools = to_google(registry)       # Google Gemini

MCP & HTTP Server

from toolcase.ext.mcp import serve_mcp, serve_http

serve_mcp(registry, transport="sse", port=8080)  # Cursor, Claude Desktop
serve_http(registry, port=8000)                   # REST API

Dependency Injection

from toolcase import Container, Scope

container = Container()
container.provide("db", lambda: Database(), Scope.SINGLETON)
container.provide("http", lambda: httpx.AsyncClient(), Scope.SCOPED)

async with container.scope() as ctx:
    db = await container.resolve("db", ctx)

Batch Execution

from toolcase import BatchConfig

params_list = [{"query": q} for q in ["python", "rust", "go"]]
results = await tool.batch_run(params_list, BatchConfig(concurrency=5))
print(f"Success: {results.success_rate:.0%}")

Streaming

from toolcase import sse_adapter

@tool(description="Stream response", streaming=True)
async def stream_search(query: str):
    for i in range(10):
        yield f"Result {i} for {query}"

async for event in sse_adapter(stream_search.stream({"query": "test"})):
    print(event)

Observability

from toolcase import configure_tracing, configure_logging, TracingMiddleware

configure_tracing(exporter="otlp", endpoint="http://localhost:4317")
configure_logging(level="INFO", json=True)
registry.use(TracingMiddleware())

Testing

from toolcase import ToolTestCase, mock_tool

class TestSearch(ToolTestCase):
    async def test_search(self):
        tool = mock_tool("search", return_value="mocked")
        result = await tool.run({"query": "test"})
        self.assert_success(result)

Settings & Environment

from toolcase import get_settings, load_env

load_env()  # Load .env files
settings = get_settings()
print(settings.cache.ttl, settings.retry.max_retries)

CLI Help

toolcase help              # List topics
toolcase help tool         # Tool creation
toolcase help middleware   # Middleware pipeline
toolcase help agents       # Agentic patterns
toolcase help mcp          # MCP/HTTP server
toolcase help result       # Monadic errors

API Reference

Core

BaseTool[T] · ToolMetadata · ToolCapabilities · @tool · init_tools

Errors

Result[T, E] · Ok · Err · ErrorCode · ToolError · try_tool_operation

Runtime

Middleware · compose · pipeline · parallel · streaming_pipeline

Agents

router · fallback · race · gate · retry_with_escalation

Concurrency

TaskGroup · CancelScope · Lock · Semaphore · run_sync

Observability

configure_tracing · configure_logging · TracingMiddleware · Span

IO

ToolCache · MemoryCache · StreamChunk · StreamEvent · BatchConfig

License

Griffin License - Made by GriffinCanCode

See LICENSE for full terms.

Release files for toolcase 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for toolcase 0.1.0
File Size Uploaded
toolcase-0.1.0.tar.gz 326.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for toolcase 0.1.0
File Interpreter ABI Platform
toolcase-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 760.3 kB

Release files / toolcase-0.1.0.tar.gz

Download URL toolcase-0.1.0.tar.gz
Size 326.6 kB
Tags Source
SHA-256 checksum
How to use checksums
f39a8176c7928918c67e1bd5f5954d52a34b8b2584f2254cc62e4929b044ed02
BLAKE2b-256 checksum
How to use checksums
b3a44e460d5cdc866bf2c36ef69f5ce80369747fe2b549333b5c555ab9569ed4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.0

Release files / toolcase-0.1.0-py3-none-any.whl

Download URL toolcase-0.1.0-py3-none-any.whl
Size 433.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
44b67beeffa02e031599c1bae975b03753f94cd1cad428869148a4e23d6c06b0
BLAKE2b-256 checksum
How to use checksums
d41c6c46c69c7119bb18d174954fa13ab441dd587c5380938e1c94a804293f3d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.0

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page