Detection Workbench
Supports running the Snort 3 engine through Docker as the preferred, isolated backend (pinned Cisco Talos snort3 image derived locally), with containers run with no network, a read-only root filesystem, no capabilities, and evidence mounted read-only; the backend in use is reported by get_status.
Runs the Snort 3 engine on registered pcap evidence: validates rule files with lint findings, executes rules offline against captures, returns parsed alerts, explains alerts by reassembling the stream, profiles rules and suggests tuning targets, tests tuning changes before/after, diffs runs, and converts Snort 2 configs via snort2lua (Cisco Talos Registered/Subscriber rules can be supplied as local files).
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Detection Workbenchcreate a case on ~/captures/test.pcap, run my rule, and list alerts"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Detection Workbench
An offline workbench, exposed as an MCP server, for writing, testing, explaining and tuning Snort 3 detections against real evidence. Your MCP client's model does the reasoning; the server runs Snort on files you register and returns structured, bounded results. Every answer about what a rule does is backed by actual Snort output, and every run is written to a case file you can export as a report.
It works only on files on disk. It never sniffs an interface, runs inline, or touches a live sensor or SIEM.
A long-form write-up with a worked example, use cases and example output is in docs/writeup.md. A complete example case directory, with every file explained, is in docs/examples/.
Install
Requires Python 3.12+ and uv. It runs on Linux and macOS (Windows through WSL2) and has been developed and tested on Linux under WSL2.
git clone https://github.com/andrewbrooks/detection-workbench.git ~/detection-workbench && cd ~/detection-workbench
uv syncSnort 3 is needed in one of two forms ([snort].backend = "auto" prefers native, then Docker):
Docker (works anywhere Docker runs). The official Talos image is pinned by digest:
docker pull ciscotalos/snort3@sha256:f15f714fd61ade114b1039687dd43352cae26cd6401b89f2b03404e0d21e322fRuns use --network none --read-only --cap-drop ALL --user <you> with inputs mounted read-only. The image is Snort 3.10.0.0.
On first use the workbench builds a small local image from it (detection-workbench/snort3:..., a few seconds, no network). The
published image keeps Snort under a home directory that only its own user (uid 1000) can enter, so a container running as your
user would fail with "permission denied" on any other uid. The derived image adds search permission on those directories and
nothing else; no capability is added to the container. get_status reports the image in use.
Native. Install Snort 3 so snort is on PATH (build from source, or Homebrew on macOS: brew install snort; check snort -V reports 3.x). Stock config is found at <prefix>/etc/snort/, /usr/local/etc/snort/ or
/opt/homebrew/etc/snort/; override with [snort].defaults_lua.
Check with get_status once connected, or run the demo: uv run scripts/demo_noisy_rule.py.
Related MCP server: retriage
Configure
~/.detection-workbench/config.toml (override the path with DW_CONFIG). Everything is optional.
case_dir = "~/.detection-workbench/cases" # cases live outside the repo by default
allowed_roots = ["~/captures", "~/rules"] # evidence may only be registered from here (and the case dir)
[limits]
timeout_s = 120 # per engine process
max_input_bytes = 2147483648
max_rules_bytes = 52428800
max_alerts_returned = 200 # per call; totals are always reported
max_alerts_parsed = 250000
payload_display_bytes = 512
error_excerpt_lines = 20
[snort]
backend = "auto" # auto | native | docker
binary = "snort"
# defaults_lua = "/usr/local/etc/snort/snort_defaults.lua"allowed_roots is empty by default, so only files inside the case directory can be registered until you add yours.
Connect
The server speaks MCP over stdio. Add it to any MCP client's server configuration, for example:
{
"mcpServers": {
"detection-workbench": {
"command": "uv",
"args": ["--directory", "/home/you/detection-workbench", "run", "detection-workbench"]
}
}
}The server's instructions (also exposed as the detection_engineering prompt) teach the client the workflow:
start a case, write → validate → run → confirm it fires and stays quiet, tune the rule before suppressing, prove changes
with test_tuning, and be honest about what one capture proves.
Tools
Area | Tools |
Case |
|
Snort |
|
A case is a directory of JSON files plus an append-only events.jsonl; see docs/case-schema.md.
Runs are immutable and record the engine and version, argument list, input hashes, and rule-set hash.
export_case writes a report with the analyst summary (set with update_case), an overview of the captures, engines and rule sets, findings, per-run alert tables, tuning decisions with before and after counts, caveats (stream warnings, truncated or failed runs, single-sample limits), an event timeline and a run appendix. The report presents recorded data; the conclusions in it are the summary the analyst or client wrote. See the example case.
Safety model
The server parses untrusted evidence and passes model-written text to native binaries, so:
No shell. Commands are argument lists; there is no
shell=Trueanywhere (a test greps for it).No config injection. Rules and settings go into generated files in the run directory. Values that appear in generated Lua pass through one typed, tested escaping module that rejects anything not plain. Snort's
--luais never used. Rule sets containingincludedirectives are refused, since Snort would open the named file.Path control. Reads are limited to
allowed_rootsand the case directory after symlinks are resolved; devices, FIFOs, sockets and directories are refused. Evidence is hashed at registration. For every run the file is opened without following symlinks, its location is checked on the open file, and it is copied into the run directory while being hashed; the engine analyses that verified copy (deleted afterwards), so a file cannot be swapped between the check and the use, and the engine never sees the original filename.Offline only. The only packet source is
-r <one registered pcap>with the pcap DAQ in read-file mode. A final gate rejects interface, inline, other-DAQ and plugin-path arguments, and no tool has a parameter for them.Limits. Per-run timeout that kills the whole process group (or the named container), input-size caps, alert caps per call, a minimal environment, and refusal to run as root. Docker runs have no network, a read-only root filesystem, and no capabilities.
Choose Docker for evidence you do not trust. The Docker backend runs Snort with no network, a read-only filesystem and no capabilities. The native backend runs Snort as your own user with none of that isolation, so a flaw in Snort's parsing of a hostile capture would run with your privileges. (Access to the Docker daemon is itself powerful; only run this as a user you trust with it.)
Bounded output. Raw stdout/stderr are never returned: only parsed results and a short error excerpt. Payloads are shown as truncated hex plus printable ASCII.
Write discipline. Writes go only inside the case directory or your
allowed_roots, at paths you name, and never through a symlink. Existing files, and anything registered as evidence, are never overwritten:write_rules_filereturns a diff instead.Private by default. Case directories and the files in them are owner-only. Cell values in the CSV export that a spreadsheet would read as a formula (starting with
=,+,-or@) are quoted, and findings and notes cannot add headings to the report.
Talos Registered/Subscriber rules need your Oinkcode and licence: the workbench never downloads them and accepts them only as local files you point to.
Known limitations
Verified on Snort 3.10.0.0 only (the Docker image). The latest upstream is 3.12.4.0; the integration tests pin the behaviours below so an upgrade shows up as a test diff. Native Linux/macOS installs are supported by the code but untested.
Un-ACKed TCP data is not inspected by Snort 3.10, so rules on service buffers (
http_uriand similar) can miss on flows where the peer never acknowledged the request (truncated or one-sided captures). Raw-packet rules still fire.run_pcapreports these flows instream_caveats;flush_one_sided=truerecovers purely one-sided flows at the cost of changing how some raw rules match on them. Details in docs/notes.md (A6b).pkt_numfor alerts on reassembled data is the packet that triggered the flush (usually the peer's ACK), not the packet carrying the matched bytes.explain_alertreassembles the stream itself and reports the data packets.Each run temporarily copies its pcap into the run directory (up to
max_input_bytes) and deletes the copy afterwards, so large captures cost disk space and time while a run is in progress.convert_snort2does not followincludelines (it runssnort2lua -i). A Snort 2 config that pulls rules in withincludeconverts only what is written in the file itself, and the result is reported aspartialwith notes naming the skipped lines. Convert each rules file separately.Snort is silent about a rule with no
sid.validate_rulesadds separateworkbench_lintfindings for this and other hygiene problems.Validation reports cascade noise: a missing
;makes Snort misreport the next rule. The workbench re-checks suspect rules singly.SELinux. On hosts that enforce SELinux, Docker bind mounts may need volume labels (
:z), which the Docker backend does not add.Evidence text reaches the model. Packet payloads, rule messages and filenames appear in tool output, so a hostile capture can contain text written to look like instructions. The server's instructions tell the model to treat it as data, but that is guidance, not enforcement: review what the model proposes, particularly rule changes.
One client per server process. The active case is server state, so concurrent clients would share it. Run one server per client.
One capture is one sample; results on synthetic or small captures say little about production traffic.
Phases 2 (Zeek/tshark pivots) and 3 (Zircolite/Sigma regression harness) are designed in docs/plan.md but not built.
Development
uv run pytest -q # unit + parser tests, no Snort needed
DW_INTEGRATION=1 uv run pytest -q tests/integration # needs Docker or native Snort 3
uv run scripts/make_fixtures.py # regenerate synthetic captures (scapy)
uv run scripts/record_snort_outputs.py # re-record real Snort output used by parser testsReal-world captures are never committed. To run the opt-in real-capture test, set DW_REAL_PCAPS to a directory of your own pcaps
(DW_INTEGRATION=1 DW_REAL_PCAPS=~/captures uv run pytest -q tests/integration -k real); it is skipped when unset.
Contributing and security
See CONTRIBUTING.md for setup, the rules the code relies on, and how to add an engine. Report vulnerabilities privately as described in SECURITY.md.
License
Apache License 2.0. See LICENSE.
Available Tools
21 toolsadd_findingB
Record a short statement supported by specific runs, e.g. 'SID 1000042 fires 300 times, 95% from 10.0.4.20'. Run and evidence ids must exist. Starts as status 'open'. Example: add_finding(statement="SID 1000042 is dominated by one scanner", run_ids=["r-0002"])
| Name | Required | Description | Default |
|---|---|---|---|
| run_ids | Yes | ||
| statement | Yes | ||
| evidence_ids | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It discloses that referenced ids must exist and that the new finding starts with status 'open', but it omits permissions, duplicate handling, return behavior, and other mutation side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded, compact, and uses examples efficiently. The inline statement example and the example call serve different purposes without adding substantial waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with no annotations, 0% schema coverage, and no output schema, the description covers the core purpose, id existence constraints, initial status, and an example. It still leaves gaps around return values, optional evidence behavior, and side effects.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate. It explains that statement is a short supported assertion and illustrates run_ids through the example, while also noting evidence ids must exist, but it does not clarify that evidence_ids is optional or define array semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Record a short statement supported by specific runs.' It is clear what the tool creates, but it does not explicitly distinguish it from siblings such as update_finding or add_note.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a prerequisite ('Run and evidence ids must exist') and an invocation example, implying when the tool is appropriate. It does not explain when to use add_finding versus update_finding or add_note, nor does it state exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
add_noteC
Add free-text context to the case. Example: add_note(text="Capture taken during the 14:00 scan window")
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It implies a mutation but does not disclose whether the note is appended or replaces existing context, what permissions are required, or what the tool returns.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The definition is short and front-loaded, with the core purpose stated first and an example second. It avoids unnecessary repetition, though the example could be seen as slightly redundant with the purpose sentence.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
As a mutation tool with no annotations, no output schema, and an undocumented parameter, the description should do more. It doesn't explain persistence, side effects, or when to prefer this over closely related siblings such as add_finding.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single parameter is undocumented in the schema (0% coverage), but the description partially compensates by calling it free-text context and showing an example value. It still lacks constraints, formatting expectations, or length limits.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a clear verb/resource pair: adding free-text context to a case. It distinguishes itself somewhat from siblings like add_finding or register_evidence by emphasizing free-text notes, but it doesn't explicitly contrast the alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use add_note versus add_finding, register_evidence, or update_case. The example clarifies the shape of a call but not the decision criteria for choosing this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_caseB
Create a case and make it active. Every run, finding and decision is recorded in it. Example: create_case(title="Noisy SID 1000042 on the proxy capture")
| Name | Required | Description | Default |
|---|---|---|---|
| title | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It usefully discloses that the case becomes active and that runs, findings, and decisions are recorded in it, but it omits return values, failure conditions (e.g., if a case is already active), and permissions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences plus a short example, front-loading the core action and state change. Every element contributes without waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter creation tool with no annotations or output schema, the description covers purpose, activation, and container behavior. It falls short on routing against the sibling 'open_case' and on what the caller receives or how errors are signaled.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% for the single 'title' parameter. The example ('Noisy SID 1000042 on the proxy capture') adds practical meaning about the expected title content, but no constraints or naming rules are stated.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Create a case') and adds that the new case is made active, which goes beyond the title alone. However, it does not differentiate this from the sibling 'open_case', leaving the create-vs-open distinction unresolved.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit guidance on when to use create_case versus alternatives such as open_case, list_cases, or get_case. The example implies a scenario (creating a case for a noisy SID) but does not state selection criteria or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
diff_runsC
Alerts added, removed and changed between two runs, grouped by SID. Example: diff_runs(run_a="r-0002", run_b="r-0003")
| Name | Required | Description | Default |
|---|---|---|---|
| run_a | Yes | ||
| run_b | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It discloses that output is grouped by SID and lists alert categories, but omits critical behavioral details such as directionality (diff from A to B?), run existence requirements, error behavior, and full return shape.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences: purpose first, example second. It is front-loaded and contains no superfluous language.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter diff tool with no output schema and no annotations, the description covers the core purpose and shows an example call. However, it leaves gaps around directionality and return structure that an agent would need to invoke and interpret the tool confidently.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate. It gives an example with run_a and run_b as run IDs, but does not explain the semantics of the parameters, such as which run is the baseline or the expected ID format beyond the example.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific operation: diffing alerts between two runs, with added, removed, and changed categories and SID grouping. It distinguishes the tool's core behavior but does not explicitly contrast it with siblings like get_alerts or list_cases.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides an example call but no guidance on when to use this tool versus alternatives. There are no preconditions, exclusions, or statement of what situations call for a run diff.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
explain_alertA
Facts about one alert: the rule text and parsed options, the 5-tuple/direction/service, a bounded hex+ASCII dump, and which content/pcre options appear in the payload and at what offsets (wire bytes reassembled from the pcap, plus Snort's own inspected buffer). Report facts; you do the explaining. Example: explain_alert(run_id="r-0002", alert_idx=0)
| Name | Required | Description | Default |
|---|---|---|---|
| run_id | Yes | ||
| alert_idx | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the behavioral burden and does well: it discloses that the dump is bounded, that offsets come from wire bytes reassembled from the pcap and Snort's inspected buffer, and that the tool reports facts rather than doing analysis. It does not explicitly state read-only behavior, permissions, or error cases, keeping it from a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the main purpose and uses a compact example. It is appropriately sized, though the dense technical list is slightly harder to scan than a shorter, more structured explanation would be.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, but the description enumerates the returned information in enough detail for an agent to understand what facts it will receive: rule text, parsed options, tuple, bounded dump, and offset findings. It is not fully complete regarding response shape or error behavior, but it is substantially adequate for this two-parameter inspection tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It does so only partially through the example explain_alert(run_id="r-0002", alert_idx=0), which implies alert_idx is zero-based, but it does not define run_id's source, alert_idx bounds, or the relationship between the two parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific resource, 'one alert,' and enumerates the facts returned: rule text, parsed options, 5-tuple/direction/service, hex+ASCII dump, and content/pcre offsets. It does not explicitly differentiate itself from siblings such as get_alerts or pcap_summary, so it stops short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'Report facts; you do the explaining' implies this tool is for fact gathering rather than analysis, which is useful context. However, it gives no explicit when-to-use guidance, prerequisites, or alternatives such as get_alerts or pcap_summary.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
export_caseA
Export the case as a Markdown report ('markdown') or a Timesketch-importable CSV ('timesketch_csv'). Without a path the file goes in the case's exports/ folder. A path must end in .md or .csv and an existing file is only replaced with overwrite=true. Example: export_case(format="markdown")
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | ||
| format | No | markdown | |
| overwrite | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations at all, the description carries the full burden, and it does meaningful work: it discloses the default write location (the case's exports/ folder), the extension constraint on path, and the safety behavior that an existing file is only replaced when overwrite=true. It does not say whether the case must be open first or what the call returns, leaving a modest gap for a filesystem-writing operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three compact sentences plus a call example, front-loaded with the purpose and format choice, then the path rule, then the overwrite safeguard. Every sentence adds a distinct behavioral fact; nothing is restated from the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 3-parameter, no-output-schema tool the description covers purpose, format selection, default location, naming constraint, and overwrite safety. The remaining gap is that with no output schema, it never says what the call returns (e.g., the written file path) or whether multiple exports overwrite by naming convention.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% (only titles and defaults), so the description must supply semantics and largely does: all three parameters get meaning beyond the schema, including the two valid format values that are not encoded as an enum, the constraint that path must end in .md or .csv, and the default directory when path is omitted. Only overwrite's boolean default is left to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Export the case') and immediately enumerates the two output forms it can produce ('markdown' report or 'timesketch_csv'). No sibling tool in the list exports case data, so the scope boundary is unambiguous without naming a competitor.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explains what each format is for (human-readable Markdown vs. Timesketch-importable CSV), which is enough for an agent to choose between them, and gives the default ('markdown' via the example). It stops short of explicit when-not-to-use guidance or prerequisites (e.g., must the case be open?), which is why it is not a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_alertsB
Page or filter a run's alerts by SID, source/destination address or packet range. Example: get_alerts(run_id="r-0002", sid=1000042, src="10.0.4.20", limit=20)
| Name | Required | Description | Default |
|---|---|---|---|
| dst | No | ||
| sid | No | ||
| src | No | ||
| limit | No | ||
| offset | No | ||
| pkt_to | No | ||
| run_id | Yes | ||
| pkt_from | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full disclosure burden. It implies a read via 'Page or filter' but never states that it is read-only, non-destructive, what the default page size is, or how pagination termination works — for an 8-parameter list tool with zero annotation coverage this is a substantial gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with zero waste: capability first, then a compact, immediately usable invocation example. Nothing is repeated from the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 8-parameter filter tool with no annotations and no output schema, the description leaves the return shape (list of alerts? total count?) and several parameter meanings unaddressed. It is adequate to start a call but not complete enough to invoke confidently across all filters.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate; it names run_id, sid, src, dst, limit and the packet range, and the example anchors concrete values. However, offset and the semantics of pkt_from/pkt_to (inclusive? packet index vs number?) and SID meaning are left undefined, so it only partially compensates.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Page or filter') and resource ('a run's alerts') with the scoping key (run_id) and the dimensions available for filtering. It is distinguishable from siblings like explain_alert or pcap_summary, though it does not explicitly contrast itself with them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by 'Page or filter', and the example shows a typical filtered call, but there is no statement of when to prefer this over explain_alert or pcap_summary, and no preconditions (e.g., the run must already exist).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_caseB
Summary of the active case: evidence, findings, decisions, notes and recent runs.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are supplied, so the description carries the full disclosure burden. It does usefully state the composition of the returned summary, implying a read-only aggregate, but says nothing about failure behavior when no case is active, result size, or whether the summary is truncated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One short sentence with no filler, and the core noun 'active case' is front-loaded. The only soft redundancy is restating the tool name as 'Summary,' but the enumerated contents earn their space.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no parameters and no output schema, the description must alone convey what the agent gets back, and it does list the content categories. It stops short of explaining what defines the 'active case' or what happens when none exists, which matters for a zero-argument tool that depends entirely on ambient state.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, which is the baseline-4 case. The description's mention of 'the active case' is consistent with the empty schema and confirms the tool is implicitly scoped rather than parameterized.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the resource and enumerates its contents (evidence, findings, decisions, notes, recent runs), which tells an agent roughly what comes back. However, it is a noun phrase with no verb, and it never distinguishes itself from siblings like list_cases, get_status, or export_case, which an agent could plausibly reach for instead.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance and no mention of alternatives. The phrase 'the active case' weakly implies it operates on an ambient current case rather than an ID, but the agent is left to infer when this call is appropriate versus list_cases or get_status.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_statusA
Engine versions and backend (native or Docker), config location, allowed_roots, limits and the active case. Call this first if something is unavailable.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations at all, so the description carries the full burden. It does disclose the returned information set and implies a non-mutating diagnostic read, but never explicitly says the call is read-only, side-effect free, or whether it requires the engine to be running. For a low-risk zero-param status check that is acceptable but not generous.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the returned fields, with the operational hint last. No filler. Minor deduction because the first sentence is a verbless fragment ('...limits and the active case'), which reads slightly clipped.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description must describe return contents and it does so thoroughly for a status endpoint. Missing only the return format/shape (e.g. structured vs. text) and the failure behavior alluded to by 'if something is unavailable'.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing for the description to disambiguate. Baseline of 4 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Enumerates exactly what the tool reports: engine versions, backend type (native or Docker), config path, allowed_roots, limits, and the active case. That is a concrete resource scope an agent can distinguish from data-access siblings like get_case or list_cases. It stops short of a clean verb+object statement (the sentence is a bare noun list), but the substance is clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"Call this first if something is unavailable" gives one concrete triggering condition, which is genuinely useful for a diagnostic tool. It does not cover the general case (inspecting environment/config before other operations) or state when it is unnecessary, so guidance is implied rather than complete.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_casesB
List cases in the case directory with ids, titles and status.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It usefully discloses the returned fields (ids, titles, status), which gives some sense of the read shape, but it omits ordering, pagination, volume, and permission/safety context expected for an unannotated tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no wasted words. Appropriately sized for a zero-parameter list tool, though it is perhaps a bit terse given the sibling set.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-param read tool with no output schema, the description covers the essentials (what is returned) but leaves out ordering, result size, and how it relates to get_case. Adequate but with clear gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters and the schema is empty with 100% coverage, so there is nothing for the description to clarify — the baseline of 4 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('List') and resource ('cases in the case directory') plus the fields returned (ids, titles, status). It is implicitly distinguishable from get_case (singular retrieval), though it never names or contrasts with that sibling explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit guidance on when to use this versus get_case or the other case-related siblings, and no mention of ordering, pagination, or filtering expectations. The listing intent is only implied by the verb 'List'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
open_caseC
Make an existing case active. Example: open_case(case_id="20261022-noisy-sid-1000042")
| Name | Required | Description | Default |
|---|---|---|---|
| case_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and discloses almost none of it: no statement of permissions, no side effects on other cases (e.g. whether a currently active case is deactivated), no error behavior for invalid or already-open cases. 'Make active' implies a state mutation but leaves its consequences unstated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences: purpose first, example second. No filler, though the example is arguably doing parameter work that a brief clause about case_id could do more directly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a state-mutating tool with no annotations and no output schema, the description says nothing about the resulting state, return value, or failure modes. An agent knows the intent but not the consequences, which is insufficient for a mutation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate for the single required case_id. The concrete example ("20261022-noisy-sid-1000042") usefully conveys the ID format, but the parameter itself is never named or explained and its required-ness and accepted forms are left to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and effect on a specific resource: making an *existing* case active, which separates it from create_case or get_case. It does not explain what 'active' means as a state (versus update_case or other statuses), so the purpose is clear but not fully differentiated from every sibling.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to open a case versus updating it, what prerequisites exist, or what happens if the case is already active or closed. The only added content is a literal example invocation, not usage conditions or alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pcap_summaryB
Packet count, time range, protocols, top talkers and services for a registered pcap. Example: pcap_summary(evidence_id="e-0001")
| Name | Required | Description | Default |
|---|---|---|---|
| evidence_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the full burden, and it partly discharges it by disclosing the exact return contents, which implies a non-mutating read. It does not say anything about permissions, cost, behavior on a missing/unregistered evidence_id, or whether the pcap is re-parsed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with the return payload front-loaded and an example appended. No filler, though the example consumes a full sentence for modest added value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and no annotations, the description is the sole source of truth. It covers the return fields adequately but omits error behavior and the registration prerequisite beyond an oblique hint, leaving an agent guessing about prerequisites for a forensic evidence tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate and it only partly does: the example shows evidence_id is passed as a short string identifier like 'e-0001', which clarifies the expected format. It does not state that the ID must refer to a registered pcap or what happens otherwise.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the resource (a registered pcap) and enumerates the concrete facts it returns: packet count, time range, protocols, top talkers, services. That is specific enough to distinguish it from run_pcap or get_alerts, though the verb itself ('summarize') is only implied rather than stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'for a registered pcap' implies the prerequisite that evidence must be registered first, which is genuinely useful routing information. However, it never states when to use this versus run_pcap or get_alerts, and gives no exclusions or failure conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
profile_rulesB
Run the rules with Snort's rule profiler and return the slowest rules with checks, matches and time. Example: profile_rules(pcap_id="e-0001", rules_id="e-0002", top=10)
| Name | Required | Description | Default |
|---|---|---|---|
| top | No | ||
| pcap_id | Yes | ||
| rules_id | No | ||
| rules_text | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the behavioral burden. It does disclose the return fields (checks, matches, time) and identifies the operation as a profiling run, but it doesn't mention cost, whether the rules source is required, or anything about error conditions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two compact sentences with a concrete call example, front-loading the action and the return shape. The example repeats parameter names visible in the schema, but it usefully signals the id format (e-0001).
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 4-parameter tool with no annotations, no output schema and zero schema coverage, the description covers the purpose and the return fields but omits how to supply rules (rules_id vs rules_text), the meaning of top, and any usage constraints.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, but it only illustrates pcap_id, rules_id and top in the example. The fourth parameter rules_text, the likely mutual exclusivity between rules_id and rules_text, and the default of top=20 are all left unexplained.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: run Snort's rule profiler on rules and return the slowest rules with checks, matches and time. That distinguishes it from sibling tools like validate_rules or run_pcap, though no sibling is named explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The stated output (slowest rules) implies the use case of finding performance hotspots, but there is no explicit when-to-use, when-not-to-use, or pointer to alternatives such as suggest_tuning_targets or test_tuning, which would help the agent choose.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
register_evidenceA
Register a pcap/pcapng or rules file in the active case (hashed, type-detected, never copied or modified). The path must be under allowed_roots. Returns the evidence id (e-0001 ...) used by other tools. Example: register_evidence(path="~/captures/proxy.pcap")
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | ||
| type | No | ||
| label | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses that the file is hashed and type-detected, that it is never copied or modified (a strong non-destructive guarantee), that an allowed_roots constraint applies, and the shape of the returned id. It omits error behavior on invalid paths or duplicates, and whether registration mutates the active case.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight lines: the effect and its guarantees first, then the constraint, then the return value, then a single example. Every sentence contributes new information and nothing is repeated from the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 3-parameter entry-point tool with no annotations and no output schema, the description supplies the essential context: what is done to the file, the path restriction, and the id returned for downstream tools. The gap left is the undocumented `label` parameter and failure modes, which is a modest but real omission.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It documents `path` reasonably (allowed_roots constraint plus an example format) and the file-type vocabulary ('pcap/pcapng or rules') hints at valid `type` values, but it never explains the optional `type` override versus the automatic type detection, and `label` is not mentioned at all.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific verb (register) and specific resource types (pcap/pcapng or rules file) scoped to the active case, and states what the operation does mechanically: hashed, type-detected, never copied or modified. The closing sentence that it returns the evidence id used by other tools positions it unambiguously against siblings like write_rules_file and the analysis tools (run_pcap, validate_rules) that consume the id.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides one hard precondition ('path must be under allowed_roots') and a concrete example call, which is real guidance for invoking it correctly. However, it never states when to choose this over alternatives, whether re-registering the same path is allowed, or what to do when the path is outside allowed_roots; usage is implied rather than spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
run_pcapB
Run rules against a registered pcap. Returns the run id, total alerts, counts by SID with msg, the first alerts, and stream_caveats (flows where Snort cannot inspect un-ACKed data). home_net is an IP/CIDR or list like '[10.0.0.0/8,192.168.0.0/16]'; no raw Lua is accepted. Example: run_pcap(pcap_id="e-0001", rules_id="e-0002", home_net="10.0.0.0/8")
| Name | Required | Description | Default |
|---|---|---|---|
| pcap_id | Yes | ||
| profile | No | ||
| home_net | No | ||
| rules_id | No | ||
| rules_text | No | ||
| external_net | No | ||
| flush_one_sided | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden and does well by disclosing the return payload: run id, total alerts, counts by SID with msg, first alerts, and stream_caveats. It also explains stream_caveats as flows Snort cannot inspect for un-ACKed data. Gaps remain around permissions, side effects, and whether the run is persisted, but the disclosed behavior is substantially richer than the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core action and return shape, followed by parameter guidance and an example. It is informative without excessive verbosity, though the long first sentence packs several return fields together.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There are no annotations, no output schema, and 0% schema description coverage across seven parameters. The description explains the return values and a few parameters, but it is not complete enough to confidently invoke optional parameters such as profile, external_net, rules_text, or flush_one_sided.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, but it only meaningfully covers pcap_id, rules_id via the example, and home_net formatting. It leaves profile, rules_text, external_net, and flush_one_sided unexplained, even though rules_text versus rules_id is especially important to clarify.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: "Run rules against a registered pcap." It also previews the return payload, making the operation concrete. It does not explicitly distinguish this from siblings such as validate_rules or pcap_summary, so it stops short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage by requiring a registered pcap and giving a concrete example, and it notes that no raw Lua is accepted. However, it does not state when to use this tool versus validate_rules, pcap_summary, get_alerts, or other siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
suggest_tuning_targetsB
Rank the noisiest SIDs in a run by count, with distinct sources/destinations and how concentrated the hits are in one source. Example: suggest_tuning_targets(run_id="r-0002")
| Name | Required | Description | Default |
|---|---|---|---|
| top | No | ||
| run_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations and no output schema, the description does useful work by disclosing what the ranking exposes (hit counts, distinct sources/destinations, source concentration). It says nothing about safety profile, cost of scanning a run, or limits on the ranking beyond the default top value.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences, front-loaded with the core verb and resource, followed by a concrete example that clarifies the run_id format. Nothing is redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Without an output schema, the description's summary of returned metrics is the main source of return-value information and it covers it adequately. The remaining gaps are the undocumented top parameter and the lack of sibling routing guidance.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must carry parameter meaning. It illustrates run_id indirectly via the example ("r-0002"), but the top parameter is never mentioned, and its role in bounding the ranking must be guessed from the name and default.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific action and resource: ranking the noisiest SIDs within a run, plus the metrics returned (count, distinct sources/destinations, concentration). This is materially different from siblings like profile_rules or test_tuning, though it never explicitly contrasts itself with them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no statement of when to call this versus alternatives such as profile_rules, get_alerts, or test_tuning, and no prerequisites or exclusions. The sample invocation shows the call shape but not the decision context, so usage is only inferable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
test_tuningA
Apply one structured change to a copy, re-run the same pcap, and return before/after counts per SID. Records a decision. change.kind is one of: suppress: {kind, sid, track:'by_src'|'by_dst', ip} event_filter: {kind, sid, type:'limit'|'threshold'|'both', track, count, seconds} rate_filter: {kind, sid, track, count, seconds, new_action, timeout} rule_edit: {kind, sid, rule:''} Example: test_tuning(before_run_id="r-0002", change={"kind":"suppress","sid":1000042,"track":"by_src","ip":"10.0.4.20"}, reason="known scanner")
| Name | Required | Description | Default |
|---|---|---|---|
| change | Yes | ||
| reason | Yes | ||
| before_run_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the full burden. It does disclose valuable traits: the change is applied to a copy (live ruleset untouched), the pcap is re-run (costly operation), before/after per-SID counts are returned, and a decision record is persisted. It omits failure modes, whether before_run_id must reference an existing run, and whether repeated calls are idempotent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose sentence is front-loaded, followed by the variant specs and a single worked example that exercises all three parameters. No filler; every line is load-bearing for correct invocation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a nested object with zero schema descriptions, no annotations, and no output schema, the description covers the hard part (change variants) and states the return shape. The remaining gap is the provenance of before_run_id and what happens when the change is invalid or the run id is unknown.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% and the `change` object is opaque (additionalProperties: true), so the description must compensate — and it does, enumerating the exact required fields for all four change.kind variants. before_run_id and reason are only illustrated by the trailing example, not defined (e.g. where the run id comes from, why reason is required).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a precise action chain: apply one structured change to a copy, re-run the same pcap, return before/after counts per SID. The "to a copy" phrasing implicitly separates it from write_rules_file, but no sibling is named explicitly, so the differentiation is left to inference.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies a hypothesis-testing workflow (test a suppression/filter/rule edit before committing) and says it "Records a decision", but never states when to prefer this over run_pcap, diff_runs, or write_rules_file. Usage is inferable from the workflow rather than declared.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_caseA
Write the case summary (your analysis and conclusions, Markdown allowed) and/or set the status to 'open' or 'closed'. The summary appears at the top of the exported report, so cite run and finding ids in it. Call it again to revise; each change is logged. Example: update_case(summary="SID 1000042 is too broad (f-0001, r-0003); the rewrite in r-0005 fixes it.", status="closed")
| Name | Required | Description | Default |
|---|---|---|---|
| status | No | ||
| summary | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It usefully discloses that the summary appears at the top of the exported report and that each change is logged. It does not mention permissions, whether closing a case is reversible, or what happens to prior summary text beyond the logging note.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core action, followed by practical report context, revision behavior, and a concrete example. Every sentence adds useful information without waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter mutation tool with no output schema and no annotations, the description is largely complete: it covers both parameters, report placement, revision behavior, and logging. The main remaining gap is the lack of explicit guidance relative to the sibling open_case tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must define both parameters, and it does. It explains that summary is the analysis/conclusions in Markdown and should cite ids, and that status accepts 'open' or 'closed'. The example reinforces both parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: write the case summary and/or set its status. It clearly defines what fields are affected and the allowed status values. It does not explicitly distinguish this from the sibling open_case tool, which also relates to opening cases.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives useful context for using the tool: cite run and finding ids, revise by calling again, and each change is logged. However, it does not explain when to use update_case(status='open') versus the sibling open_case tool, leaving a meaningful ambiguity for an agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_findingB
Change a finding's status (open, confirmed, dismissed) or wording; history is kept. Example: update_finding(finding_id="f-0001", status="confirmed")
| Name | Required | Description | Default |
|---|---|---|---|
| status | No | ||
| statement | No | ||
| finding_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden; it usefully discloses that 'history is kept', implying an audit trail and non-destructive semantics. It does not say whether permissions are required, whether a statement edit replaces prior text, or how partial updates behave.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence plus one concrete example; nothing is padded. The example earns its place by showing the id format and the status argument.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with no annotations, no output schema, and zero schema descriptions, the description covers the status domain and audit behavior but leaves gaps around partial-update semantics (both status and statement optional/nullable), error behavior, and confirmation of return value.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate, and it does partially by enumerating status values (open, confirmed, dismissed) — real information absent from the enum-less schema. However 'wording' only loosely maps to the 'statement' parameter, and validation constraints or format for finding_id are unstated.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('change') and resource ('a finding's status or wording') and enumerates the status domain. The resource is distinct from sibling add_finding, though no sibling is named explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The example call implies how to invoke it and the status values suggest the intended use, but there is no explicit statement of when to use this versus add_finding or when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validate_rulesA
Check rules with Snort itself. Give a registered rules file (rules_id) or inline rules_text. Returns errors as {line, sid, error, plain}, warnings, and workbench_lint hygiene items (e.g. a missing sid, which Snort does not report). Fast enough for a write-test-fix loop. Example: validate_rules(rules_text='alert http any any -> any any ( msg:"x"; http_uri; content:"abc"; sid:1000001; rev:1; )')
| Name | Required | Description | Default |
|---|---|---|---|
| rules_id | No | ||
| rules_text | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral-disclosure burden and does well by describing return structure: errors as {line, sid, error, plain}, warnings, and workbench_lint hygiene items. It also notes that missing-sid lint coverage goes beyond Snort itself, though it does not explicitly state side effects, permissions, or whether validation is strictly read-only.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose, then moves efficiently through inputs, outputs, performance, and an example. It is appropriately sized overall, though the example is somewhat long and the output-detail sentence is dense.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter validation tool with no annotations and no output schema, the description supplies the key missing context: both input modes, the shape of returned errors/warnings/lint items, and expected speed. It could still be more complete about whether rules_id and rules_text are mutually exclusive, what happens if neither is supplied, and any side effects.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it does: rules_id is identified as a registered rules file, rules_text as inline rules, and the "or" phrasing makes the intended alternative input modes clear. The example further illustrates the rules_text form.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ("Check rules") and a clear method/resource ("with Snort itself"), so the core operation is unambiguous. It does not explicitly contrast itself with sibling tools such as profile_rules, test_tuning, or write_rules_file, leaving some sibling differentiation implicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase "Fast enough for a write-test-fix loop" gives a useful usage context, implying iterative rule authoring. However, it does not explicitly say when to use this versus alternatives, when not to use it, or how it relates to write_rules_file/profiling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
write_rules_fileA
Save rules to a path you name. Existing files are never overwritten unless overwrite=true; instead a diff is returned. Registered evidence is never overwritten. Example: write_rules_file(path="~/rules/local-new.rules", rules_text="alert ...")
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | ||
| overwrite | No | ||
| rules_text | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses the destructive-action policy (no overwrite by default), what happens on conflict (a diff is returned rather than data loss), and a separate protection for registered evidence. It stops short of stating required permissions or whether the returned diff is the only response payload.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences plus an example, front-loaded with the core action and the most safety-relevant constraint. The example earns its place by showing both required parameters together; the 'Registered evidence is never overwritten' sentence is slightly tangential but adds a useful guardrail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 3-parameter write tool with no annotations and no output schema, the description covers the key behavioral risk (non-overwrite + diff return) that an agent needs before calling it. Remaining gaps are path validity rules and the full response shape, which are moderate rather than blocking.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate, and it partially does: the semantics of 'overwrite' and the conflict behavior are spelled out, and the example demonstrates a realistic path and rules_text value. It never explains what the 'path' parameter accepts (absolute vs. relative, allowed roots) or the format expectations for rules_text, leaving meaningful ambiguity.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource ('Save rules to a path you name') and implicitly scopes it as the write counterpart to validate_rules/profile_rules in the sibling set. It never explicitly names a sibling, so an agent must infer the boundary, but the purpose itself is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The overwrite rule ('never overwritten unless overwrite=true; instead a diff is returned') implies the safe-write workflow an agent would follow, and the example shows a real invocation shape. However, there is no explicit when-to-use vs. validate_rules or run_pcap guidance, and no stated prerequisites for the rules file.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
21 tool updates
v0.1.0- First observed
add_finding - First observed
add_note - First observed
create_case - First observed
diff_runs - First observed
explain_alert - First observed
export_case - First observed
get_alerts - First observed
get_case - First observed
get_status - First observed
list_cases - First observed
open_case - First observed
pcap_summary - First observed
profile_rules - First observed
register_evidence - First observed
run_pcap - First observed
suggest_tuning_targets - First observed
test_tuning - First observed
update_case - First observed
update_finding - First observed
validate_rules - First observed
write_rules_file
TDQS
Scored across 21 tools
Each tool targets a distinct resource+action (case CRUD, evidence registration, findings/notes, pcap analysis, tuning tests). A few tools operate on the same run object (get_alerts, explain_alert, suggest_tuning_targets, diff_runs) but their descriptions clearly separate enumeration, single-alert forensics, ranking, and comparison. Case tools like get_case/open_case/update_case are close but distinguishable by their descriptions.
Names use snake_case throughout and are mostly verb_noun (create_case, add_finding, run_pcap, test_tuning). Minor deviations exist, notably the noun-first 'pcap_summary' and the verb-less 'diff_runs', but these remain readable and predictable.
21 tools across case management, evidence, rule validation/execution, alert analysis, and tuning is on the heavier side but each earns a distinct role. The surface feels comprehensive rather than padded for a detection-engineering workflow.
Covers the full case lifecycle (create/open/list/get/update/export), evidence registration, findings, notes, pcap analysis, rule validation, running, alert inspection, profiling, tuning tests, run diffing, and rule writing. Minor gaps: no standalone run listing/summary or evidence listing/removal, so discoverability of past runs relies on get_case.
Maintenance
Related MCP Connectors
Governed data discovery, exact queries, decisions, simulations, and runtime utilities over MCP.
Remote MCP for A2A failure replay MCP, structured receipts, audit logs, and reviewer-ready evidence.
Offline methodology engine for authorized penetration testing, CTF, and security research.
Evidence-readiness MCP server: validate, audit, and score briefs, memos, and evidence packs.
Related MCP Servers
- AlicenseCqualityAmaintenanceEnables coding agents to query, compare, and audit local profiler traces, benchmarks, memory captures, and execution evidence without uploading code or data, using CLI and MCP interfaces.111247 PyPI210MIT
- AlicenseNot gradedqualityBmaintenanceEnables MCP clients to run hardened, read-only radare2-based static binary triage tools, including disassembly, cross-reference following, string decoding, function renaming, and evidence-checked report generation without executing the sample.MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI assistants and security analysts to inspect PCAP/PCAPNG captures through MCP tools or REST endpoints, reassembling TCP/UDP streams, extracting payload artifacts, detecting CTF flags, credential leaks and network anomalies, and generating formal PDF or Markdown forensic reports. Every finding is bound to exact frame numbers, timestamps and endpoints with SHA-256 deduplicated evidence provenance.MIT
- FlicenseNot gradedqualityAmaintenanceEnables users to run Kali-based security tools for network scanning, binary and symbol analysis, string extraction, and live or captured traffic analysis through an MCP client. It also supports isolated Docker sandbox command execution with resource limits and file transfer.-