Classification

How Sealmark decides what each tool takes, so a pack only calls a tool with a target the harness owns.

shipped

Most MCP servers are not databases. Before any pack runs, Sealmark reads each tool's name, description and input schema and decides what kind of argument it takes. Nothing is called to do this. The answer decides which packs may probe the tool, and it is printed in every report so you can check it.

Tool classes#

ClassThe tool takesExample arguments
sqla SQL stringsql, query, statement
patha file or directory pathpath, file, directory, dest
urla web addressurl, uri, endpoint, or a string with format: uri
commanda program or shell stringcommand, cmd, script, or an argument list args
gita repository locationrepo_path, repository, git_dir
textother free textany string that matches nothing above
opaquenothing the harness can fillno string arguments, every argument an enum, or a required argument it has no safe value for

Only string arguments and arrays of strings count. Names are compared without case, _, - or spaces, so file_path, filePath and filepath are one name. A tool that matches several classes gets one primary class by specificity (command, then sql, then git, then path, then url, then text) and the others are recorded as secondary. A secondary url (a path tool that also has a url parameter) is also probed by net, and the report says secondary: url (probed by net). A secondary path or git is not probed, because a write probe there could only produce a vacuous pass; the tool is listed under "Not covered" with its primary class.

Confidence#

Each classification carries a confidence:

  • low: nothing strong. A generic name such as name or target with no hint in the tool's name or description stays low, and so does any tool the harness cannot fill every required argument for.
  • medium: a strong argument name (path, url, command), or a generic name backed by a hint in the tool's name or description.
  • high: a strong name and a hint from the name or description (read_file with a path argument).
  • explicit: you said so, with tools.overrides or sql_tools.

A path or git tool whose destructiveHint is true has its confidence lowered one step, and the reason is printed.

Confidence gates what runs#

Class and confidencePacks that may call the tool
any class, lowcore only, which sends it schema-invalid input
sql, medium or abovedb and sqlite
path, medium or abovefs and effects, inside the sandbox
git, medium or abovegit (needs {sandbox} in the config) and effects, inside the sandbox
url, medium or above, or a secondary urlnet (and effects inside the sandbox)
command, high or explicitexec, only with --active (a command-line flag only, never a config file or an environment variable) and the sandbox on
command, mediumcore only
text, opaque, excludedcore only

What you see in a report#

The text report has a Classification: block with one line per tool: its class, its confidence, its annotation hints and the reason.

text
Classification:
  read_text_file  path    high  [readOnly]  ← param "path", name matches /read|file/
  echo            text    low   core only: string parameters only, and none names a path, URL, command, SQL or repository; add it under tools: to include it
  add             opaque  low   core only: the tool has no string parameters; add it under tools: to include it
  packs applied: fs, effects, core

A tool that only the core checks reach is also listed under "Not covered", with a hint that depends on the reason: add the tool under tools: for an uncertain guess, or write a probes: entry when no override can make the arguments fillable. The JSON record carries the same rows as classification.

Fixing a wrong guess#

Say what a tool takes with tools.overrides. An override always wins, is printed as override: tools.overrides, and gets confidence explicit. An override that names a parameter the tool does not have is a configuration error (exit code 2) that lists the tool's parameters.

yaml
tools:
  overrides:
    legacy_thing: { class: opaque }          # never probe this tool beyond core
    fetch_page:   { class: url, params: { url: target } }
  exclude: ["admin_*"]

tools.include (default ["*"]) and tools.exclude are lists of name patterns, with * and ?. A tool they leave out is not called by any pack, core included, and is shown as excluded. All three tools.* keys are locked, so setting one makes the run CUSTOM. SQL tools are found by the rules on the configuration page, or named with sql_tools.

Related: Packs, Sandbox, Configuration.