Tool Call Protocol and the 40+ Built-in Tool Ecosystem
Chapter 18: Tool Calling Protocol and the 40+ Built-in Tool Ecosystem
One of Hermes Agent's core competitive advantages is its out-of-the-box suite of 40+ built-in tools. These tools cover the full spectrum from web access and file operations to code execution and multimedia processing — the "hands and feet" through which an Agent perceives and changes the world. This chapter provides a comprehensive overview of the tool classification system, the JSON calling protocol, custom registration methods, and permission control mechanisms.
18.1 Tool Classification System
Hermes built-in tools are organized into six functional domains:
Hermes Tool Ecosystem
├── System Tools — terminal, processes, environment variables
├── Network Tools — search, HTTP, scraping
├── File Tools — read/write, directories, compression
├── Code Tools — execution, debugging, analysis
├── Multimedia Tools — images, audio, video, PDF
└── Platform Tools — Git, Docker, databases, APIs
Complete Tool Reference
System Tools (8)
| Tool Name | Description | Typical Use Cases |
|---|---|---|
terminal |
Execute shell commands | Run scripts, install packages |
process_manager |
Manage background processes | Start/stop services |
env_manager |
Read/write environment variables | Configuration management |
cron_scheduler |
Schedule periodic tasks | Background automation |
system_info |
Get system metrics | CPU/memory/disk monitoring |
clipboard |
Read/write clipboard | Content passing between tools |
notification |
Send system notifications | Task completion alerts |
sleep |
Wait for specified duration | Polling interval control |
Network Tools (9)
| Tool Name | Description | Typical Use Cases |
|---|---|---|
web_search |
Multi-engine web search | Information retrieval |
browser_navigate |
Browser navigation (Playwright) | Dynamic page access |
browser_click |
Click page elements | Form filling, interactions |
browser_screenshot |
Capture webpage screenshots | Visual verification |
http_request |
Send HTTP requests | API calls |
rss_reader |
Read RSS feeds | News aggregation |
html_extract |
Extract webpage content | Data scraping |
link_checker |
Check link availability | Dead link detection |
dns_lookup |
DNS resolution | Network diagnostics |
File Tools (7)
| Tool Name | Description | Typical Use Cases |
|---|---|---|
file_read |
Read file contents | Code analysis, config reading |
file_write |
Write to files | Generate reports, save results |
file_search |
Fuzzy file search | Locate code files |
directory_list |
List directory contents | Project structure exploration |
file_compress |
Compress/decompress files | Packaging and distribution |
file_diff |
Compare file differences | Code review |
file_watch |
Monitor file changes | Hot-reload triggers |
Code Tools (6)
| Tool Name | Description | Typical Use Cases |
|---|---|---|
code_execute |
Execute code snippets | Python/JS sandbox execution |
code_lint |
Static code analysis | Style checking |
code_format |
Format code | black/prettier |
code_test |
Run test suites | pytest/jest |
code_debug |
Debug code | Breakpoint tracing |
repl |
Interactive REPL session | Experimental code testing |
Multimedia Tools (6)
| Tool Name | Description | Typical Use Cases |
|---|---|---|
image_analyze |
Visual image analysis | OCR, object recognition |
image_generate |
Generate images | DALL-E/Stable Diffusion |
image_edit |
Edit images | Crop, filters |
audio_transcribe |
Speech-to-text (Whisper) | Meeting transcription |
pdf_extract |
Extract PDF content | Document analysis |
chart_generate |
Generate charts (Mermaid/matplotlib) | Data visualization |
Platform Tools (8)
| Tool Name | Description | Typical Use Cases |
|---|---|---|
git_operations |
Git version control | Commits, branches, merges |
docker_manage |
Docker container management | Deploy, test environments |
database_query |
Database queries (SQL/NoSQL) | Data analysis |
api_call |
Call external APIs | Third-party service integration |
email_send |
Send emails | Automated notifications |
calendar_manage |
Calendar management | Meeting scheduling |
spreadsheet |
Spreadsheet operations (Excel/CSV) | Data processing |
cloud_storage |
Cloud storage (S3/OSS) | File upload/download |
18.2 Tool Calling JSON Protocol
Hermes uses a strictly defined JSON protocol for tool calls, consisting of "call request" and "call response" objects.
18.2.1 Tool Call Request Format
{
"tool_calls": [
{
"id": "call_abc123",
"type": "function",
"function": {
"name": "web_search",
"arguments": {
"query": "Hermes Agent latest version features",
"max_results": 10,
"search_engine": "google",
"date_range": "past_month",
"safe_search": true
}
}
}
]
}
18.2.2 Tool Call Response Format
{
"tool_results": [
{
"tool_call_id": "call_abc123",
"role": "tool",
"name": "web_search",
"content": {
"status": "success",
"results": [
{
"title": "Hermes 4: NousResearch's Latest Agent Model",
"url": "https://nousresearch.com/hermes-4",
"snippet": "Hermes 4 introduces improved function calling...",
"score": 0.95
}
],
"total_results": 847000,
"query_time_ms": 342
}
}
]
}
18.2.3 Complete Multi-Tool Call Sequence
// Step 1: Agent decision, initiating tool call
{
"role": "assistant",
"content": null,
"tool_calls": [
{
"id": "call_001",
"type": "function",
"function": {
"name": "web_search",
"arguments": {
"query": "Python asyncio best practices 2024",
"max_results": 5
}
}
}
]
}
// Step 2: Tool execution result returned
{
"role": "tool",
"tool_call_id": "call_001",
"content": "Found 5 results: [...]"
}
// Step 3: Agent decides to call second tool based on results
{
"role": "assistant",
"content": null,
"tool_calls": [
{
"id": "call_002",
"type": "function",
"function": {
"name": "file_write",
"arguments": {
"path": "/output/asyncio_summary.md",
"content": "# Python AsyncIO Best Practices\n\n..."
}
}
}
]
}
// Step 4: Second tool result
{
"role": "tool",
"tool_call_id": "call_002",
"content": "{\"success\": true, \"path\": \"/output/asyncio_summary.md\"}"
}
// Step 5: Agent final reply to user
{
"role": "assistant",
"content": "I've completed the research and saved the results to /output/asyncio_summary.md..."
}
18.2.4 Tool Schema Definition
Each tool's parameter structure follows JSON Schema Draft 7:
{
"name": "http_request",
"description": "Send an HTTP request and return the response content",
"parameters": {
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "Target URL, must begin with http:// or https://",
"format": "uri"
},
"method": {
"type": "string",
"enum": ["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD"],
"default": "GET"
},
"headers": {
"type": "object",
"additionalProperties": {"type": "string"}
},
"body": {
"type": ["string", "object", "null"]
},
"timeout_seconds": {
"type": "integer",
"minimum": 1,
"maximum": 300,
"default": 30
},
"follow_redirects": {
"type": "boolean",
"default": true
}
},
"required": ["url"]
}
}
18.3 Custom Tool Registration
Beyond the 40+ built-in tools, Hermes supports three methods for registering custom tools.
Method 1: Python Decorator
The simplest approach, ideal for rapid prototyping:
from hermes.tools import tool, ToolResult
@tool(
name="weather_query",
description="Query current weather and forecast for a specified city",
tags=["weather", "external-api"],
timeout_seconds=15,
)
def get_weather(
city: str,
days: int = 3,
unit: str = "celsius",
) -> ToolResult:
import requests
api_key = os.environ["WEATHER_API_KEY"]
response = requests.get(
"https://api.weatherapi.com/v1/forecast.json",
params={"key": api_key, "q": city, "days": days},
timeout=10,
)
data = response.json()
return ToolResult(
success=True,
output={
"city": data["location"]["name"],
"current_temp": data["current"]["temp_c"],
"condition": data["current"]["condition"]["text"],
"forecast": [
{
"date": day["date"],
"max": day["day"]["maxtemp_c"],
"min": day["day"]["mintemp_c"],
}
for day in data["forecast"]["forecastday"]
],
}
)
Method 2: YAML Configuration File
Suited for DevOps pipelines — no code changes required:
# tools/custom_tools.yaml
tools:
- name: jira_create_ticket
description: "Create a ticket in Jira"
type: http_wrapper
endpoint: "https://your-org.atlassian.net/rest/api/3/issue"
method: POST
auth:
type: basic
username_env: JIRA_USER
password_env: JIRA_API_TOKEN
parameters:
- name: summary
type: string
required: true
- name: priority
type: string
enum: [Highest, High, Medium, Low, Lowest]
default: Medium
- name: project_key
type: string
required: true
tags: [jira, project-management]
timeout_seconds: 30
hermes tool register --config ./tools/custom_tools.yaml
Method 3: Inheriting BaseTool
For complex tools requiring full lifecycle control:
from hermes.tools import BaseTool, ToolResult, ToolContext
class DatabaseQueryTool(BaseTool):
name = "database_query_advanced"
description = "Execute SQL or NoSQL queries against PostgreSQL/MySQL/MongoDB"
async def setup(self):
self.connection_pool = {}
async def run(self, params: dict, context: ToolContext) -> ToolResult:
dialect = params.get("dialect", "postgresql")
conn = await self._get_connection(params["connection_string"], dialect)
try:
result = await self._execute_query(conn, params["query"], dialect)
return ToolResult(
success=True,
output={
"rows": result.rows,
"row_count": len(result.rows),
"columns": result.columns,
"query_time_ms": result.execution_time_ms,
}
)
except Exception as e:
return ToolResult(success=False, error=str(e))
async def teardown(self):
for conn in self.connection_pool.values():
await conn.close()
18.4 Tool Permission Control
Hermes implements a fine-grained tool permission system to prevent unauthorized operations.
Permission Hierarchy
Global Permissions
└── Session Permissions
└── Tool Permissions
└── Parameter-level Restrictions
Permission Configuration
# hermes_permissions.yaml
profiles:
readonly_research:
allow:
- network:search
- network:fetch
- file:read
deny:
- file:write
- file:delete
- terminal:execute
full_developer:
allow: ["*"]
deny:
- env:write
restrictions:
file:write:
allowed_paths: [/workspace/**, /tmp/**]
denied_paths: [/workspace/.env, /workspace/secrets/**]
terminal:execute:
denied_commands: ["rm -rf /", ":(){ :|:& };:"]
production_deploy:
allow: [git:read, docker:run, network:fetch]
deny: [terminal:execute, file:delete]
approval_required: [docker:run, database:write]
Runtime Permission Check
class PermissionChecker:
def check(self, tool_name: str, params: dict, context: AgentContext) -> PermissionResult:
required = self._get_tool_permissions(tool_name)
for perm in required:
if perm in context.permission_profile.denied:
return PermissionResult(
allowed=False,
reason=f"Permission {perm} is denied in the current profile"
)
if tool_name == "file_write":
path = params.get("path", "")
if not self._is_path_allowed(path, context):
return PermissionResult(
allowed=False,
reason=f"Path {path} is outside the allowed write scope"
)
return PermissionResult(allowed=True)
18.5 Summary
This chapter provided a comprehensive overview of the Hermes Agent tool ecosystem:
- Six tool categories: System / Network / File / Code / Multimedia / Platform, 40+ tools ready out of the box
- JSON calling protocol: Standardized
tool_calls/tool_resultsformat, OpenAI-compatible - Three registration methods: Decorator (quick), YAML config (DevOps-friendly), BaseTool inheritance (full control)
- Fine-grained permission system: Four-layer permission model with path-level and command-level controls
- Telemetry and monitoring: Built-in tool usage statistics for observability dashboards
Review Questions
-
When an Agent invokes multiple tools simultaneously (parallel tool calling), how do you ensure the result ordering correctly maps back to each
tool_call_id? -
The
file_writetool uses glob pattern matching for path restrictions. If a user requests writing to/workspace/../etc/passwd, how is the path traversal attack defended against? -
Custom YAML-configured tools can be hot-loaded without restarting Hermes. During a hot-reload, how are in-flight tool calls protected from interruption?