Documentation
¶
Overview ¶
Package tools composes the model-facing tool catalog of the mecatl kit. The correctness- and security-critical filesystem tool bodies — Read, Edit, Write, Grep, Glob, and the optional Bash — now live in the importable engine module (engine/adapter/fstools) so external consumers of engine/agent get them, and their enforced invariants, by import; this package re-exports them via alias.go and adds the host-repo-coupled tools that CANNOT live in the engine module: FetchMcpResource (MCP-coupled). WebFetch and WebSearch are re-exported from their importable engine reference adapters.
All() and Register() cover the always-available tools that need only a Workspace — the fstools filesystem tools plus WebFetch and FetchMcpResource, which need no extra dependency. Two tools are NOT in All() because they need an injected dependency and are constructed/registered separately by the composition root: Bash needs a tool.CommandRunner (NewBashTool(), an alias for fstools.NewBashTool; a deployment with no shell simply omits it), and WebSearch needs a search provider (NewWebSearchTool(provider)).
Each tool parses its session.ToolCall.Args (JSON), runs against the Workspace seam, and returns a session.ToolResult. Recoverable, model-addressable failures (a missing argument, a failed Edit invariant, a non-existent file) are returned as an *error* ToolResult via session.NewToolError so the model can read and recover from them; the Go error return is reserved for harness-level faults the model cannot act on.
Every tool carries a documentation-quality ToolSpec.Description: the description is the model's onboarding manual for the tool (gauntlet #10), so it states when to use the tool, when not to, one worked example, and its limits. Each tool also reports a correct ReadOnly() value, which drives the agent loop's read-parallel / mutate-serial dispatch (gauntlet #4).
Index ¶
- Constants
- func All() []tool.Tool
- func NewBashTool() tool.Tool
- func NewWebFetchTool() webfetch.Tool
- func NewWebSearchTool(provider tool.SearchProvider) search.WebSearchTool
- func NoFS() []tool.Tool
- func Register(cat *tool.Catalog) error
- type BashTool
- type EditTool
- type FetchMcpResourceTool
- type GlobTool
- type GrepTool
- type ReadTool
- type WebFetchTool
- type WebSearchTool
- type WriteTool
Constants ¶
const BashToolName = fstools.BashToolName
BashToolName is the catalog name of the Bash tool — the single authority for the name Bash registers under (see fstools.BashToolName). Callers probe the catalog for bash enablement by this constant rather than a literal.
Variables ¶
This section is empty.
Functions ¶
func All ¶
All returns the always-available core tools as a fresh slice, ready for registration in the composition root. The order is the canonical catalog order: the filesystem tools from engine/adapter/fstools (Read, Edit, Write, Grep, Glob) followed by the host-repo web/MCP reads. Bash is NOT included: it requires a tool.CommandRunner and is optional — add it separately via NewBashTool when a runner is configured.
FetchMcpResource (issue #223 Phase 2) is an outbound read like WebFetch, so it rides in BOTH profiles via All() and NoFS().
func NewBashTool ¶
NewBashTool constructs the Bash tool (a thin wrapper over fstools.NewBashTool). The runner is read off the tool.Environment at Execute time (issue #462), so the constructor takes no runner. The composition root registers the returned tool ONLY when a runner is available for the namespace. It is a function, not a re-exported var, so no other package can reassign the constructor.
func NewWebFetchTool ¶
NewWebFetchTool constructs WebFetch with its production network policy.
func NewWebSearchTool ¶
func NewWebSearchTool(provider tool.SearchProvider) search.WebSearchTool
NewWebSearchTool constructs the WebSearch tool bound to provider (a thin wrapper over search.NewWebSearchTool). It is a function, not a re-exported var, so no other package can reassign the constructor.
func NoFS ¶
NoFS returns the core tools available in a NO-filesystem session (the "no-fs" session profile): WebFetch + FetchMcpResource. Every file-touching core tool — Read, Edit, Write, Grep, Glob (and the separately-constructed Bash) — is deliberately absent: a no-FS session has no workspace, so offering them would only generate honest-but-useless not-exist errors and burn turns. The composition root (internal/app registerCoreTools) selects NoFS() vs All() per the session's catalog profile; this is the single definition of the no-FS core surface. FetchMcpResource (issue #223 Phase 2) is an outbound read that needs no filesystem, so it stays in the no-FS profile alongside WebFetch.
func Register ¶
Register adds the always-available core tools (everything in All(), i.e. NOT Bash) to cat. It returns the first registration error (e.g. a name collision) encountered, or nil on success. To enable command execution, additionally register NewBashTool(), e.g. cat.MustRegister(tools.NewBashTool()).
Types ¶
type BashTool ¶
BashTool runs a shell command via an injected tool.CommandRunner. See fstools.BashTool.
type EditTool ¶
EditTool replaces an exact substring, enforcing the three Edit invariants. See fstools.EditTool.
type FetchMcpResourceTool ¶
type FetchMcpResourceTool struct {
// contains filtered or unexported fields
}
FetchMcpResourceTool fetches the contents of an https:// resource URI returned by an MCP tool's resource_link (issue #223 Phase 2). It is the client-side affordance that lets the model ACT on a resource_link Phase 1 surfaced as a typed block.
SECURITY (Decision #5 of issue #223): server-returned resource_link URIs are NEVER auto-dereferenced blindly. Only https:// URIs are client-fetched, and every one is validated through session.ValidateMediaURL — the STRICTER SSRF IP-deny (no plaintext-http-to-loopback, IP-deny for the metadata IP / RFC1918 / link-local / CGNAT, inet_aton-style rejection) — both on the request URL AND on each redirect target's origin. Non-https schemes (perf://, file://, custom) stay SERVER-readonly: the tool returns a model-facing error pointing the model at ReadMcpResource with the owning server name, rather than guessing which server owns the URI.
SSRF is defended at TWO layers, each closing a gap the other cannot:
- URL-STRING layer (redirects): the per-call client's CheckRedirect re-runs session.ValidateMediaURL on every redirect target's origin URL string. A public origin that 302s to https://169.254.169.254/ is rejected before the redirect dial.
- DIAL-IP layer (initial + redirects): the transport's DialContext resolves the hostname via net.DefaultResolver.LookupIPAddr and calls session.ValidateResolvedIP on each resolved IP, rejecting any that is not a routable public address. This closes the DNS-rebinding window the URL-string layer cannot: an attacker-controlled resolver can answer ValidateMediaURL's hostname check with a public IP, then return 169.254.169.254 (or RFC1918) when the dialer actually connects. The dial-time check fires on BOTH the initial hop and every redirect dial (a redirect that passed the URL-string screen still dials through this transport), so neither layer is bypassable by the other.
It is read-only (an outward read, no mutation), so it slots into the loop's read-parallel dispatch path. Its http.Client is constructed PER CALL (a bounded one-shot fetch), so it owns no outlives-a-call resource and needs no CLOUD-NATIVE.md List 1 inventory row (ADR 0059 caveat).
The zero value is the production tool (per-call client). Tests inject a custom http.Client via withHTTPClient to drive the fetch path offline.
func (FetchMcpResourceTool) Execute ¶
func (t FetchMcpResourceTool) Execute(ctx context.Context, in session.ToolCall, _ tool.Environment) (session.ToolResult, error)
Execute parses+validates the call, then either fetches an https:// URI or guides the model to ReadMcpResource for non-https URIs. Recoverable failures (a missing uri, a rejected SSRF target, a non-https scheme, a fetch error) are returned as model-facing tool errors (NewToolError), never a Go error — the Go error return is reserved for harness-level faults (ctx cancellation).
func (FetchMcpResourceTool) ReadOnly ¶
func (FetchMcpResourceTool) ReadOnly() bool
ReadOnly reports that FetchMcpResource is a read-only operation (an outward fetch, no state mutation), so it runs in the loop's read-parallel batch.
func (FetchMcpResourceTool) Spec ¶
func (FetchMcpResourceTool) Spec() tool.ToolSpec
Spec returns the model-facing specification of the FetchMcpResource tool.
type ReadTool ¶
ReadTool reads a file and records the read for Edit's read-before-edit invariant. See fstools.ReadTool.
type WebFetchTool ¶
WebFetchTool is the importable engine WebFetch implementation re-exported for existing root-module consumers.
type WebSearchTool ¶
type WebSearchTool = search.WebSearchTool
WebSearchTool graduated into the importable engine module (engine/adapter/search, issue #363). The body and its correctness/security invariants live once, in engine/adapter/search; this is a thin type/func alias, not a re-implementation, so there is no second copy to drift.