tools

package
v0.0.20 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 28, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

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

View Source
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

func All() []tool.Tool

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

func NewBashTool() tool.Tool

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

func NewWebFetchTool() webfetch.Tool

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

func NoFS() []tool.Tool

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

func Register(cat *tool.Catalog) error

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

type BashTool = fstools.BashTool

BashTool runs a shell command via an injected tool.CommandRunner. See fstools.BashTool.

type EditTool

type EditTool = fstools.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:

  1. 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.
  2. 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

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

Spec returns the model-facing specification of the FetchMcpResource tool.

type GlobTool

type GlobTool = fstools.GlobTool

GlobTool lists files matching a glob pattern. See fstools.GlobTool.

type GrepTool

type GrepTool = fstools.GrepTool

GrepTool searches file contents for a regular expression. See fstools.GrepTool.

type ReadTool

type ReadTool = fstools.ReadTool

ReadTool reads a file and records the read for Edit's read-before-edit invariant. See fstools.ReadTool.

type WebFetchTool

type WebFetchTool = webfetch.Tool

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.

type WriteTool

type WriteTool = fstools.WriteTool

WriteTool creates or overwrites a file (read-before-overwrite on existing paths). See fstools.WriteTool.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL