The Tooling Layer - Transform agent decisions into actions via unified tool abstractions
Project description
Agent Tooling: The Tooling Layer
Vision & Purpose
The Tooling Layer is the action engine of the AI Agent Stack. It translates agent decisions into real-world effects by providing a unified interface for tools that interact with databases, APIs, file systems, and external services.
This repository implements the concepts from the Agent Stack Whitepaper, specifically the Tooling section which covers:
- Tool Definitions: Name, description, input/output schemas
- Function Calling: Structured JSON tool invocations
- Tool Composition: Building complex tools from atomic ones
- MCP Integration: Model Context Protocol for tool sharing
"From decisions to actions - unified tool abstractions for AI agents."
๐ฆ Installation
From PyPI (Recommended)
pip install agent-tooling-layer
# With MCP server support:
pip install "agent-tooling-layer[mcp]"
# With HTTP server support:
pip install "agent-tooling-layer[server]"
# Everything:
pip install "agent-tooling-layer[all]"
From Source
git clone https://github.com/jasperan/agent-tooling.git
cd agent-tooling
pip install -e .
๐ Notebooks
Interactive Jupyter notebooks demonstrating tool capabilities:
| Name | Description | Link |
|---|---|---|
| agent_tooling_demo | Comprehensive demo of all tool categories with arena mode |
๐ Features
โ Unified Tool Abstraction
@toolDecorator: Define tools with automatic schema generation- Direct + MCP: Same tool works both ways
- Type-Safe: Pydantic validation for inputs/outputs
- Auto-Documentation: Schemas generated from docstrings
๐ ๏ธ Tool Categories
| Category | Tools | Description |
|---|---|---|
| Developer | read_file, write_file, execute_python, execute_shell |
File system and code execution |
| Data | query_database, call_api, fetch_json, scrape_webpage |
Database and API access |
| Cognitive | calculate, web_search, wikipedia_search |
Reasoning support tools |
| Communication | send_email, slack_notify, webhook |
Notifications (coming soon) |
| Media | analyze_image, read_pdf, transcribe |
File processing (coming soon) |
๐ Tool Composition
Build complex workflows from atomic tools:
from agent_tooling import ToolComposer, ToolStep
# Research Assistant: search -> summarize -> save
research = ToolComposer.sequential(
name="research_assistant",
description="Search, summarize, and save results",
tools=[
ToolStep("web_search", output_key="results"),
ToolStep("summarize", input_mapping={"text": "results"}),
ToolStep("write_file", input_mapping={"content": "summary"}),
]
)
๐ป Usage
1. Interactive CLI
# Launch interactive menu
agent-tooling
# List all tools
agent-tooling --list
# Arena mode: compare tools
agent-tooling --arena
# Start MCP server
agent-tooling --mcp
Interactive Experience:
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ AGENT TOOLING CLI โ
โ The Tooling Layer of the AI Agent Stack โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
? Select an action:
List Tools
Run Tool
Arena: Compare Tools
Dashboard
MCP Server
Exit
2. Python API
from agent_tooling import tool, ToolRegistry
# Define a custom tool
@tool(name="greet", category="custom", mcp_enabled=True)
def greet(name: str, formal: bool = False) -> str:
"""Generate a greeting message.
Args:
name: Name of the person to greet
formal: Whether to use formal language
Returns:
A greeting message
"""
if formal:
return f"Good day, {name}. How may I assist you?"
return f"Hey {name}! What's up?"
# Use directly
result = greet(name="Alice", formal=True)
print(result.data) # "Good day, Alice. How may I assist you?"
# Get schema for function calling
schema = greet.to_openai_function()
3. Using Built-in Tools
from agent_tooling.tools.developer import read_file, execute_python
from agent_tooling.tools.cognitive import calculate, web_search
# Read a file
result = read_file(path="README.md")
print(result.data[:100])
# Execute Python code
result = execute_python(code="result = sum(range(100))")
print(result.data) # {'return_value': 4950, ...}
# Calculate
result = calculate(expression="sqrt(144) + pi")
print(result.data) # {'result': 15.14159...}
# Search the web
results = web_search(query="Python MCP protocol")
for r in results.data:
print(f"- {r['title']}: {r['url']}")
4. MCP Server Mode
Expose your tools to any MCP-compatible client (Claude, etc.):
# Start MCP server
agent-tooling --mcp
# Or from Python
from agent_tooling.mcp import create_mcp_server
server = create_mcp_server(name="my-tools")
server.run_stdio()
5. HTTP Server Mode
# Start HTTP server on port 8082
agent-tooling-server --port 8082
Then use the REST API:
# List tools
curl http://localhost:8082/tools
# Execute a tool
curl -X POST http://localhost:8082/execute \
-H "Content-Type: application/json" \
-d '{"name": "calculate", "parameters": {"expression": "2 + 2"}}'
# Get OpenAI function schemas
curl http://localhost:8082/schemas/openai
๐ง Architecture
The @tool Decorator
The decorator extracts everything needed from your function:
@tool(name="my_tool", category="custom", mcp_enabled=True)
def my_tool(required_param: str, optional_param: int = 10) -> dict:
"""Short description for the tool.
Args:
required_param: Description of this parameter
optional_param: Description with default value
Returns:
What the tool returns
"""
return {"result": f"{required_param}: {optional_param}"}
Automatically generates:
- JSON Schema for validation
- OpenAI function calling format
- MCP tool format
- Parameter validation
Tool Result
All tools return a ToolResult:
ToolResult(
success=True, # Did it work?
data={"key": "value"}, # The result data
error=None, # Error message if failed
tool_name="my_tool", # Which tool produced this
execution_time_ms=12.5, # How long it took
metadata={}, # Additional info
)
Registry
Tools are automatically registered:
from agent_tooling import ToolRegistry
# List all tools
for tool in ToolRegistry.list_tools():
print(f"{tool['name']}: {tool['description']}")
# Get a specific tool
tool = ToolRegistry.get("calculate")
result = tool.run(expression="1 + 1")
# Get schemas for function calling
schemas = ToolRegistry.to_openai_functions()
๐ Visual Modes
Arena Mode
Compare multiple tools on the same task:
from agent_tooling.visualization import ToolArena
arena = ToolArena()
arena.compare(
tools=["web_search", "wikipedia_search"],
query="machine learning"
)
Dashboard
Real-time monitoring of tool activity:
from agent_tooling.visualization import ToolDashboard
dashboard = ToolDashboard()
dashboard.start() # Live terminal UI
Traces
Step-by-step execution visualization:
from agent_tooling.visualization import ToolTracer
tracer = ToolTracer()
with tracer.trace("my_workflow") as trace:
trace.add_step("fetch_data", "input", {"url": "..."})
trace.add_step("process", "process", {"items": 100})
trace.add_step("save", "output", {"path": "result.json"})
๐ Appendix A: Adding Custom Tools
- Create a new file in
src/agent_tooling/tools/your_category/:
from agent_tooling import tool, ToolError
@tool(name="my_custom_tool", category="your_category", mcp_enabled=True)
def my_custom_tool(param1: str, param2: int = 0) -> dict:
"""Description of what this tool does.
Args:
param1: First parameter description
param2: Second parameter with default
Returns:
Dictionary with results
"""
try:
# Your implementation
return {"result": f"Processed {param1} with {param2}"}
except Exception as e:
raise ToolError(str(e), tool_name="my_custom_tool")
- Import it in the category's
__init__.py - The tool is now available everywhere!
๐ง Appendix B: Troubleshooting
- Tool not found: Ensure the tool module is imported before use
- MCP connection failed: Check that the server is running in stdio mode
- Timeout errors: Increase timeout parameter for slow operations
- Permission denied: Check file/network access permissions
๐งช Appendix C: Tool Samples (Demo Mode)
Run agent-tooling --demo to execute all safe samples interactively. Use flags to include more:
agent-tooling --demo # Safe tools only
agent-tooling --demo --demo-network # Include network-dependent tools
agent-tooling --demo --demo-ollama # Include Ollama-dependent tools
agent-tooling --demo --demo-all # Run everything
agent-tooling --demo-json # Output results as JSON
Below are sample inputs and outputs for each tool category.
Cognitive Tools
calculate โ Evaluate mathematical expressions
| Sample | Input | Output |
|---|---|---|
| Basic arithmetic | {"expression": "2 + 2"} |
{"result": 4, "type": "int"} |
| Scientific | {"expression": "sqrt(144) + pow(2, 3)"} |
{"result": 20.0, "type": "float"} |
| Trigonometry | {"expression": "sin(pi / 2)"} |
{"result": 1.0, "type": "float"} |
web_search โ Search the web (requires network)
| Sample | Input |
|---|---|
| Tech search | {"query": "Python MCP protocol", "num_results": 3} |
wikipedia_search โ Wikipedia lookup (requires network)
| Sample | Input |
|---|---|
| Science lookup | {"query": "Large language model", "sentences": 3} |
Data Tools
query_database โ Execute SQL queries
| Sample | Input | Output |
|---|---|---|
| Mock SELECT | {"sql": "SELECT * FROM users LIMIT 5"} |
{"rows": [{"id": 1, "name": "Example Row 1"}, {"id": 2, "name": "Example Row 2"}], "row_count": 2} |
call_api โ HTTP API requests (requires network)
| Sample | Input |
|---|---|
| Get IP | {"url": "https://httpbin.org/ip", "method": "GET"} |
fetch_json โ Fetch JSON data (requires network)
| Sample | Input |
|---|---|
| Fetch UUID | {"url": "https://httpbin.org/uuid"} |
Developer Tools
read_file โ Read file contents
| Sample | Input | Output (truncated) |
|---|---|---|
| Read self | {"path": "src/agent_tooling/tools/developer/filesystem.py"} |
"""File System Tools - Read, write, and navigate... |
file_exists โ Check if a path exists
| Sample | Input | Output |
|---|---|---|
| Check README | {"path": "README.md"} |
{"exists": true, "is_file": true, "is_dir": false} |
execute_python โ Execute Python code
| Sample | Input | Output |
|---|---|---|
| Sum range | {"code": "result = sum(range(1, 101))"} |
{"return_value": 5050} |
| List comprehension | {"code": "result = [x**2 for x in range(10)]"} |
{"return_value": [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]} |
get_file_info โ File metadata
| Sample | Input | Output (key fields) |
|---|---|---|
| Info self | {"path": "src/.../filesystem.py"} |
{"name": "filesystem.py", "is_file": true, "size_bytes": 18721, "extension": ".py"} |
search_files โ Search for patterns in files
| Sample | Input | Output |
|---|---|---|
| Search imports | {"pattern": "from agent_tooling", "include_glob": "*.py", "max_results": 5} |
[{"file": "tests/test_tools.py", "line": 4, "content": "from agent_tooling import ..."}] |
Media Tools
analyze_image โ Vision analysis via Ollama llava (requires Ollama)
| Sample | Input |
|---|---|
| Describe URL | {"source": "https://example.com/photo.png"} |
pdf_to_markdown โ Convert PDF to markdown
| Sample | Input | Output |
|---|---|---|
| Convert sample | {"path": "sample.pdf"} |
"# Agent Tooling - Sample Document\n\n## Introduction\n\nThis is a sample PDF..." |
summarize_pdf โ Summarize PDF via Ollama (requires Ollama)
| Sample | Input |
|---|---|
| Summarize sample | {"path": "sample.pdf", "max_pages": 1} |
๐ License
MIT License - see LICENSE for details.
Related Projects
- agent-reasoning - The Reasoning Layer
- agent-application - The Application Layer (coming soon)
- agent-infrastructure - The Infrastructure Layer (coming soon)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file agent_tooling_layer-0.1.0.tar.gz.
File metadata
- Download URL: agent_tooling_layer-0.1.0.tar.gz
- Upload date:
- Size: 61.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
41521e45a69f6577af801dad2c7447dd723d0670d5476746f59a8351140f1719
|
|
| MD5 |
36958fd04a6eece3d98b5cb473b025e2
|
|
| BLAKE2b-256 |
917898d02095b779ddc0862c1e8efe8dc3d26b6cf841c041dc893876eed38112
|
File details
Details for the file agent_tooling_layer-0.1.0-py3-none-any.whl.
File metadata
- Download URL: agent_tooling_layer-0.1.0-py3-none-any.whl
- Upload date:
- Size: 67.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bbe611a8ed9729bc63a246c72ee17f72258282db08bbf1b037c2d7b6b1f78678
|
|
| MD5 |
6098b9d9ac9a16858b78948d826e058f
|
|
| BLAKE2b-256 |
b1b15e268e598253bcbb2cc2b5ae9e608e8e6481edf4185deeacbd6602ee5ad5
|