Add detailed documentation with examples for: - hanzo-tools-fs: read, write, edit, tree, find, search, ast - hanzo-tools-shell: cmd, ps, zsh, bash, auto-backgrounding - hanzo-tools-browser: 70+ Playwright actions, device emulation - hanzo-tools-memory: memories, facts, knowledge bases, scopes - hanzo-tools-reasoning: think and critic tools - hanzo-tools-lsp: go-to-definition, references, rename, hover - hanzo-tools-refactor: rename, extract, inline, batch operations - hanzo-tools-agent: multi-agent orchestration, consensus, swarm - hanzo-tools-llm: unified LLM interface with 100+ models Each doc includes: - Installation instructions - Quick start examples - Full API reference - Usage examples - Best practices
5.6 KiB
hanzo-tools-core
The foundation package for all Hanzo tool implementations. Provides base classes, type definitions, and utilities for building MCP-compatible tools.
Installation
pip install hanzo-tools-core
Or as part of the full toolkit:
pip install hanzo-mcp[tools-all]
Overview
hanzo-tools-core provides:
- BaseTool - Abstract base class for all tool implementations
- FileSystemTool - Specialized base for file operations
- ToolRegistry - Central registry for tool management
- MCPResourceDocument - Structured response format
- ToolContext - Runtime context for tool execution
- PermissionManager - Path-based access control
Quick Start
Creating a Custom Tool
from hanzo_tools.core import BaseTool, ToolContext
class MyTool(BaseTool):
"""A custom tool implementation."""
@property
def name(self) -> str:
return "my_tool"
@property
def description(self) -> str:
return "Does something useful"
async def call(self, ctx: ToolContext, message: str) -> str:
"""Execute the tool.
Args:
ctx: Tool execution context
message: Input message to process
Returns:
Processed result
"""
return f"Processed: {message}"
def register(self, mcp_server):
"""Register with MCP server."""
@mcp_server.tool(name=self.name, description=self.description)
async def handler(message: str) -> str:
ctx = ToolContext()
return await self.call(ctx, message=message)
Using the Tool Registry
from hanzo_tools.core import ToolRegistry, BaseTool
# Register tools
registry = ToolRegistry()
registry.register(MyTool())
# Get a tool by name
tool = registry.get("my_tool")
# List all registered tools
for name, tool in registry.items():
print(f"{name}: {tool.description}")
Base Classes
BaseTool
The abstract base class all tools must inherit from:
from abc import ABC, abstractmethod
class BaseTool(ABC):
"""Abstract base class for all Hanzo tools."""
@property
@abstractmethod
def name(self) -> str:
"""Unique identifier for the tool."""
...
@property
@abstractmethod
def description(self) -> str:
"""Human-readable description shown to LLMs."""
...
@abstractmethod
async def call(self, ctx: ToolContext, **params) -> str:
"""Execute the tool with given parameters."""
...
@abstractmethod
def register(self, mcp_server: FastMCP) -> None:
"""Register the tool with an MCP server."""
...
FileSystemTool
Specialized base class for tools that operate on the filesystem:
from hanzo_tools.core import FileSystemTool
class ReadTool(FileSystemTool):
"""Read file contents."""
@property
def name(self) -> str:
return "read"
async def call(self, ctx, file_path: str) -> str:
# Automatic path validation and permission checking
validated_path = self.validate_path(file_path)
async with aiofiles.open(validated_path) as f:
return await f.read()
Response Format
MCPResourceDocument
Structured format for tool responses:
from hanzo_tools.core import MCPResourceDocument
# Create a document response
doc = MCPResourceDocument(
uri="file:///path/to/file.py",
mime_type="text/x-python",
text="def hello(): pass"
)
# Convert to JSON string for MCP
response = doc.to_json_string()
Context Management
ToolContext
Runtime context passed to every tool invocation:
from hanzo_tools.core import ToolContext, create_tool_context
# Create context with custom settings
ctx = create_tool_context(
allowed_paths=["/home/user/project"],
enable_write=True,
timeout=30.0
)
# Access context in tool
async def call(self, ctx: ToolContext, **params):
if ctx.enable_write:
# Perform write operation
...
Permission Management
PermissionManager
Controls which paths tools can access:
from hanzo_tools.core import PermissionManager
pm = PermissionManager(
allowed_paths=[
"/home/user/project",
"/tmp"
],
denied_paths=[
"/home/user/project/.env",
"/home/user/project/secrets"
]
)
# Check if path is allowed
if pm.is_allowed("/home/user/project/src/main.py"):
# Safe to access
...
Decorators
auto_timeout
Automatically handle timeouts for long-running operations:
from hanzo_tools.core import auto_timeout
class SlowTool(BaseTool):
@auto_timeout(seconds=30)
async def call(self, ctx, **params):
# Will automatically timeout after 30 seconds
result = await slow_operation()
return result
Error Handling
Tools should return error messages as strings rather than raising exceptions:
async def call(self, ctx, file_path: str) -> str:
try:
content = await read_file(file_path)
return content
except FileNotFoundError:
return f"Error: File not found: {file_path}"
except PermissionError:
return f"Error: Permission denied: {file_path}"
except Exception as e:
return f"Error: {type(e).__name__}: {str(e)}"
API Reference
::: hanzo_tools.core.base.BaseTool options: show_source: false members: - name - description - call - register
::: hanzo_tools.core.base.FileSystemTool
::: hanzo_tools.core.base.ToolRegistry
::: hanzo_tools.core.types.MCPResourceDocument
::: hanzo_tools.core.context.ToolContext
::: hanzo_tools.core.permissions.PermissionManager