mirror of
https://github.com/hanzoai/python-sdk.git
synced 2026-10-23 20:23:00 +00:00
docs(hanzo-tools): add README with architecture, API, and usage examples
This commit is contained in:
@@ -0,0 +1,222 @@
|
||||
# hanzo-tools
|
||||
|
||||
Core infrastructure and plugin framework for Hanzo AI's modular MCP tool system.
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
pip install hanzo-tools # Core only
|
||||
pip install hanzo-tools[dev] # filesystem, shell, editor, lsp, refactor, todo, reasoning, config
|
||||
pip install hanzo-tools[ai] # llm, agent, memory
|
||||
pip install hanzo-tools[all] # Everything
|
||||
```
|
||||
|
||||
Individual tool packages can be installed separately:
|
||||
|
||||
```bash
|
||||
pip install hanzo-tools-fs
|
||||
pip install hanzo-tools-shell
|
||||
pip install hanzo-tools-browser
|
||||
pip install hanzo-tools-llm
|
||||
pip install hanzo-tools-memory
|
||||
pip install hanzo-tools-editor
|
||||
pip install hanzo-tools-vector
|
||||
# ... etc
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Register all discovered tools
|
||||
|
||||
```python
|
||||
from hanzo_tools import discover_tools, register_all
|
||||
from mcp.server import FastMCP
|
||||
|
||||
mcp = FastMCP("my-server")
|
||||
|
||||
# Auto-discover and register all installed tool packages
|
||||
registered = register_all(mcp)
|
||||
```
|
||||
|
||||
### Register individual tool packages
|
||||
|
||||
```python
|
||||
from hanzo_tools.fs import register_tools as register_fs
|
||||
from hanzo_tools.shell import register_tools as register_shell
|
||||
|
||||
register_fs(mcp, permission_manager)
|
||||
register_shell(mcp)
|
||||
```
|
||||
|
||||
### Build a custom tool
|
||||
|
||||
```python
|
||||
from typing import Any
|
||||
from mcp.server import FastMCP
|
||||
from mcp.server.fastmcp import Context as MCPContext
|
||||
from hanzo_tools.core import BaseTool, ToolRegistry, with_error_logging
|
||||
|
||||
class WeatherTool(BaseTool):
|
||||
@property
|
||||
def name(self) -> str:
|
||||
return "get_weather"
|
||||
|
||||
@property
|
||||
def description(self) -> str:
|
||||
return "Get current weather for a location"
|
||||
|
||||
@with_error_logging("get_weather")
|
||||
async def call(self, ctx: MCPContext, **params: Any) -> str:
|
||||
location = params["location"]
|
||||
return f"Weather in {location}: 72°F, sunny"
|
||||
|
||||
def register(self, mcp_server: FastMCP) -> None:
|
||||
@mcp_server.tool()
|
||||
async def get_weather(location: str, ctx: MCPContext) -> str:
|
||||
"""Get current weather for a location."""
|
||||
return await self.call(ctx, location=location)
|
||||
|
||||
# Register with the MCP server
|
||||
ToolRegistry.register_tool(mcp, WeatherTool())
|
||||
```
|
||||
|
||||
### Filesystem tools with permissions
|
||||
|
||||
```python
|
||||
from hanzo_tools.core import FileSystemTool, PermissionManager
|
||||
|
||||
pm = PermissionManager(
|
||||
allowed_paths=["/home/user/projects"],
|
||||
deny_patterns=[".git", "node_modules", ".env"],
|
||||
)
|
||||
|
||||
class ReadFileTool(FileSystemTool):
|
||||
def __init__(self):
|
||||
super().__init__(permission_manager=pm)
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
return "read_file"
|
||||
|
||||
@property
|
||||
def description(self) -> str:
|
||||
return "Read a file"
|
||||
|
||||
async def call(self, ctx, **params):
|
||||
path = params["path"]
|
||||
if not self.is_path_allowed(path):
|
||||
return "Access denied"
|
||||
return open(path).read()
|
||||
|
||||
def register(self, mcp_server):
|
||||
@mcp_server.tool()
|
||||
async def read_file(path: str, ctx) -> str:
|
||||
"""Read a file."""
|
||||
return await self.call(ctx, path=path)
|
||||
```
|
||||
|
||||
### Decorators
|
||||
|
||||
```python
|
||||
from hanzo_tools.core import auto_timeout, with_error_logging, handle_connection_errors
|
||||
|
||||
@auto_timeout("search", timeout=120)
|
||||
@with_error_logging("search")
|
||||
@handle_connection_errors
|
||||
async def search_files(pattern: str, path: str) -> str:
|
||||
...
|
||||
```
|
||||
|
||||
Timeouts are configurable via environment variables:
|
||||
|
||||
```bash
|
||||
HANZO_TIMEOUT_SEARCH=300 # Override search timeout to 5 minutes
|
||||
HANZO_TIMEOUT_BROWSER=600 # Override browser timeout to 10 minutes
|
||||
```
|
||||
|
||||
### Tool enable/disable
|
||||
|
||||
```python
|
||||
from hanzo_tools.core import ToolRegistry
|
||||
|
||||
# Disable a tool at runtime
|
||||
ToolRegistry.set_tool_enabled("browser", False)
|
||||
|
||||
# Check if a tool is enabled
|
||||
if ToolRegistry.is_tool_enabled("browser"):
|
||||
...
|
||||
```
|
||||
|
||||
Tool states persist to `~/.hanzo/mcp/tool_states.json`.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
hanzo-tools (core)
|
||||
├── BaseTool — Abstract base for all tools
|
||||
├── FileSystemTool — Base for filesystem tools with permissions
|
||||
├── ToolRegistry — Enable/disable and registration
|
||||
├── ToolContext — Execution context with logging/progress
|
||||
├── PermissionManager — Path-based access control
|
||||
├── MCPResourceDocument — Structured response formatting
|
||||
├── auto_timeout — Configurable async timeouts
|
||||
├── with_error_logging — Error logging to ~/.hanzo/mcp/logs/
|
||||
├── handle_connection_errors — Graceful disconnect handling
|
||||
├── validate_path_parameter — Path validation
|
||||
├── discover_tools() — Plugin discovery via entry points
|
||||
└── register_all() — Auto-register all discovered tools
|
||||
|
||||
hanzo-tools-fs — File read/write/search/glob
|
||||
hanzo-tools-shell — Shell command execution
|
||||
hanzo-tools-browser — Browser automation (Playwright)
|
||||
hanzo-tools-editor — Code editing with AST awareness
|
||||
hanzo-tools-lsp — Language Server Protocol integration
|
||||
hanzo-tools-refactor — Refactoring operations
|
||||
hanzo-tools-llm — LLM inference tools
|
||||
hanzo-tools-agent — Agent orchestration
|
||||
hanzo-tools-memory — Persistent memory/context
|
||||
hanzo-tools-vector — Vector DB operations
|
||||
hanzo-tools-database — Database query tools
|
||||
hanzo-tools-jupyter — Jupyter notebook tools
|
||||
hanzo-tools-todo — Task/todo management
|
||||
hanzo-tools-reasoning — Chain-of-thought reasoning
|
||||
hanzo-tools-config — Configuration management
|
||||
hanzo-tools-mcp — MCP protocol utilities
|
||||
hanzo-tools-computer — Computer use (screen/keyboard)
|
||||
```
|
||||
|
||||
Tool packages register via `importlib.metadata` entry points (`group="hanzo.tools"`), enabling automatic discovery without explicit imports.
|
||||
|
||||
## API
|
||||
|
||||
### Core Classes
|
||||
|
||||
| Class | Purpose |
|
||||
|-------|---------|
|
||||
| `BaseTool` | Abstract base — implement `name`, `description`, `call()`, `register()` |
|
||||
| `FileSystemTool` | Extends BaseTool with `permission_manager` and `validate_path()` |
|
||||
| `ToolRegistry` | Class-level enable/disable with JSON persistence |
|
||||
| `ToolContext` | Wraps MCP context with `info()`, `warning()`, `error()`, `progress()` |
|
||||
| `PermissionManager` | Allowed paths + deny patterns for filesystem access control |
|
||||
| `MCPResourceDocument` | Response type with `to_json_string()`, `to_readable_string()`, `to_dict()` |
|
||||
| `ValidationResult` | Boolean result with optional error message |
|
||||
|
||||
### Decorators
|
||||
|
||||
| Decorator | Purpose |
|
||||
|-----------|---------|
|
||||
| `@auto_timeout(name, timeout=None)` | Async timeout with env var override (`HANZO_TIMEOUT_*`) |
|
||||
| `@with_error_logging(name)` | Log errors to `~/.hanzo/mcp/logs/` and return friendly messages |
|
||||
| `@handle_connection_errors` | Catch disconnects gracefully |
|
||||
| `@retry(max_attempts, delay, backoff)` | Exponential backoff retry |
|
||||
|
||||
### Top-level Functions
|
||||
|
||||
| Function | Purpose |
|
||||
|----------|---------|
|
||||
| `discover_tools()` | Find all installed tool packages via entry points |
|
||||
| `register_all(mcp, pm, enabled)` | Register all discovered tools with an MCP server |
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
Reference in New Issue
Block a user