Tools¶
Tool system -- base class, registry, invoker, built-in tools, and MCP bridge.
Base Tool¶
base
¶
Base tool abstraction and execution result model.
Defines the BaseTool ABC that all concrete tools extend, and the
ToolExecutionResult value object returned by tool execution.
ToolExecutionResult
pydantic-model
¶
Bases: BaseModel
Result of executing a tool's business logic.
This is the internal result type returned by BaseTool.execute.
The invoker converts it into a ToolResult for the LLM, carrying
only content and is_error -- metadata is not forwarded
to the LLM and is available only for programmatic consumers.
Note
The metadata dict is shallowly frozen by Pydantic's
frozen=True. Tool implementations construct and return
this model, but the invoker converts it into a provider-facing
ToolResult -- metadata is not forwarded to LLM providers
or other external boundaries, so no additional boundary copy
is needed at this layer.
Attributes:
| Name | Type | Description |
|---|---|---|
content |
str
|
Tool output as a string. |
is_error |
bool
|
Whether the execution failed. |
metadata |
dict[str, Any]
|
Optional structured data for programmatic consumers. |
Config:
frozen:Trueallow_inf_nan:False
Fields:
BaseTool
¶
Bases: ABC
Abstract base class for all tools in the system.
Subclasses must implement execute to define tool behavior.
The to_definition method converts the tool into a
ToolDefinition suitable for sending to an LLM provider.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Non-blank tool name. |
description |
str
|
Human-readable description of the tool. |
parameters_schema |
dict[str, Any] | None
|
JSON Schema dict describing expected arguments,
or |
category |
ToolCategory
|
Tool category for access-level gating. |
action_type |
str
|
Security action type for SecOps classification. |
Initialize a tool with name, description, schema, and category.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Non-blank tool name. |
required |
description
|
str
|
Human-readable description. |
''
|
parameters_schema
|
dict[str, Any] | None
|
JSON Schema for tool parameters. |
None
|
category
|
ToolCategory
|
Tool category for access-level gating. |
required |
action_type
|
str | None
|
Security action type for SecOps classification.
When |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If name is empty or whitespace-only. |
Source code in src/synthorg/tools/base.py
parameters_schema
property
¶
JSON Schema for tool parameters, or None if unspecified.
Returns a deep copy to prevent mutation of internal state.
to_definition
¶
Convert this tool to a ToolDefinition for LLM providers.
Returns:
| Type | Description |
|---|---|
ToolDefinition
|
A |
Source code in src/synthorg/tools/base.py
execute
abstractmethod
async
¶
Execute the tool with the given arguments.
Arguments are pre-validated against the tool's JSON Schema (if
one is defined) by the ToolInvoker before reaching this
method. Implementations with a schema can assume compliance
when invoked through the invoker; tools without a schema
receive unvalidated arguments.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
arguments
|
dict[str, Any]
|
Parsed arguments matching the parameters schema. |
required |
Returns:
| Type | Description |
|---|---|
ToolExecutionResult
|
A |
Source code in src/synthorg/tools/base.py
Registry¶
registry
¶
Tool registry -- maps tool names to BaseTool instances.
Immutable after construction. Provides lookup, membership testing,
and conversion to a tuple of ToolDefinition objects for LLM providers.
ToolRegistry
¶
Immutable registry of named tools.
Examples:
Build from a list of tools::
registry = ToolRegistry([echo_tool, search_tool])
tool = registry.get("echo")
Check membership::
if "echo" in registry:
...
Initialize with an iterable of tools.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tools
|
Iterable[BaseTool]
|
Tools to register. Duplicate names raise |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If two tools share the same name. |
Source code in src/synthorg/tools/registry.py
get
¶
Look up a tool by name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Tool name. |
required |
Returns:
| Type | Description |
|---|---|
BaseTool
|
The registered tool instance. |
Raises:
| Type | Description |
|---|---|
ToolNotFoundError
|
If no tool is registered with that name. |
Source code in src/synthorg/tools/registry.py
list_tools
¶
all_tools
¶
to_definitions
¶
Return all tool definitions as a sorted tuple, ordered by name.
Returns:
| Type | Description |
|---|---|
tuple[ToolDefinition, ...]
|
Sorted tuple of tool definitions for LLM providers. |
Source code in src/synthorg/tools/registry.py
__contains__
¶
Check whether a tool name is registered.
Source code in src/synthorg/tools/registry.py
Invoker¶
invoker
¶
Tool invoker -- validates and executes tool calls.
Bridges LLM ToolCall objects with concrete BaseTool.execute
methods. Recoverable errors are returned as ToolResult(is_error=True);
non-recoverable errors (MemoryError, RecursionError) are logged and
re-raised. BaseException subclasses (KeyboardInterrupt,
SystemExit, asyncio.CancelledError) propagate uncaught.
ToolInvoker
¶
ToolInvoker(
registry,
*,
permission_checker=None,
security_interceptor=None,
agent_id=None,
task_id=None,
agent_provider_name=None,
invocation_tracker=None,
)
Validate parameters, enforce security policies, and execute tools.
Recoverable errors are returned as ToolResult(is_error=True).
Non-recoverable errors (MemoryError, RecursionError) are
re-raised after logging.
Examples:
Invoke a single tool call::
invoker = ToolInvoker(registry)
result = await invoker.invoke(tool_call)
Invoke multiple tool calls concurrently::
results = await invoker.invoke_all(tool_calls)
Limit concurrency::
results = await invoker.invoke_all(tool_calls, max_concurrency=3)
Initialize with a tool registry and optional checkers.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
registry
|
ToolRegistry
|
Registry to look up tools from. |
required |
permission_checker
|
ToolPermissionChecker | None
|
Optional checker for access-level gating.
When |
None
|
security_interceptor
|
SecurityInterceptionStrategy | None
|
Optional pre/post-tool security layer. |
None
|
agent_id
|
str | None
|
Agent ID for security context. |
None
|
task_id
|
str | None
|
Task ID for security context. |
None
|
agent_provider_name
|
str | None
|
Provider name the agent is using, for cross-family LLM security evaluation. |
None
|
invocation_tracker
|
ToolInvocationTracker | None
|
Optional tracker for recording invocations for the activity timeline. |
None
|
Source code in src/synthorg/tools/invoker.py
pending_escalations
property
¶
Escalations detected during the most recent invoke/invoke_all.
Populated when a security ESCALATE verdict with a non-None
approval_id is returned, or when a tool returns
requires_parking metadata. Cleared at the start of every
invoke() and invoke_all() call.
get_permitted_definitions
¶
Return tool definitions filtered by the permission checker.
When no permission checker is set, returns all definitions.
Returns:
| Type | Description |
|---|---|
tuple[ToolDefinition, ...]
|
Tuple of permitted tool definitions, sorted by name. |
Source code in src/synthorg/tools/invoker.py
invoke
async
¶
Execute a single tool call.
Steps
- Look up the tool in the registry.
- Check permissions against the permission checker (if any).
- Validate arguments against the tool's JSON Schema (if any).
- Run security interceptor pre-tool check (if any).
- Call
tool.execute(arguments=...). - Scan tool output for sensitive data (if interceptor is set).
- Return a
ToolResultwith the output.
Recoverable errors produce ToolResult(is_error=True).
Non-recoverable errors are re-raised.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tool_call
|
ToolCall
|
The tool call from the LLM. |
required |
Returns:
| Type | Description |
|---|---|
ToolResult
|
A |
Source code in src/synthorg/tools/invoker.py
invoke_all
async
¶
Execute multiple tool calls concurrently.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tool_calls
|
Iterable[ToolCall]
|
Tool calls to execute. |
required |
max_concurrency
|
int | None
|
Max concurrent invocations ( |
None
|
Returns:
| Type | Description |
|---|---|
tuple[ToolResult, ...]
|
Tuple of results in the same order as the input. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If max_concurrency < 1. |
MemoryError
|
Re-raised if a single fatal error occurred. |
RecursionError
|
Re-raised if a single fatal error occurred. |
ExceptionGroup
|
If multiple fatal errors occurred. |
Source code in src/synthorg/tools/invoker.py
Permissions¶
permissions
¶
Tool permission checker -- enforces access-level gating.
Resolves tool permissions using a priority-based system:
1. If tool name is in denied → DENIED
2. If tool name is in allowed → ALLOWED
3. If access level is CUSTOM → DENIED
4. If tool category is in the level's allowed categories → ALLOWED
5. Otherwise → DENIED
ToolPermissionChecker
¶
Enforces tool access permissions based on access level and explicit lists.
Each access level grants a set of tool categories. Explicit allowed
and denied lists override the level-based rules (denied has highest
priority). All name matching is case-insensitive.
Examples:
Create from agent permissions::
checker = ToolPermissionChecker.from_permissions(identity.tools)
if checker.is_permitted("git_push", ToolCategory.VERSION_CONTROL):
...
Filter tool definitions for LLM prompt::
defs = checker.filter_definitions(registry)
Initialize with access level and explicit name lists.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
access_level
|
ToolAccessLevel
|
Base access level for category gating. |
STANDARD
|
allowed
|
frozenset[str]
|
Explicitly allowed tool names (normalized on store). |
frozenset()
|
denied
|
frozenset[str]
|
Explicitly denied tool names (normalized on store). |
frozenset()
|
Source code in src/synthorg/tools/permissions.py
from_permissions
classmethod
¶
Create a checker from an agent's ToolPermissions model.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
permissions
|
ToolPermissions
|
Agent tool permissions. |
required |
Returns:
| Type | Description |
|---|---|
Self
|
Configured permission checker. |
Source code in src/synthorg/tools/permissions.py
is_permitted
¶
Check whether a tool is permitted.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tool_name
|
str
|
Name of the tool. |
required |
category
|
ToolCategory
|
Category of the tool. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
Source code in src/synthorg/tools/permissions.py
check
¶
Assert that a tool is permitted, raising on denial.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tool_name
|
str
|
Name of the tool. |
required |
category
|
ToolCategory
|
Category of the tool. |
required |
Raises:
| Type | Description |
|---|---|
ToolPermissionDeniedError
|
If the tool is not permitted. |
Source code in src/synthorg/tools/permissions.py
denial_reason
¶
Return a human-readable reason why a tool would be denied.
Intended for use after confirming the tool is denied via
is_permitted or via check. If the tool is actually
permitted, the returned string does not apply and should not
be shown to users.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tool_name
|
str
|
Name of the tool. |
required |
category
|
ToolCategory
|
Category of the tool. |
required |
Returns:
| Type | Description |
|---|---|
str
|
Explanation string suitable for error messages. |
Source code in src/synthorg/tools/permissions.py
filter_definitions
¶
Return only permitted tool definitions from a registry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
registry
|
ToolRegistry
|
Tool registry to filter. |
required |
Returns:
| Type | Description |
|---|---|
tuple[ToolDefinition, ...]
|
Tuple of permitted tool definitions, sorted by tool name. |
Source code in src/synthorg/tools/permissions.py
Errors¶
errors
¶
Tool error hierarchy.
All tool errors carry an immutable context mapping for structured
metadata. Unlike provider errors, tool errors have no is_retryable
flag -- retry decisions are made at higher layers.
ToolError
¶
Bases: Exception
Base exception for all tool-layer errors.
Attributes:
| Name | Type | Description |
|---|---|---|
message |
Human-readable error description. |
|
context |
MappingProxyType[str, Any]
|
Immutable metadata about the error (tool name, etc.). |
Initialize a tool error.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message
|
str
|
Human-readable error description. |
required |
context
|
dict[str, Any] | None
|
Arbitrary metadata about the error. Stored as an immutable mapping; defaults to empty if not provided. |
None
|
Source code in src/synthorg/tools/errors.py
__str__
¶
Format error with optional context metadata.
ToolNotFoundError
¶
Bases: ToolError
Requested tool is not registered in the registry.
Source code in src/synthorg/tools/errors.py
ToolParameterError
¶
Bases: ToolError
Tool parameters failed schema validation.
Source code in src/synthorg/tools/errors.py
ToolExecutionError
¶
Bases: ToolError
Tool execution raised an unexpected error.
Source code in src/synthorg/tools/errors.py
ToolPermissionDeniedError
¶
Bases: ToolError
Tool invocation blocked by the permission checker.
Source code in src/synthorg/tools/errors.py
Code Runner¶
code_runner
¶
Code runner tool -- executes code snippets in a sandboxed environment.
Supports Python, JavaScript, and Bash via configurable sandbox backends.
CodeRunnerTool
¶
Bases: BaseTool
Executes code snippets in a sandboxed environment.
Supports Python, JavaScript, and Bash. Delegates execution to
a SandboxBackend for isolation and resource control.
Initialize the code runner tool.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sandbox
|
SandboxBackend
|
Sandbox backend for isolated code execution. |
required |
Source code in src/synthorg/tools/code_runner.py
execute
async
¶
Execute a code snippet in the sandbox.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
arguments
|
dict[str, Any]
|
Must contain |
required |
Returns:
| Type | Description |
|---|---|
ToolExecutionResult
|
A |
Source code in src/synthorg/tools/code_runner.py
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | |
Git Tools¶
git_tools
¶
Built-in git tools for version control operations.
Provides workspace-scoped git tools that agents use to interact with
git repositories. All tools enforce workspace boundary security -- the
LLM never controls absolute paths. See _git_base._BaseGitTool for
the subprocess execution model, environment hardening, and path
validation shared by all tools.
GitStatusTool
¶
Bases: _BaseGitTool
Show the working tree status of the git repository.
Returns the output of git status with optional short or
porcelain formatting.
Initialize the git_status tool.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
workspace
|
Path
|
Absolute path to the workspace root. |
required |
sandbox
|
SandboxBackend | None
|
Optional sandbox backend for subprocess isolation. |
None
|
Source code in src/synthorg/tools/git_tools.py
execute
async
¶
Run git status.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
arguments
|
dict[str, Any]
|
Optional |
required |
Returns:
| Type | Description |
|---|---|
ToolExecutionResult
|
A |
Source code in src/synthorg/tools/git_tools.py
GitLogTool
¶
Bases: _BaseGitTool
Show commit log history.
Returns recent commits with optional filtering by count, author, date range, ref, and paths.
Initialize the git_log tool.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
workspace
|
Path
|
Absolute path to the workspace root. |
required |
sandbox
|
SandboxBackend | None
|
Optional sandbox backend for subprocess isolation. |
None
|
Source code in src/synthorg/tools/git_tools.py
execute
async
¶
Run git log.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
arguments
|
dict[str, Any]
|
Log options (max_count, oneline, ref, author, since, until, paths). |
required |
Returns:
| Type | Description |
|---|---|
ToolExecutionResult
|
A |
Source code in src/synthorg/tools/git_tools.py
GitDiffTool
¶
Bases: _BaseGitTool
Show changes between commits, the index, and the working tree.
Returns the output of git diff with optional ref comparison,
staged changes view, stat summary, and path filtering.
Initialize the git_diff tool.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
workspace
|
Path
|
Absolute path to the workspace root. |
required |
sandbox
|
SandboxBackend | None
|
Optional sandbox backend for subprocess isolation. |
None
|
Source code in src/synthorg/tools/git_tools.py
execute
async
¶
Run git diff.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
arguments
|
dict[str, Any]
|
Diff options (staged, ref1, ref2, stat, paths). |
required |
Returns:
| Type | Description |
|---|---|
ToolExecutionResult
|
A |
ToolExecutionResult
|
returns "No changes" (not an error). |
Source code in src/synthorg/tools/git_tools.py
GitBranchTool
¶
Bases: _BaseGitTool
Manage branches -- list, create, switch, or delete.
Supports listing all branches, creating new branches (optionally from a start point), switching between branches, and deleting branches.
Initialize the git_branch tool.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
workspace
|
Path
|
Absolute path to the workspace root. |
required |
sandbox
|
SandboxBackend | None
|
Optional sandbox backend for subprocess isolation. |
None
|
Source code in src/synthorg/tools/git_tools.py
execute
async
¶
Run a branch operation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
arguments
|
dict[str, Any]
|
Branch action, name, start_point, force. |
required |
Returns:
| Type | Description |
|---|---|
ToolExecutionResult
|
A |
Source code in src/synthorg/tools/git_tools.py
GitCommitTool
¶
Bases: _BaseGitTool
Stage and commit changes.
Stages specified paths (or all changes with all=True), then
creates a commit with the provided message.
Initialize the git_commit tool.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
workspace
|
Path
|
Absolute path to the workspace root. |
required |
sandbox
|
SandboxBackend | None
|
Optional sandbox backend for subprocess isolation. |
None
|
Source code in src/synthorg/tools/git_tools.py
execute
async
¶
Stage and commit changes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
arguments
|
dict[str, Any]
|
Commit message, optional paths, optional all flag. |
required |
Returns:
| Type | Description |
|---|---|
ToolExecutionResult
|
A |
Source code in src/synthorg/tools/git_tools.py
GitCloneTool
¶
Bases: _BaseGitTool
Clone a git repository into the workspace.
Validates that the target directory stays within the workspace
boundary. Supports optional branch selection and shallow clone
depth. URLs are validated against allowed schemes (https, ssh,
SCP-like) and checked for SSRF via hostname/IP validation with
async DNS resolution. Local paths, file://, and plain
http:// URLs are rejected.
Initialize the git_clone tool.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
workspace
|
Path
|
Absolute path to the workspace root. |
required |
sandbox
|
SandboxBackend | None
|
Optional sandbox backend for subprocess isolation. |
None
|
network_policy
|
GitCloneNetworkPolicy | None
|
SSRF prevention network policy. Defaults to blocking all private/reserved IPs with an empty hostname allowlist. |
None
|
Source code in src/synthorg/tools/git_tools.py
execute
async
¶
Clone a repository.
Validation order: scheme check -> argument checks (branch,
depth, directory) -> SSRF host/IP check -> TOCTOU DNS
rebinding mitigation -> git clone. All cheap local
checks run before the async DNS lookup.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
arguments
|
dict[str, Any]
|
Clone URL, optional directory, branch, depth. |
required |
Returns:
| Type | Description |
|---|---|
ToolExecutionResult
|
A |
Source code in src/synthorg/tools/git_tools.py
File System Tools¶
read_file
¶
Read file tool -- reads file content from the workspace.
Supports optional line-range selection and enforces a maximum file-size guard to prevent loading excessively large files into memory.
ReadFileTool
¶
Bases: BaseFileSystemTool
Reads the content of a file within the workspace.
Supports optional start_line / end_line for partial reads.
Files exceeding 1 MB are read in bounded fashion: when no line
range is specified only the first 1 MB is returned (with a
truncation notice). Binary (non-UTF-8) files produce an error.
Examples:
Read an entire file::
tool = ReadFileTool(workspace_root=Path("/ws"))
result = await tool.execute(arguments={"path": "src/main.py"})
Initialize the read-file tool.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
workspace_root
|
Path
|
Root directory bounding file access. |
required |
Source code in src/synthorg/tools/file_system/read_file.py
execute
async
¶
Read a file and return its content.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
arguments
|
dict[str, Any]
|
Must contain |
required |
Returns:
| Type | Description |
|---|---|
ToolExecutionResult
|
A |
Source code in src/synthorg/tools/file_system/read_file.py
write_file
¶
Write file tool -- creates or overwrites files in the workspace.
WriteFileTool
¶
Bases: BaseFileSystemTool
Creates or overwrites a file within the workspace.
Optionally creates parent directories when create_directories
is True.
Examples:
Write a new file::
tool = WriteFileTool(workspace_root=Path("/ws"))
result = await tool.execute(
arguments={"path": "out.txt", "content": "hello"}
)
Initialize the write-file tool.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
workspace_root
|
Path
|
Root directory bounding file access. |
required |
Source code in src/synthorg/tools/file_system/write_file.py
execute
async
¶
Write content to a file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
arguments
|
dict[str, Any]
|
Must contain |
required |
Returns:
| Type | Description |
|---|---|
ToolExecutionResult
|
A |
Source code in src/synthorg/tools/file_system/write_file.py
edit_file
¶
Edit file tool -- search-and-replace within workspace files.
EditFileTool
¶
Bases: BaseFileSystemTool
Replaces the first occurrence of old_text with new_text.
If old_text is not found, returns an error indicating that the
text was not found. When multiple occurrences exist, only the first
is replaced and a warning is included in the output.
Returns immediately with no change if old_text and new_text
are identical.
Examples:
Replace text::
tool = EditFileTool(workspace_root=Path("/ws"))
result = await tool.execute(
arguments={
"path": "main.py",
"old_text": "foo",
"new_text": "bar",
}
)
Initialize the edit-file tool.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
workspace_root
|
Path
|
Root directory bounding file access. |
required |
Source code in src/synthorg/tools/file_system/edit_file.py
execute
async
¶
Edit a file by replacing text.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
arguments
|
dict[str, Any]
|
Must contain |
required |
Returns:
| Type | Description |
|---|---|
ToolExecutionResult
|
A |
Source code in src/synthorg/tools/file_system/edit_file.py
delete_file
¶
Delete file tool -- removes a single file from the workspace.
DeleteFileTool
¶
Bases: BaseFileSystemTool
Deletes a single file within the workspace.
Directories cannot be deleted with this tool -- only regular files.
The require_elevated property is defined for future use by the
engine's permission system (not yet enforced).
Examples:
Delete a file::
tool = DeleteFileTool(workspace_root=Path("/ws"))
result = await tool.execute(arguments={"path": "tmp.txt"})
Initialize the delete-file tool.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
workspace_root
|
Path
|
Root directory bounding file access. |
required |
Source code in src/synthorg/tools/file_system/delete_file.py
require_elevated
property
¶
Whether this tool requires elevated permissions.
Indicates this tool requires explicit approval before execution due to its destructive nature. Not yet consumed by the engine; defined for forward-compatibility.
execute
async
¶
Delete a file from the workspace.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
arguments
|
dict[str, Any]
|
Must contain |
required |
Returns:
| Type | Description |
|---|---|
ToolExecutionResult
|
A |
Source code in src/synthorg/tools/file_system/delete_file.py
list_directory
¶
List directory tool -- lists entries in a workspace directory.
ListDirectoryTool
¶
Bases: BaseFileSystemTool
Lists files and directories within the workspace.
Supports optional glob filtering and recursive listing. Output is
sorted alphabetically with type prefixes ([DIR] / [FILE] /
[SYMLINK] / [ERROR]).
Results are capped at MAX_ENTRIES (1000) entries to prevent
excessive output.
Examples:
List current directory::
tool = ListDirectoryTool(workspace_root=Path("/ws"))
result = await tool.execute(arguments={})
Initialize the list-directory tool.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
workspace_root
|
Path
|
Root directory bounding file access. |
required |
Source code in src/synthorg/tools/file_system/list_directory.py
execute
async
¶
List directory contents.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
arguments
|
dict[str, Any]
|
Optionally contains |
required |
Returns:
| Type | Description |
|---|---|
ToolExecutionResult
|
A |
Source code in src/synthorg/tools/file_system/list_directory.py
MCP Bridge¶
config
¶
MCP bridge configuration models.
Defines MCPServerConfig for individual MCP server connections and
MCPConfig as the top-level container. Both are frozen Pydantic
models following the project's immutability conventions.
MCPServerConfig
pydantic-model
¶
Bases: BaseModel
Configuration for a single MCP server connection.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
NotBlankStr
|
Unique server identifier. |
transport |
Literal['stdio', 'streamable_http']
|
Transport type ( |
command |
NotBlankStr | None
|
Command to launch a stdio server. |
args |
tuple[str, ...]
|
Command-line arguments for stdio server. |
env |
dict[str, str]
|
Environment variables for stdio server. |
url |
NotBlankStr | None
|
URL for streamable HTTP server. |
headers |
dict[str, str]
|
HTTP headers for streamable HTTP server. |
enabled_tools |
tuple[NotBlankStr, ...] | None
|
Allowlist of tool names ( |
disabled_tools |
tuple[NotBlankStr, ...]
|
Denylist of tool names. |
timeout_seconds |
float
|
Timeout for tool invocations. |
connect_timeout_seconds |
float
|
Timeout for initial connection. |
result_cache_ttl_seconds |
float
|
TTL for result cache entries. |
result_cache_max_size |
int
|
Maximum result cache entries. |
enabled |
bool
|
Whether the server is active. |
Config:
frozen:Trueallow_inf_nan:False
Fields:
-
name(NotBlankStr) -
transport(Literal['stdio', 'streamable_http']) -
command(NotBlankStr | None) -
args(tuple[str, ...]) -
env(dict[str, str]) -
url(NotBlankStr | None) -
headers(dict[str, str]) -
enabled_tools(tuple[NotBlankStr, ...] | None) -
disabled_tools(tuple[NotBlankStr, ...]) -
timeout_seconds(float) -
connect_timeout_seconds(float) -
result_cache_ttl_seconds(float) -
result_cache_max_size(int) -
enabled(bool)
Validators:
-
_validate_transport_fields -
_validate_tool_filters
MCPConfig
pydantic-model
¶
Bases: BaseModel
Top-level MCP bridge configuration.
Attributes:
| Name | Type | Description |
|---|---|---|
servers |
tuple[MCPServerConfig, ...]
|
Tuple of MCP server configurations. |
Config:
frozen:Trueallow_inf_nan:False
Fields:
-
servers(tuple[MCPServerConfig, ...])
Validators:
-
_validate_unique_server_names
models
¶
MCP bridge internal value objects.
Defines MCPToolInfo for discovered tool metadata and
MCPRawResult for raw MCP call results before mapping.
MCPToolInfo
pydantic-model
¶
Bases: BaseModel
Discovered tool metadata from an MCP server.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
NotBlankStr
|
Tool name as reported by the server. |
description |
str
|
Human-readable tool description. |
input_schema |
dict[str, Any]
|
JSON Schema for tool parameters. |
server_name |
NotBlankStr
|
Name of the server that hosts this tool. |
Config:
frozen:Trueallow_inf_nan:False
Fields:
-
name(NotBlankStr) -
description(str) -
input_schema(dict[str, Any]) -
server_name(NotBlankStr)
MCPRawResult
pydantic-model
¶
Bases: BaseModel
Raw result from an MCP tool call before mapping.
Attributes:
| Name | Type | Description |
|---|---|---|
content |
tuple[Any, ...]
|
MCP content blocks from the call result. |
is_error |
bool
|
Whether the MCP call reported an error. |
structured_content |
dict[str, Any] | None
|
Optional structured content from the result. |
Config:
frozen:Trueallow_inf_nan:False
Fields:
-
content(tuple[Any, ...]) -
is_error(bool) -
structured_content(dict[str, Any] | None)
client
¶
MCP client -- thin async wrapper over the MCP SDK.
Manages a single connection to an MCP server and provides tool discovery and invocation through the MCP protocol.
MCPClient
¶
Async client for a single MCP server.
Wraps the MCP SDK's ClientSession to provide connection
management, tool discovery, and tool invocation. A lock
serializes all session access to prevent interleaving.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
MCPServerConfig
|
Server connection configuration. |
required |
Source code in src/synthorg/tools/mcp/client.py
connect
async
¶
Establish a connection to the MCP server.
Raises:
| Type | Description |
|---|---|
MCPConnectionError
|
If the connection fails. |
RuntimeError
|
If already connected. |
Source code in src/synthorg/tools/mcp/client.py
disconnect
async
¶
Close the connection and release resources.
Source code in src/synthorg/tools/mcp/client.py
list_tools
async
¶
Discover tools from the connected server.
Applies enabled_tools / disabled_tools filters
from the server configuration.
Returns:
| Type | Description |
|---|---|
tuple[MCPToolInfo, ...]
|
Filtered tuple of discovered tool metadata. |
Raises:
| Type | Description |
|---|---|
MCPDiscoveryError
|
If discovery fails. |
Source code in src/synthorg/tools/mcp/client.py
call_tool
async
¶
Invoke a tool on the connected server.
Acquires the session lock to respect MCP's sequential protocol constraint. Applies the configured timeout.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tool_name
|
str
|
Name of the tool to invoke. |
required |
arguments
|
dict[str, Any]
|
Arguments to pass to the tool. |
required |
Returns:
| Type | Description |
|---|---|
MCPRawResult
|
Raw result from the MCP server. |
Raises:
| Type | Description |
|---|---|
MCPTimeoutError
|
If the invocation times out. |
MCPInvocationError
|
If the invocation fails. |
Source code in src/synthorg/tools/mcp/client.py
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 | |
reconnect
async
¶
Disconnect and reconnect to the server.
Raises:
| Type | Description |
|---|---|
MCPConnectionError
|
If the reconnection fails. |
Source code in src/synthorg/tools/mcp/client.py
__aenter__
async
¶
__aexit__
async
¶
Exit async context: disconnect from server.
bridge_tool
¶
MCP bridge tool -- wraps an MCP server tool as a BaseTool.
Each MCPBridgeTool instance represents a single tool discovered
from an MCP server, bridging MCP protocol calls into the internal
tool system.
MCPBridgeTool
¶
Bases: BaseTool
Bridge between an MCP server tool and the internal tool system.
Constructs a BaseTool whose execute delegates to an MCP
server via MCPClient. An optional MCPResultCache avoids
redundant remote calls for identical invocations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tool_info
|
MCPToolInfo
|
Discovered MCP tool metadata. |
required |
client
|
MCPClient
|
Connected MCP client for the server. |
required |
cache
|
MCPResultCache | None
|
Optional result cache. |
None
|
Source code in src/synthorg/tools/mcp/bridge_tool.py
execute
async
¶
Execute the MCP tool via the client.
Checks the cache first (if available). On cache miss, invokes the remote tool and stores the result.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
arguments
|
dict[str, Any]
|
Tool invocation arguments. |
required |
Returns:
| Type | Description |
|---|---|
ToolExecutionResult
|
Mapped |
Source code in src/synthorg/tools/mcp/bridge_tool.py
Sandbox¶
protocol
¶
Sandbox backend protocol definition.
SandboxBackend
¶
Bases: Protocol
Protocol for pluggable sandbox backends.
Implementations execute commands in an isolated environment with environment filtering, workspace enforcement, and timeout support. Subprocess and Docker are built-in backends.
execute
async
¶
Execute a command in the sandbox.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
command
|
str
|
Executable name or path. |
required |
args
|
tuple[str, ...]
|
Command arguments. |
required |
cwd
|
Path | None
|
Working directory (defaults to sandbox workspace root). |
None
|
env_overrides
|
Mapping[str, str] | None
|
Extra environment variables for the sandbox. |
None
|
timeout
|
float | None
|
Seconds before the process is killed. Falls back
to the backend's default timeout if |
None
|
Returns:
| Type | Description |
|---|---|
SandboxResult
|
A |
Raises:
| Type | Description |
|---|---|
SandboxStartError
|
If the subprocess could not be started. |
SandboxError
|
If cwd is outside the workspace boundary. |
Source code in src/synthorg/tools/sandbox/protocol.py
cleanup
async
¶
health_check
async
¶
Return True if the backend is operational.
Returns:
| Type | Description |
|---|---|
bool
|
|
get_backend_type
¶
Return a short identifier for this backend type.
Returns:
| Type | Description |
|---|---|
NotBlankStr
|
A string like |
config
¶
Subprocess sandbox configuration model.
SubprocessSandboxConfig
pydantic-model
¶
Bases: BaseModel
Configuration for the subprocess sandbox backend.
Attributes:
| Name | Type | Description |
|---|---|---|
timeout_seconds |
float
|
Default command timeout in seconds. |
workspace_only |
bool
|
When enabled, rejects commands whose working directory falls outside the workspace boundary. |
restricted_path |
bool
|
When enabled, filters PATH entries to retain only known safe system directories. |
env_allowlist |
tuple[str, ...]
|
Environment variable names allowed to pass through.
Supports |
env_denylist_patterns |
tuple[str, ...]
|
fnmatch patterns to strip even if in
the allowlist (e.g. |
extra_safe_path_prefixes |
tuple[str, ...]
|
Additional non-empty absolute PATH prefixes appended to platform defaults for the PATH filter. |
Config:
frozen:Trueallow_inf_nan:False
Fields:
-
timeout_seconds(float) -
workspace_only(bool) -
restricted_path(bool) -
env_allowlist(tuple[str, ...]) -
env_denylist_patterns(tuple[str, ...]) -
extra_safe_path_prefixes(tuple[str, ...])
Validators:
-
_validate_prefixes→extra_safe_path_prefixes
extra_safe_path_prefixes
pydantic-field
¶
Additional safe PATH prefixes appended to platform defaults.
Use this to allow tool-specific directories (e.g. a custom Git install location) through the PATH filter without modifying the built-in platform defaults.
result
¶
Sandbox execution result model.
SandboxResult
pydantic-model
¶
Bases: BaseModel
Immutable result of a sandboxed command execution.
Attributes:
| Name | Type | Description |
|---|---|---|
stdout |
str
|
Captured standard output. |
stderr |
str
|
Captured standard error. |
returncode |
int
|
Process exit code. |
timed_out |
bool
|
Whether the process was killed due to timeout. |
success |
bool
|
Computed -- |
Config:
frozen:Trueallow_inf_nan:False
Fields:
-
stdout(str) -
stderr(str) -
returncode(int) -
timed_out(bool)
subprocess_sandbox
¶
Subprocess-based sandbox backend.
Executes commands via asyncio.create_subprocess_exec with
environment filtering, workspace boundary enforcement, timeout
management, and PATH restriction.
SubprocessSandbox
¶
Subprocess sandbox backend.
Runs commands in child processes with filtered environment variables, workspace boundary checks, and configurable timeouts.
Attributes:
| Name | Type | Description |
|---|---|---|
config |
SubprocessSandboxConfig
|
Sandbox configuration. |
workspace |
Path
|
Absolute path to the workspace root directory. |
Initialize the subprocess sandbox.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
SubprocessSandboxConfig | None
|
Sandbox configuration (defaults to standard config). |
None
|
workspace
|
Path
|
Absolute path to the workspace root. Must exist. |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If workspace is not absolute or does not exist. |
Source code in src/synthorg/tools/sandbox/subprocess_sandbox.py
execute
async
¶
Execute a command in the sandbox.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
command
|
str
|
Executable name or path. |
required |
args
|
tuple[str, ...]
|
Command arguments. |
required |
cwd
|
Path | None
|
Working directory (defaults to workspace root). |
None
|
env_overrides
|
Mapping[str, str] | None
|
Extra env vars applied on top of filtered env. |
None
|
timeout
|
float | None
|
Seconds before the process is killed. |
None
|
Returns:
| Type | Description |
|---|---|
SandboxResult
|
A |
Raises:
| Type | Description |
|---|---|
SandboxStartError
|
If the subprocess could not be started. |
SandboxError
|
If cwd is outside the workspace boundary or if no safe PATH directories can be determined. |
Source code in src/synthorg/tools/sandbox/subprocess_sandbox.py
491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 | |
cleanup
async
¶
health_check
async
¶
Return True if the workspace directory exists.
Source code in src/synthorg/tools/sandbox/subprocess_sandbox.py
errors
¶
Sandbox error hierarchy.
All sandbox errors inherit from ToolError so that sandbox failures
surface through the standard tool error path.
SandboxError
¶
Bases: ToolError
Base exception for sandbox-layer errors.
Source code in src/synthorg/tools/errors.py
SandboxTimeoutError
¶
Bases: SandboxError
Execution was killed because it exceeded the timeout.
Reserved for sandbox backends that need to signal timeout as an
exception rather than a result flag. Currently unused -- both
subprocess and Docker return SandboxResult.timed_out instead.
Source code in src/synthorg/tools/errors.py
SandboxStartError
¶
Bases: SandboxError
Failed to start the sandbox execution environment.