Architecture 4 Tools - djvolz/coda-code-assistant GitHub Wiki
- Primary implementation:
coda/tools/base.py - Tool executor:
coda/tools/executor.py - File operations:
coda/tools/file_tools.py - Git operations:
coda/tools/git_tools.py - Web operations:
coda/tools/web_tools.py - Shell operations:
coda/tools/shell_tools.py - Permission system:
coda/tools/permissions.py - MCP integration:
coda/tools/mcp_manager.py,coda/tools/mcp_server.py - Session storage:
coda/tools/session_storage.py - Tests:
tests/test_tools.py,tests/tools/
The Tools module provides a comprehensive framework for AI-assisted tool execution with safety controls, permissions, and extensibility. It supports both built-in tools and external tools via the Model Context Protocol (MCP). The main interface is defined in coda/tools/base.py with the BaseTool abstract class.
coda/tools/
├── __init__.py # Module exports and initialization (verified)
├── base.py # Core interfaces and registry (verified)
├── executor.py # Tool execution engine (verified)
├── file_tools.py # File system operations (verified)
├── git_tools.py # Git repository operations (verified)
├── web_tools.py # Web fetching and search (verified)
├── shell_tools.py # Shell command execution (verified)
├── permissions.py # Permission system (verified)
├── mcp_manager.py # MCP server management (verified)
├── mcp_server.py # MCP protocol server (verified)
├── mcp_stdio_client.py # MCP stdio client (verified)
└── session_storage.py # Tool invocation tracking (verified)
Location: coda/tools/base.py
Purpose: Defines the abstract interface for all tools
Key Classes:
-
BaseTool: Abstract base class for tools -
ToolSchema: Tool metadata and parameters -
ToolParameter: Parameter definitions with validation -
ToolRegistry: Centralized tool management
Location: coda/tools/executor.py
Purpose: Orchestrates tool execution with safety checks
Key Methods:
-
execute_tool_call(): Main execution pipeline -
get_available_tools(): Returns tool schemas -
format_tool_result(): Formats results for display
Location: coda/tools/permissions.py
Purpose: Fine-grained access control for tool execution
Key Components:
-
PermissionLevelenum: Permission tiers -
PermissionRule: Rule definitions -
PermissionManager: Rule evaluation engine
Location: coda/tools/mcp_manager.py
Purpose: Integrates external tools via Model Context Protocol
Key Classes:
-
MCPManager: Server lifecycle management -
ExternalMCPTool: Wrapper for MCP tools
Implementation: coda/tools/base.py
class BaseTool(ABC):
"""Abstract base class for all tools."""
@abstractmethod
def get_schema(self) -> ToolSchema:
"""Return the tool's schema."""
pass
@abstractmethod
async def execute(self, arguments: dict[str, Any]) -> ToolResult:
"""Execute the tool with given arguments."""
passImplementation: coda/tools/base.py
class ToolRegistry:
"""Centralized registry for all available tools."""
def __init__(self):
self._tools: dict[str, BaseTool] = {}
self._categories: dict[ToolCategory, list[str]] = {}
def register(self, tool: Type[BaseTool], category: Optional[ToolCategory] = None):
"""Register a tool class."""
tool_instance = tool()
self._tools[tool_name] = tool_instanceImplementation: Different tool implementations with common interface
Each tool type implements the BaseTool interface differently:
- File tools for file operations
- Git tools for version control
- Web tools for internet access
- Shell tools for command execution
sequenceDiagram
participant AI
participant Executor as ToolExecutor
participant Permissions as PermissionManager
participant Registry as ToolRegistry
participant Tool as BaseTool
participant Storage as SessionStorage
AI->>Executor: execute_tool_call(ToolCall)
Executor->>Registry: get_tool(tool_name)
Registry->>Executor: Return tool instance
alt Dangerous tool
Executor->>Permissions: check_permission(tool, user)
Permissions->>Permissions: Evaluate rules
alt Permission denied
Permissions->>Executor: Denied
Executor->>AI: Return error
else Permission granted
Permissions->>Executor: Allowed
end
end
Executor->>Tool: validate_arguments(args)
Tool->>Executor: Validation result
alt Valid arguments
Executor->>Tool: execute(arguments)
Tool->>Tool: Perform operation
Tool->>Executor: Return ToolResult
Executor->>Storage: log_invocation()
Executor->>AI: Return formatted result
else Invalid arguments
Executor->>AI: Return validation error
end
File Tools (file_tools.py)
-
ReadFileTool: Read file contents with encoding support -
WriteFileTool: Write files with backup creation -
EditFileTool: Advanced file editing operations -
ListDirectoryTool: Directory listing with patterns
Git Tools (git_tools.py)
-
GitStatusTool: Repository status information -
GitLogTool: Commit history with filtering -
GitDiffTool: View diffs between commits/branches -
GitBranchTool: Branch management operations
Web Tools (web_tools.py)
-
FetchUrlTool: Fetch and convert web content -
SearchWebTool: Web search via DuckDuckGo
Shell Tools (shell_tools.py)
-
ShellExecuteTool: Execute shell commands with safety controls- Dangerous patterns blocklist
- Completely blocked patterns
- Safe command allowlist
Permission Levels (permissions.py):
class PermissionLevel(str, Enum):
DENIED = "denied" # No access
READ_ONLY = "read_only" # Read operations only
LIMITED = "limited" # Limited write operations
STANDARD = "standard" # Standard operations
ELEVATED = "elevated" # Elevated privileges
ADMIN = "admin" # Full accessPermission Rules support:
- Tool-specific permissions
- Category-based permissions
- Time-based restrictions
- Usage rate limiting
- Parameter value restrictions
- User approval requirements
MCP Manager (mcp_manager.py):
class MCPManager:
"""Manages MCP server lifecycle and tool discovery."""
async def start_server(self, server_config: dict):
"""Start an MCP server subprocess."""
# Launches external MCP server
async def discover_tools(self):
"""Discover tools from all active servers."""
# Queries servers for available toolsExternal Tool Wrapper (mcp_manager.py):
class ExternalMCPTool(BaseTool):
"""Wrapper for external MCP tools."""
async def execute(self, arguments: dict[str, Any]):
"""Execute tool via MCP protocol."""
# Sends request to external serverLocation: coda/tools/base.py
Purpose: Abstract base class for all tools
Methods:
-
get_schema() -> ToolSchema: Return tool metadata -
execute(arguments: dict) -> ToolResult: Execute tool -
validate_arguments(arguments: dict) -> str | None: Validate inputs
Location: coda/tools/executor.py
Purpose: Manages tool execution with safety controls
Methods:
-
execute_tool_call(tool_call: ToolCall) -> ToolResult: Execute tool -
get_available_tools() -> list[ToolSchema]: List tools
Location: coda/tools/permissions.py
Purpose: Evaluates permission rules for tool access
Methods:
check_tool_permission(tool_name, user_context) -> PermissionResultadd_rule(rule: PermissionRule) -> Noneevaluate_rules(tool_name, context) -> PermissionLevel
Config Files:
- Tool permissions:
~/.config/coda/permissions.yaml - MCP servers:
~/.config/coda/mcp.json
MCP Server Configuration Example:
{
"servers": [
{
"name": "example-server",
"command": "node",
"args": ["path/to/server.js"],
"env": {"API_KEY": "..."}
}
]
}-
coda.configuration: Config management -
coda.agents: Tool integration with agents -
coda.session: Session tracking integration
-
httpx>=0.24.0: HTTP client for web tools -
beautifulsoup4>=4.12.0: HTML parsing -
html2text>=2020.1.16: HTML to markdown conversion -
GitPython>=3.1.0: Git operations
- Unit tests:
tests/test_tools.py - Tool-specific tests:
tests/tools/test_*.py - Integration tests:
tests/tools/test_tools_with_mock_provider.py
- Tool Registry: Registration and discovery
- Permission System: Rule evaluation
- MCP Integration: Server communication
try:
result = await tool.execute(tool_call.arguments)
except Exception as e:
logger.error(f"Tool execution failed: {e}")
return ToolResult(
tool_call_id=tool_call.id,
content=f"Error: {str(e)}"
)Tools validate arguments before execution and return descriptive errors for invalid inputs.
- Async Execution: All tools use async/await for non-blocking operations
- Connection Pooling: HTTP clients reused for web tools
- Subprocess Management: MCP servers managed with process pools
- Result Caching: Some tools cache results (e.g., git status)
- Command Injection Prevention: Shell tools use shlex for safe parsing
- Path Traversal Protection: File tools validate paths
- Rate Limiting: Permission system supports usage limits
- Approval Workflows: Dangerous operations require user consent
- Audit Trail: All invocations logged to session storage
from coda.tools import tool_registry
# Get a tool
read_tool = tool_registry.get_tool("read_file")
# Execute it
result = await read_tool.execute({
"path": "/path/to/file.txt"
})# Example custom tool
from coda.tools.base import BaseTool, ToolSchema, ToolParameter
class CustomTool(BaseTool):
def get_schema(self) -> ToolSchema:
return ToolSchema(
name="custom_tool",
description="My custom tool",
parameters={
"input": ToolParameter(
type="string",
description="Input value"
)
}
)
async def execute(self, arguments: dict) -> ToolResult:
# Tool implementation
return ToolResult(success=True, output="Done!")-
Agent Module: Tools exposed via
MCPToolAdapter -
CLI Module: Tool chat integration in
tool_chat.py - Session Module: Tool invocations tracked in database
-
New Tools: Extend
BaseTooland register - Custom Permissions: Add rules to permission manager
- MCP Servers: Add external tool servers
- Shell Safety: Some commands always blocked for safety
- Web Scraping: Limited by site structure and anti-bot measures
- File Size: Large file operations may timeout
All files referenced in this document: