Specialized Tool Classes
MARSYS provides specialized tool classes that encapsulate domain-specific functionality for agents with structured APIs, error handling, and configuration management.
On This Page
Overview
Tool classes provide:
Structured Output
Consistent Dict/JSON responses for easy parsing
Error Handling
Comprehensive error classification and recovery
Configuration
Environment variables or explicit parameters
Security
Validation, timeouts, output size limits
Tool Class Comparison
| Tool Class | Operations | API Keys | Security Features |
|---|---|---|---|
| FileOperationTools | 6 file ops | None | Base dir restriction, path validation |
| BashTools | 10 commands | None | Blocked patterns, whitelist, timeout |
| SearchTools | 5 sources | None required (Google optional) | API key validation, rate limits |
| BrowserAgent | Browser control | None | Timeout, mode restrictions |
FileOperationTools
High-level file system operations with type-aware handling.
Capabilities
Read, write, edit (unified diff), search content, find files, list directories
Key Features
- Type-aware file reading (Python, JSON, PDF, Markdown, images)
- Unified diff editing for precise changes
- Ripgrep-based content search
- Glob/regex file finding
- Base directory restrictions for security
from marsys.environment.file_operations import FileOperationToolsfrom pathlib import Pathfile_tools = FileOperationTools(base_directory=Path("/project"),force_base_directory=True # Jail to base directory)# Get tools dict for agenttools = file_tools.get_tools()
Use with: FileOperationAgent, or custom agents needing file operations. See File Operations Guide for complete documentation.
BashTools
Safe bash command execution with validation and specialized helpers.
Capabilities
Execute commands, grep, find, sed, awk, tail, head, wc, diff, streaming execution
Key Features
- Command validation with blocked dangerous patterns
- Whitelisting support for production
- Timeout enforcement
- Output size limits (prevents memory exhaustion)
- Specialized helper methods for common operations
from marsys.environment.bash_tools import BashToolsbash_tools = BashTools(working_directory="/project",allowed_commands=["grep", "find", "wc"], # Whitelisttimeout_default=30)# Get tools dict for agenttools = bash_tools.get_tools()
Use with: FileOperationAgent (optional), or custom agents needing shell access.
SearchTools
Multi-source search across web and scholarly databases.
Capabilities
DuckDuckGo, Google, arXiv, Semantic Scholar, PubMed search
Key Features
- API key validation at initialization
- Only exposes tools with valid credentials
- Optional API keys for higher rate limits (Semantic Scholar, PubMed)
- Configurable result limits (max 20 per query)
from marsys.environment.search_tools import SearchToolsimport ossearch_tools = SearchTools(google_api_key=os.getenv("GOOGLE_SEARCH_API_KEY"),google_cse_id=os.getenv("GOOGLE_CSE_ID_GENERIC"))# Get tools (validates API keys, raises ValueError if missing)try:tools = search_tools.get_tools(tools_subset=["duckduckgo", "arxiv"])except ValueError as e:print(f"Missing required API keys: {e}")
Use with: WebSearchAgent, or custom agents needing search capabilities. See Built-in Tools Guide for search setup.
BrowserAgent
Browser automation through the BrowserAgent class with Playwright integration.
Capabilities
Navigate, click, type, screenshot, JavaScript execution, element extraction
Key Features
- Two modes: PRIMITIVE (content extraction) and ADVANCED (visual interaction)
- Vision-based interaction with auto-screenshot
- Built-in browser tools
from marsys.agents import BrowserAgentfrom marsys.models import ModelConfigimport os# Create BrowserAgent with built-in browser toolsbrowser_agent = await BrowserAgent.create_safe(model_config=ModelConfig(type="api",provider="openrouter",name="anthropic/claude-sonnet-4",temperature=0.3),name="web_scraper",mode="primitive", # or "advanced" for visual interactiongoal="Web automation agent",instruction="You are a web automation specialist. Navigate websites, extract content, and interact with web pages as instructed.",headless=True)# Browser tools are automatically available to the agentresult = await browser_agent.run("Navigate to example.com and extract content")# Always cleanupawait browser_agent.cleanup()
Note
Browser tools are accessed through BrowserAgent, not a separate BrowserTools class.
Integration Patterns
Pattern 1: Using with Agents
All tool classes provide get_tools() method that returns a dict of wrapped functions:
from marsys.agents import Agentfile_tools = FileOperationTools()bash_tools = BashTools()# Combine tools from multiple classestools = {}tools.update(file_tools.get_tools())tools.update(bash_tools.get_tools())agent = Agent(model_config=config,goal="File operations specialist",instruction="...",tools=tools)
Pattern 2: Conditional Tool Loading
Enable tools based on configuration:
tools = {}# Always include file operationstools.update(file_tools.get_tools())# Conditionally add bash toolsif enable_bash:bash_tools = BashTools(allowed_commands=allowed_commands if production else None)tools.update(bash_tools.get_tools())# Conditionally add search tools (validates API keys)if has_search_api_keys:try:search_tools = SearchTools(google_api_key=api_key, google_cse_id=cse_id)tools.update(search_tools.get_tools(tools_subset=["google", "arxiv"]))except ValueError:logger.warning("Search tools not available - missing API keys")
Pattern 3: Custom Tool Subset
Select specific tools from a class:
# FileOperationTools: get only read/write toolsall_file_tools = file_tools.get_tools()read_write_only = {k: v for k, v in all_file_tools.items()if k in ["read_file", "write_file"]}# SearchTools: get only scholarly sourcessearch_tools = SearchTools()scholarly_only = search_tools.get_tools(tools_subset=["arxiv", "semantic_scholar", "pubmed"])
Pattern 4: Tool Configuration
Configure tool behavior through initialization:
from pathlib import Path# FileOperationTools: restrict to specific directoryfile_tools = FileOperationTools(base_directory=Path("/app/data"),force_base_directory=True # Cannot escape /app/data)# BashTools: production whitelistbash_tools = BashTools(allowed_commands=["grep", "find", "wc", "ls"],blocked_commands=["rm", "mv"], # Additional blockstimeout_default=10 # Shorter timeout)# SearchTools: explicit API keys (override env vars)search_tools = SearchTools(google_api_key="explicit_key_here",google_cse_id="explicit_cse_id_here",semantic_scholar_api_key="explicit_key_here")
Creating Custom Tool Classes
1. Class Structure
from typing import Dict, Callable, Any, Optionalfrom pathlib import Pathclass MyToolClass:"""Custom tool class for domain-specific operations."""def __init__(self,config_param: str,optional_param: Optional[int] = None):"""Initialize with configuration."""self.config_param = config_paramself.optional_param = optional_param or 10# Validate configurationself._validate_config()def _validate_config(self):"""Validate configuration at initialization."""if not self.config_param:raise ValueError("config_param is required")def get_tools(self) -> Dict[str, Callable]:"""Return wrapped tool functions for agent integration."""return {"my_tool": self.my_tool_operation,"another_tool": self.another_operation}async def my_tool_operation(self,param: str,**kwargs) -> Dict[str, Any]:"""Tool operation with structured output.Returns:Dict with success, result, and optional error fields"""try:# Perform operationresult = self._do_work(param)return {"success": True,"result": result,"metadata": {"param": param}}except Exception as e:return {"success": False,"error": str(e),"error_type": type(e).__name__}
2. Structured Output
Always return Dict with consistent structure:
# Success response{"success": True,"result": <data>,"metadata": {...} # Optional}# Error response{"success": False,"error": <error_message>,"error_type": <exception_type>,"details": {...} # Optional}
3. Error Handling
Catch and classify errors:
try:result = await self._perform_operation(param)return {"success": True, "result": result}except FileNotFoundError as e:return {"success": False,"error": f"File not found: {e}","error_type": "FileNotFoundError","recoverable": True}except PermissionError as e:return {"success": False,"error": f"Permission denied: {e}","error_type": "PermissionError","recoverable": False}except Exception as e:return {"success": False,"error": f"Unexpected error: {e}","error_type": type(e).__name__,"recoverable": False}
Best Practices
1. Use Tool Classes for Consistency
# GOOD - Use tool classes for structured, tested functionalityfile_tools = FileOperationTools()tools = file_tools.get_tools()# BAD - Create ad-hoc tool functions without structuredef my_read_file(path):with open(path) as f:return f.read() # No error handling, no structured output
2. Validate Configuration Early
class MyTools:def __init__(self, api_key: str):if not api_key:raise ValueError("API key required") # Fail fastself.api_key = api_key
3. Provide Helpful Error Messages
# GOOD - Helpfulraise ValueError("Google Search requires GOOGLE_SEARCH_API_KEY and GOOGLE_CSE_ID_GENERIC. ""Get from: https://developers.google.com/custom-search/v1/overview")# BAD - Vagueraise ValueError("Missing API key")
4. Use Type Hints
async def search(self,query: str,max_results: int = 10) -> Dict[str, Any]:"""Type hints improve IDE support and clarity."""...
5. Document Return Formats
async def my_tool(self, param: str) -> Dict[str, Any]:"""Perform operation.Args:param: Input parameterReturns:Dict with:- success (bool): Operation success- result (Any): Operation result if successful- error (str): Error message if failed"""
Environment Variables
| Tool Class | Environment Variables | Required |
|---|---|---|
| SearchTools | GOOGLE_SEARCH_API_KEY (optional)GOOGLE_CSE_ID_GENERIC (optional)SEMANTIC_SCHOLAR_API_KEY (optional)NCBI_API_KEY (optional) | None (DuckDuckGo is free) |
| FileOperationTools | None | No |
| BashTools | None | No |
| BrowserAgent | None | No |
Setup Guides
Related Documentation
Built-in Tools Guide
Simple function-based tools.
File Operations Guide
Advanced file handling strategies.
Tools API Reference
Complete API documentation for tools.
Agent API
Building agents with tools.