Adding a New Tool¶
Overview¶
In OpenSage, tools are implemented as Agent Skills (bash scripts) or MCP toolsets (Model Context Protocol), rather than Python functions. This design allows tools to be executed directly in sandbox containers via bash commands, providing better isolation and flexibility.
Tool Types¶
1. Agent Skills (Bash Scripts)¶
Agent Skills are bash scripts organized in a structured directory format with metadata. They are automatically discovered and loaded by the framework.
2. MCP Toolsets¶
MCP (Model Context Protocol) toolsets provide integration with external services or tools running in separate containers, typically accessed via SSE (Server-Sent Events) connections.
Creating an Agent Skill¶
Directory Structure¶
Create a skill directory under src/<package>/bash_tools/:
src/<package>/bash_tools/
└── category/
└── tool-name/
├── SKILL.md # Tool metadata and documentation
└── scripts/
└── tool_script.sh # The actual bash script
Example structure:
SKILL.md Format¶
The SKILL.md file contains YAML frontmatter and markdown documentation:
---
name: tool-name
description: Brief description of what the tool does
---
# Tool Name
Detailed description of the tool's functionality.
## Usage
```bash
scripts/tool_script.sh arg1 arg2 --option value
Parameters¶
param1 (required, positional position 0)¶
Type: str
Description of the parameter.
param2 (optional, positional position 1)¶
Type: int
Description of the parameter.
--option (optional, named parameter)¶
Type: str
Description of the option.
--flag (optional, flag)¶
Type: bool (default: false)
Description of the flag.
Return Value¶
Returns a JSON object with results:
Requires Sandbox¶
main
Timeout¶
Default timeout: 60 seconds
### Parameter Types
- **Positional parameters**: Specified with `positional position N` in the parameter description
- **Named parameters**: Use `--param_name value` format
- **Boolean flags**: Use `--flag` (no value needed)
### Bash Script Implementation
The bash script should:
1. Accept command-line arguments (positional and named)
2. Return JSON output for structured results
3. Use proper exit codes (0 for success, non-zero for errors)
**Example script:**
```bash
#!/bin/bash
# tool_script.sh - Tool description
# Usage: ./tool_script.sh param1 param2 --option value
if [ -z "$1" ]; then
echo '{"error": "Missing required parameter"}'
exit 1
fi
PARAM1="$1"
PARAM2="${2:-default}"
# Process --option if provided
OPTION=""
while [[ $# -gt 0 ]]; do
case $1 in
--option)
OPTION="$2"
shift 2
;;
*)
shift
;;
esac
done
# Tool logic here
RESULT=$(some_command "$PARAM1" "$PARAM2")
# Return JSON
echo "{\"success\": true, \"result\": \"$RESULT\"}"
Sandbox Requirements¶
Specify required sandbox types in the ## Requires Sandbox section:
Or for multiple sandboxes:
Automatic Discovery¶
Tools are automatically discovered from: - src/<package>/bash_tools/ (built-in tools) - ~/.local/plugins/<product>/tools/ (user plugins)
The framework scans these directories for SKILL.md files and loads them automatically.
Creating an MCP Toolset¶
MCP toolsets are created via Python functions that return MCPToolset instances:
# src/<package>/toolbox/category/get_toolset.py
from google.adk.tools.mcp_tool.mcp_toolset import MCPToolset, SseConnectionParams
from <package>.toolbox.decorators import requires_sandbox, safe_tool_execution
from <package>.utils.agent_utils import get_mcp_url_from_session_id
@safe_tool_execution
@requires_sandbox("gdb_mcp")
def get_toolset(aigise_session_id: str) -> MCPToolset:
"""Create MCPToolset with GDB MCP server running in Docker container.
Args:
aigise_session_id: Shared session ID for session-based management
Returns:
MCPToolset connected to GDB MCP server
"""
url = get_mcp_url_from_session_id("gdb_mcp", aigise_session_id)
mcp_toolset = MCPToolset(connection_params=SseConnectionParams(url=url))
return mcp_toolset
The function should: - Use @safe_tool_execution decorator - Use @requires_sandbox to specify required sandbox types - Return an MCPToolset instance - Be registered in the agent's tools list
Tool Registration¶
For Agent Skills¶
Agent Skills are automatically discovered and registered. No manual registration needed.
For MCP Toolsets¶
Add the toolset getter function to your agent's tools:
from <package>.toolbox.category.get_toolset import get_toolset
agent = AigiseAgent(
name="my_agent",
tools=[get_toolset, ...], # Add the getter function
...
)
Best Practices¶
- Use bash scripts for container operations: Prefer bash scripts for tools that interact with sandbox containers
- Return JSON: Always return structured JSON from bash scripts for easy parsing
- Document thoroughly: Include clear parameter descriptions and usage examples in
SKILL.md - Handle errors gracefully: Use proper exit codes and error messages
- Specify sandbox requirements: Always document which sandboxes are required
- Use MCP for external services: Use MCP toolsets for tools that run in separate containers or services
See Also¶
- Common Patterns - Tool development patterns
- Best Practices - Best practices for tools
- Core Concepts - Understanding tools in context