Skip to main content
Glama
d3ltasecurity

opnsense-guard-mcp

opnsense-guard-mcp

A safety-first MCP server for OPNsense 26.7+.

Read-only by default. Every write is planned, policy-checked, logged, and auto-reverted unless you confirm it.

Status: alpha. Tested against a live OPNsense 26.7.4 with least-privilege API users: read tools, policy file, change planning with diffs, applying changes with verification and automatic revert, crash recovery, and a hash-chained audit log, over stdio or authenticated HTTPS. See DESIGN.md.

Not affiliated with Deciso B.V. "OPNsense" is a trademark of Deciso B.V.

What makes it different

opnsense-guard-mcp

Default mode

read-only

Read path

GET, plus POST to exactly two search endpoints (states, rules) with a fixed three-field body; path allowlist, verb denylist, traversal/encoding rejected, redirects not followed

Writes

separate API user, exact endpoint allowlist, plan → policy check → human approval → apply → verify → auto-revert unless confirmed

Rollback on 26.7+

own object-level snapshots + revert (the savepoint API is gone in 26.7); survives restarts

Guardrails

allowlist policy file: interfaces, networks, rule limits, anti-lockout

Audit

hash-chained JSONL (audit verify detects edits); syslog planned

Transport

stdio, or Streamable HTTP that always needs a bearer token; optional TLS / mTLS

Dangerous tools

none exist: no reboot, firmware, service control, SSH or XML edits

Related MCP server: OPNsense MCP Server

Quick start (read-only)

  1. In OPNsense (System → Access → Users), create a user with a scrambled password, no group (not admins) and these privileges, then create an API key for it. Skip any that aren't installed; the matching tool just reports "forbidden".

    Privilege

    Used by

    Firewall: Rules [new]

    firewall_rules, firewall_rule_get, planning

    Firewall: Aliases (view-only)

    firewall_aliases, planning

    Status: Interfaces

    interfaces

    Status: Services

    service_list

    Diagnostics: ARP Table

    arp_table

    Diagnostics: Routing tables

    routing_table

    Diagnostics: Show States

    firewall_states

    Diagnostics: Logs: Firewall: Live View

    firewall_log

    Diagnostics: Logs: System

    system_log

    Lobby: Dashboard

    system_information, system_resources, health probe

    Services: Intrusion Detection

    suricata_*

    Services: DHCP: Kea(v4) / Services: Dnsmasq DNS/DHCP: Settings / Status: DHCP leases (ISC)

    dhcp_leases: only the one you use

    System: Firmware (optional)

    system_status. It also allows installing updates, so leave it out unless you need it.

    Most OPNsense privileges are not view-only (Firewall: Aliases is an exception): several of these also allow edits through the API. The server only sends GET requests with this key, except a search POST to two exact endpoints (diagnostics/firewall/query_states, firewall/filter/searchRule) with a body it builds itself (current, rowCount, searchPhrase); OPNsense answers those lists properly only over POST. Still keep the list short: the privileges are what OPNsense itself enforces.

  2. Install:

    pipx install opnsense-guard-mcp
  3. Configure (copy .env.example to .env, or set env vars):

    OPNSENSE_URL=https://firewall.example.internal
    OPNSENSE_API_KEY=...
    OPNSENSE_API_SECRET=...
    OPNSENSE_CA_BUNDLE=/path/to/firewall-ca.pem   # or OPNSENSE_VERIFY_SSL=false
  4. Check the config (does not contact the firewall):

    opnsense-guard-mcp --check
  5. Add to your MCP client, e.g. Claude Code:

    claude mcp add opnsense -- opnsense-guard-mcp --env-file /path/to/.env

HTTP mode (shared server)

HTTP never runs without authentication. The server refuses to start if:

  • there are no tokens, or

  • it binds to a non-loopback address without TLS (override with MCP_ALLOW_PLAINTEXT=true only behind a TLS proxy).

  1. Create a token per client. It is printed once; only its SHA-256 is stored:

    opnsense-guard-mcp token new --name laptop --scope read

    token list shows names and scopes; token revoke --name laptop takes effect on the next request, no restart needed.

  2. Start the server:

    MCP_TRANSPORT=http MCP_HOST=0.0.0.0 MCP_PORT=8848 \
    MCP_TLS_CERT=server.pem MCP_TLS_KEY=server.key \
    opnsense-guard-mcp
  3. Point the client at https://<host>:8848/mcp with header Authorization: Bearer <token>.

Variable

Default

Purpose

MCP_HOST / MCP_PORT

127.0.0.1 / 8848

listen address

OPNSENSE_GUARD_TOKENS_FILE

./tokens.json

token hashes

MCP_TLS_CERT / MCP_TLS_KEY

–

serve HTTPS

MCP_TLS_CLIENT_CA

–

require client certificates (mTLS)

MCP_ALLOWED_HOSTS

localhost/127.0.0.1/MCP_HOST on the port

accepted Host headers (DNS-rebinding guard)

MCP_ALLOWED_ORIGINS

none

browser origins allowed; any other Origin is refused

MCP_RATE_LIMIT_PER_MIN

120

requests per token per minute

MCP_ALLOW_PLAINTEXT

false

allow plain HTTP on a non-loopback address

Repeated failed logins from one IP (10 a minute) are throttled with HTTP 429.

Claude Code and a private CA: Claude Code (Node) ignores the Windows/macOS certificate store for MCP servers. Point NODE_EXTRA_CA_CERTS at your CA file in the env block of ~/.claude/settings.json, then fully quit and reopen Claude, or the connection fails with UNABLE_TO_VERIFY_LEAF_SIGNATURE.

Running in Docker

The image runs as a non-root user and keeps its audit log, change journal and tokens in /data.

docker build -t opnsense-guard-mcp .

# stdio, for a local MCP client
docker run -i --rm --env-file .env -v guard-data:/data opnsense-guard-mcp

# HTTP: create a token, then serve (put the TLS files in the volume or mount them)
docker run --rm -v guard-data:/data opnsense-guard-mcp token new --name laptop --scope read
docker run -d --name opnsense-guard --env-file .env -v guard-data:/data -p 8848:8848 \
  -e MCP_TRANSPORT=http -e MCP_HOST=0.0.0.0 -e MCP_ALLOWED_HOSTS=mcp.example.internal:8848 \
  -e MCP_TLS_CERT=/data/tls/server.pem -e MCP_TLS_KEY=/data/tls/server.key \
  opnsense-guard-mcp

Mount a policy file and set OPNSENSE_GUARD_POLICY to enable writes. Stop the container with docker stop (not kill) so unconfirmed changes are reverted.

Policy and planning

Without a policy.yaml the server is read-only. To enable planning, copy policy.example.yaml to policy.yaml (or point OPNSENSE_GUARD_POLICY at it) and edit it. Unknown keys are an error.

Planning tools (rule_plan, alias_plan) read the current state, apply every policy check, and return a diff plus the reasons for any refusal. They never change the firewall. Example result for a refused rule:

+ [wan] pass in inet any from any to any '[mcp]'
  interface 'wan' is not in the allowed interfaces
  any -> any pass rules are forbidden
  inbound pass rules on WAN are forbidden
  every rule written by this server must have logging on

Built-in guardrails: only listed interfaces/actions/directions; every IP inside allow_networks; no any→any pass, WAN inbound pass, floating rules or rules without logging; edit only rules tagged [mcp] (unless only_modify_own: false); anti-lockout (no block rule that matches this server's own IP, and only new pass rules on the interface it reaches the API through). A new block or reject rule there is allowed when the same plan adds a pass rule with a lower sequence that provably lets every MCP host reach the API (source covers the host IP, destination any/(self)/the API IP, TCP, port covers the API port); both rules need a sequence.

Applying changes

Change tools appear only when both the policy is in write mode and a second, write-capable API user is configured:

OPNSENSE_WRITE_API_KEY=...      # a different OPNsense user than the read one
OPNSENSE_WRITE_API_SECRET=...

Give that user exactly two privileges: Firewall: Rules [new] and Firewall: Alias: Edit, no group. (Plain Firewall: Aliases is view-only: it allows search/get but not addItem/setItem/delItem/reconfigure.) Over HTTP, the change tools need a token with --scope write.

The flow:

  1. rule_plan / alias_plan → diff + plan_id (changes nothing).

  2. change_apply(plan_id) → asks the human to approve the diff (MCP elicitation where the client supports it; otherwise the tool returns the diff and must be called again with user_confirmed=true). Then it re-reads the firewall (refuses if anything drifted since planning), stores the before-state, writes, applies, reads everything back to verify, and checks the API is still reachable. Any failure → everything is reverted.

  3. The change is pending: it is reverted automatically after confirm_timeout_s (default 60 s) unless change_confirm is called.

  4. change_rollback undoes a pending or confirmed change. A revert never overwrites an object someone else edited meanwhile (status conflict).

Unconfirmed changes are also reverted when the server stops and, after a crash, when it starts again. Only one change can be open at a time, and max_changes_per_hour is enforced.

Limits, stated plainly

  • The revert timer runs on the MCP host. If a change cuts that host off from the firewall API, the revert cannot reach it. The anti-lockout policy and the health probe right after apply exist to prevent and catch this, but they are not the same as the firewall-side savepoint older OPNsense versions had.

  • Without elicitation, user_confirmed=true is the model's word that the user agreed. The audit log records which method was used.

Audit log

Every plan (allowed or refused) and server start is written to $OPNSENSE_GUARD_DATA_DIR/audit.jsonl (default ./data). Each line holds the hash of the previous one, so edits, deletions and reordering are detectable:

opnsense-guard-mcp audit verify
opnsense-guard-mcp audit tail -n 20

Credentials are never written to it.

Tools (read-only)

system_status, system_information, system_resources, service_list, posture_check, suricata_status, suricata_settings, suricata_alert_status, firewall_rules, firewall_rule_get, firewall_aliases, firewall_log, firewall_states, system_log, interfaces, arp_table, routing_table, dhcp_leases, raw_get, policy_show, security_audit.

In write mode also: rule_plan, alias_plan, plan_get, audit_tail. With write credentials also: change_apply, change_confirm, change_rollback, change_list, change_get.

firewall_rules returns one line per rule (50 by default) so a full ruleset fits in a chat; pass detail=true for the raw OPNsense rows, or use firewall_rule_get for one rule.

Over HTTP, a read token still sees the change tools in the tool list, but calling one is refused (needs a token with scope 'write').

Development

python -m venv .venv && . .venv/bin/activate
pip install -e ".[dev]"
ruff check . && mypy && pytest

Security

See SECURITY.md. Please report vulnerabilities privately.

Licence

MIT. See LICENSE.

Available Tools

21 tools
arp_tableA
Read-onlyIdempotent

ARP table: IP to MAC mappings currently known to the firewall.

NameRequiredDescriptionDefault

No parameters

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so safety and idempotency are covered. The description adds that the data is 'currently known to the firewall,' implying dynamic state, but does not describe freshness guarantees, return format, or other behavioral details.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no redundant or filler text. Every element identifies the resource and its contents.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a parameterless, read-only tool with annotations covering safety and no output schema, the description is complete enough. It states the resource and what it returns without needing further elaboration.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There are zero parameters, so parameter semantics are not a concern. The baseline score for a parameterless tool is 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description identifies a specific resource, the ARP table, and states its contents as IP-to-MAC mappings known to the firewall. It is clearly distinct from siblings like routing_table and interfaces, though it does not explicitly use a verb such as 'list' or 'retrieve'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no explicit guidance on when to use this tool versus alternatives such as routing_table, interfaces, or dhcp_leases. Usage is only implied by the resource name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

dhcp_leasesA
Read-onlyIdempotent

Current DHCP leases across all backends (Kea, ISC dhcpd, dnsmasq).

Queries all three and reports which backend actually holds leases.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive, so the safety profile is covered. The description adds genuine behavioral detail beyond that: this is a fan-out query across three backends that also reports which backend actually holds the leases — information an agent needs to interpret the result. It stops short of saying how partial backend failures are surfaced.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, front-loaded with what is returned and followed by the aggregation behavior. Nothing is redundant with the annotations or schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists and annotations cover safety, so the description need not explain return values. The one unaddressed concern for a multi-backend query is what happens if a backend is unreachable (error vs. partial results), which the description leaves silent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

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; the baseline for a no-param tool applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Current DHCP leases') and narrows scope by naming the three backends covered (Kea, ISC dhcpd, dnsmasq). No sibling tool touches DHCP, so differentiation is implicit, but an agent knows exactly what this returns.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the resource itself (ask for leases when you need lease data), and the second sentence hints that some backends may be empty. There is no explicit when-to-use/when-not guidance, and no alternatives named — though no DHCP alternative exists among siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

firewall_aliasesB
Read-onlyIdempotent

Firewall aliases and their contents.

Args: search: optional text filter on alias name or description. limit: maximum aliases to return (1-1000).

NameRequiredDescriptionDefault
limitNo
searchNo

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior. The description adds useful parameter semantics, but it does not describe return format, pagination behavior beyond the limit, or whether alias contents are expanded.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is short, front-loaded, and wastes little space. The Args block is structured and readable, though the opening sentence is a fragment rather than an explicit action statement.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list tool with annotations and no output schema, the description covers selection and both parameters adequately. It only lightly describes what 'contents' means and does not explain the returned alias structure, which is a minor gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, but the description compensates by documenting both parameters: search filters on alias name or description, and limit caps results at 1-1000. It does not restate the default of 200, but the schema carries that.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific resource and scope: firewall aliases plus their contents. It lacks an explicit verb such as 'list' and does not distinguish itself from siblings like firewall_rules or firewall_rule_get, but the purpose is clear enough for selection.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives no when-to-use guidance, no exclusions, and no routing to alternatives such as firewall_rules. The implied use case is to inspect aliases, but that is left entirely to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

firewall_logB
Read-onlyIdempotent

Recent firewall log entries (pass/block decisions).

Args: limit: number of log lines to return (1-1000). search: optional filter phrase (IP, port, interface, action).

NameRequiredDescriptionDefault
limitNo
searchNo

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds that results are 'recent' entries with pass/block decisions and that search filters across IP, port, interface, or action, but it does not state ordering (newest first?), truncation behavior, or how the search matches (substring vs token).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the resource and content in one line, followed by a compact args block. No filler, though the args block duplicates the parameter names rather than adding narrative around them.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter read-only log fetch with annotations covering safety and no output schema, the description supplies enough: what it returns, the size bound, and the filter dimensions. The remaining gaps (sort order, default limit of 100, result truncation) are minor, and the default is already in the schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% — the schema only carries types, titles, and defaults with no descriptions — so the description must compensate, and it largely does: it bounds limit to 1-1000 (a constraint absent from the schema) and enumerates what search can match (IP, port, interface, action). It stops short of saying whether search is a substring or multi-token match.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb-less but clear resource: 'Recent firewall log entries (pass/block decisions)' tells the agent exactly what data comes back. It implicitly distinguishes itself from siblings like system_log or firewall_states by naming the pass/block decision content, but never explicitly contrasts with them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no statement of when to use this versus system_log, firewall_states, or firewall_rules, all of which sit nearby in the sibling list. The agent must infer that this is the tool for reading log lines rather than general system logs or live connection state.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

firewall_rule_getA
Read-onlyIdempotent

One filter rule by UUID, with all fields.

Args: uuid: rule UUID as shown by firewall_rules.

NameRequiredDescriptionDefault
uuidYes

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true and destructiveHint=false, so the safety profile is covered. The description adds that the full record is returned ("with all fields"), but says nothing about behavior when the UUID does not exist.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short lines, with the outcome (one rule, all fields) front-loaded before the argument note. Nothing is padded or redundant.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter read tool with annotations covering the safety profile and no output schema, this is nearly complete; "with all fields" sets return expectations. The only gap is unspecified behavior for a missing or invalid UUID.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must carry the parameter meaning, and it does: the single argument is a rule UUID and is sourced from the firewall_rules output. That is exactly the non-obvious information an agent needs to populate it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

"One filter rule by UUID, with all fields" names a specific verb (retrieve) and resource (filter rule), scoped to a single record, which implicitly contrasts with the sibling firewall_rules list tool. The distinction is present but not stated as explicitly as it could be.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The line "uuid: rule UUID as shown by firewall_rules" tells the agent to obtain the identifier from the list sibling, implying the list-then-fetch workflow. It stops short of stating when to use this versus firewall_rules or what to do when the UUID is unknown.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

firewall_rulesA
Read-onlyIdempotent

The firewall filter ruleset, one line per rule.

Use firewall_rule_get for every field of one rule.

Args: search: optional text filter (interface, description, address). limit: maximum rules to return (1-1000). detail: return the full OPNsense rows instead of one-line summaries.

NameRequiredDescriptionDefault
limitNo
detailNo
searchNo

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare this a safe, idempotent read operation, so the bar is lower. The description still adds valuable behavioral detail: results are one-line summaries by default, and detail switches to full OPNsense rows, which tells the agent what it will actually receive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The definition is front-loaded with purpose, followed by the sibling routing guidance and then a compact Args block. Every line earns its place with no redundant or filler text.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description adequately explains the return shape (one-line summaries vs. full rows) and covers all three parameters. It could be slightly richer about ordering or pagination behavior, but it gives the agent enough to call the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the full burden and does so well. It explains search as a text filter over interface, description, and address; limit as a 1-1000 cap on returned rules; and detail as a switch between one-line summaries and full OPNsense rows.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the resource (firewall filter ruleset) and its output shape (one line per rule), and it explicitly distinguishes itself from firewall_rule_get. However, it opens with a noun phrase rather than a specific verb, so it stops short of the strongest possible purpose statement.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly names the alternative tool, firewall_rule_get, and the condition that selects it: when you need every field of one rule. That is strong routing guidance, though it doesn't cover when to prefer this tool over other firewall siblings like firewall_log or firewall_states.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

firewall_statesB
Read-onlyIdempotent

Active connection state table.

Args: limit: number of states to return (1-1000). search: optional filter on address or port.

NameRequiredDescriptionDefault
limitNo
searchNo

TDQS

B3.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds that these are *active* states (i.e., current, not historical), which meaningfully distinguishes it from the log tool, but it says nothing about whether the table is truncated, sampled, or how large the underlying table can be.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Very short with the resource identified up front and parameters immediately after. The inline "Args:" block is slightly awkward inside a description but wastes no words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With only two optional params and no output schema, the definition covers the essentials, but it never indicates what fields a state entry contains or whether results are capped/paginated — information an agent needs to interpret an empty or truncated result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description carries the full burden, and it delivers: limit is given a range (1-1000) that the schema lacks, and search is explained as filtering on address or port. It omits the documented default of 25 and doesn't say what happens when more states exist than the limit.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The phrase "Active connection state table" names the resource (live firewall connection states) but supplies no verb, so the agent must infer that this lists/returns entries. It is reasonably distinguishable from siblings like firewall_log (historical) and firewall_rules (configuration), but that distinction is left implicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this instead of firewall_log, firewall_rules, or arp_table, and no stated prerequisites or exclusions. The agent must guess from the name alone whether this is the right tool for troubleshooting live connections.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

interfacesA
Read-onlyIdempotent

All network interfaces with status, addresses, and link state.

NameRequiredDescriptionDefault

No parameters

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare this as read-only, idempotent, and non-destructive, so the safety profile is covered structurally. The description adds useful output context by listing status, addresses, and link state, but it does not discuss permissions, pagination, or other behavioral details.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is a single, front-loaded sentence with no filler. Every phrase contributes directly to what the tool returns.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter read-only tool with strong annotations and no output schema, the description is nearly complete: it identifies the resource and summarizes the returned fields. Additional detail about the response shape or filtering constraints would be needed for a 5.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

This tool takes zero parameters, so the baseline is 4. The description appropriately avoids inventing parameter semantics and instead focuses on the returned interface data.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the resource (network interfaces) and names the returned fields (status, addresses, link state), so the agent can identify it as a zero-parameter interface listing. It does not explicitly distinguish itself from nearby network siblings such as arp_table or routing_table.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use or when-not-to-use guidance is provided, and no alternatives are named. With many adjacent network and firewall tools in the sibling list, the agent is left to infer when this tool is the right choice.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

policy_showA
Read-onlyIdempotent

What this server is allowed to change: mode, interfaces, networks, limits.

Read this before planning a change so you know the limits.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint and destructiveHint=false, so safety is covered. The description adds genuine context beyond that: this is a prerequisite check whose result constrains what changes are permissible, which an agent cannot infer from the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, zero filler, with the subject scope front-loaded and the usage instruction second. Nothing repeats the title or wastes a clause.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no parameters, an output schema present, and annotations covering the safety profile, the only real job is purpose plus timing, and both are delivered. Minor gap: it does not clarify whether the output is the enforced policy versus the editable policy definition, which matters before planning a change.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

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 and the baseline is 4. The enumerated policy categories describe the returned content rather than arguments.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the resource and its contents concretely (mode, interfaces, networks, limits) and frames it as a read of enforced policy, which separates it from operational siblings like system_status or interfaces. It never states a verb such as 'returns' or 'shows the current policy', so the read nature comes from the name and annotations rather than the prose.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'Read this before planning a change so you know the limits' gives a clear, explicit precondition for calling it. It stops short of naming an alternative or stating when not to call it, but with an all-read sibling set the context is sufficient.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

posture_checkA
Read-onlyIdempotent

Health snapshot: system, services, IDS state.

Flags security-relevant services that are installed but not running.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription

No output parameters

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is fully covered. The description adds real value beyond that by disclosing the coverage domains and the specific flagging rule for installed-but-not-running security services. It stops short of anything else behavioral, such as how deep the IDS check goes or whether missing services cause errors.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with the domain coverage front-loaded and the salient flagging behavior immediately after. It is efficiently sized, though the second sentence is a sentence fragment and the first reads as a noun-phrase label rather than a verb statement.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return structure need not be explained, and with no parameters the call mechanics are trivial. What it covers plus the one notable anomaly it reports is enough for an agent to decide to call it; only the relationship to security_audit and the depth of each domain check remain unstated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so per the baseline there is nothing the description needs to disambiguate, and it correctly adds no parameter chatter. It could have stated that no scoping (host, time range, service filter) is possible, which would have set expectations, but the omission is minor for a zero-argument call.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a concrete resource (a health snapshot spanning system, services, and IDS state) and its distinguishing behavior: flagging security-relevant services installed but not running. That implicitly separates it from the narrower siblings system_status, service_list, and suricata_status, though it never names them 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.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: an agent can infer this is the 'give me an overall picture first' tool because it aggregates three domains, while the siblings cover each individually. There is no explicit when-to-use statement, no exclusion such as 'use security_audit for a full compliance sweep', and no note on cost or whether it is safe to call frequently.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

raw_getB
Read-onlyIdempotent

GET any allowlisted OPNsense API path.

The same read-only rules apply (prefix allowlist, verb denylist, no traversal), so this cannot change firewall state.

Args: path: API path beginning with /api/, e.g. /api/core/firmware/info

NameRequiredDescriptionDefault
pathYes

TDQS

B3.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint/idempotentHint/destructiveHint=false, and the description usefully goes further by naming the enforcement mechanisms (prefix allowlist, verb denylist, no traversal) and the consequence ('cannot change firewall state'). It omits what happens on a denied path and whether the body is passed through verbatim, so it stops short of 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.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the verb and resource, then the safety guarantees, then the single arg with an example. No filler; the Args block duplicates the schema slightly but is scannable and compact.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter escape-hatch tool with annotations covering the safety profile and no output schema, the description is adequate but not complete: an agent still lacks guidance on when this is preferable to a dedicated sibling and on how to find valid paths, which is the crux of calling it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the burden. It does supply the essential contract — the path must begin with /api/ and an example is given — but it does not say how to discover which paths are allowlisted or what a rejection looks like, leaving the single parameter only partially characterized.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (GET) and resource (any allowlisted OPNsense API path), so the agent knows this is a generic read passthrough. However, it never contrasts itself with the twenty specific siblings (system_status, firewall_rules, etc.), so the boundary between this and a dedicated read tool 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.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description covers safety constraints but gives no when-to-use guidance: nothing says 'prefer the dedicated tool when one exists' or 'use this for endpoints not otherwise exposed.' With 20 specific siblings, that omission is the main routing risk. The phrase 'the same read-only rules apply' also references rules defined elsewhere, adding no standalone guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

routing_tableC
Read-onlyIdempotent

The firewall's active routing table.

NameRequiredDescriptionDefault

No parameters

TDQS

C2.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is fully covered by structured data. The description adds only the word 'active', hinting at live state but not explaining whether the table is a snapshot or refreshed on each call.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is a single short fragment with no padding, which is good, but the brevity reflects under-specification rather than tight writing. It front-loads the resource but gives the agent nothing to act on.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

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 carries the full burden of explaining what the agent receives — routing table columns, whether routes include gateways/interfaces, or formatting. None of this is provided, leaving a meaningful gap for a data-retrieval tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline of 4 applies. There is nothing for the description to disambiguate on the input side.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

Identifies the specific resource (the firewall's routing table) and the qualifier 'active' narrows it, so an agent can tell it apart from siblings like arp_table or firewall_rules. However, no verb is stated — it is a noun fragment that leaves the agent to infer this is a read/retrieval operation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance, no mention of alternatives such as arp_table or firewall_states, and no stated preconditions. The agent must infer the invocation context entirely from the name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

security_auditA
Read-onlyIdempotent

Quick security review of the ruleset and IDS.

Flags any->any pass rules, inbound pass on WAN, pass rules without logging, and an IDS that is not running.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, and the description is consistent with a report-only audit ("Flags any->any pass rules..."). Beyond the annotations it adds genuine value by naming the four conditions that constitute a finding, so the agent knows what a positive result means.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the purpose and followed immediately by the enumerated checks. No filler, no restatement of the tool name, and the list form makes the findings easy to scan.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no parameters, an output schema present, and safety fully covered by annotations, the description needs only to explain what is audited and what counts as a problem, which it does. The one gap is the unaddressed relationship to `posture_check` and the other `suricata_*` / `firewall_*` siblings.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

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; there is nothing for the description to disambiguate. The description correctly conveys that the audit runs against the whole ruleset with no scoping input.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("security review of the ruleset and IDS") and enumerates the exact checks performed, so an agent knows precisely what it audits. It does not, however, distinguish itself from the sibling `posture_check`, which plausibly overlaps with this capability.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The word "Quick" implies this is a lightweight, first-pass check rather than a deep audit, which hints at usage context. But there is no explicit when-to-use, when-not-to-use, or pointer to `posture_check` / `firewall_rules` for deeper investigation, so the agent must infer the routing decision.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

service_listA
Read-onlyIdempotent

All services OPNsense knows about and whether each is running.

NameRequiredDescriptionDefault

No parameters

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so safety is covered. The description adds real behavioral context by clarifying the result set is complete ('All services OPNsense knows about') and includes per-service run state, which the annotations do not convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence with no filler, front-loading the scope ('All services') and the key returned attribute ('whether each is running'). Nothing could be removed without losing meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter read-only list with no output schema, the description covers what is enumerated and the main status field. It stops short of sketching the remaining per-service fields an agent would receive, which is the only material gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is nothing to disambiguate; the baseline for a parameterless tool applies. The description correctly implies no filtering or scoping inputs are needed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific resource (OPNsense services) and the exact information returned (whether each is running). It does not explicitly differentiate itself from siblings like system_status or system_information, which a one-clause contrast would have made trivial, 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.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: an agent can infer that this is the tool for enumerating services, but the description never states when to pick it over system_status, system_information, or security_audit. No prerequisites, exclusions, or alternatives are named.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

suricata_alert_statusA
Read-onlyIdempotent

Whether Suricata is producing alerts, from its eve.json file metadata.

OPNsense only serves alert rows over POST (queryAlerts), which a read-only server must not call. This reports liveness instead: the log file's size and last-modified time. Query alerts in your SIEM.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint, idempotentHint, and destructiveHint=false. The description adds that it reads the log file's size and last-modified time to report liveness, and explains why it avoids the POST-based alert query. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, front-loaded with the core purpose ('Whether Suricata is producing alerts'), followed by the rationale and mechanism. No redundant or filler content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no parameters, a present output schema, and rich read-only annotations, the description fully covers purpose, mechanism (file metadata), and limitation (cannot return alert rows). Error handling is the only minor omission, likely covered by the output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters and an empty schema, so there are no parameters to document. Per the baseline rule, a 4 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific liveness check: whether Suricata is producing alerts via eve.json file metadata. It distinguishes itself from alert-row retrieval and directs alert queries to the SIEM, but does not explicitly name sibling suricata_status to differentiate.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explains that OPNsense serves alert rows only over POST (queryAlerts) which a read-only server must not call, and advises querying alerts in the SIEM. Implies this tool is for liveness checks only, but lacks explicit when-to-use vs the suricata_status sibling.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

suricata_settingsB
Read-onlyIdempotent

Suricata configuration: enabled, IPS mode, interfaces, active rulesets.

NameRequiredDescriptionDefault

No parameters

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, so the safety profile is fully covered by structured data. The description adds only the inventory of configuration areas exposed, which functions more as a return-content hint than behavioral context; nothing is said about permissions, sensitivity, or whether it reflects live or persisted config.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One short line with zero filler, and the resource is front-loaded before the field inventory. It is appropriately sized for a no-argument read tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no parameters, no output schema, and full annotation coverage, the description carries a light load and mostly suffices by naming the config areas returned. What is missing is disambiguation from suricata_status and a note that these are read-only settings rather than live state, which is the main ambiguity an agent would face.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the schema imposes no semantic burden and the baseline of 4 applies. The description correctly signals a parameter-free configuration read rather than hinting at filtering options.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description is a noun-phrase inventory ('Suricata configuration: enabled, IPS mode, interfaces, active rulesets') rather than a verb+resource statement, so the agent must infer that it reads configuration. It does list the concrete config areas covered, which helps distinguish content, but it never contrasts itself with the sibling tools suricata_status and suricata_alert_status.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no statement of when to use this tool, and no exclusions. Given three Suricata-related siblings (suricata_status, suricata_alert_status), the absence of any routing guidance leaves the agent guessing whether settings or status is the right call.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

suricata_statusB
Read-onlyIdempotent

Whether the Suricata IDS/IPS service is running, stopped, or disabled.

NameRequiredDescriptionDefault

No parameters

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent and non-destructive, so safety is covered. The description adds useful detail by enumerating the possible states (running, stopped, disabled), which is more than a bare status check would convey, but it says nothing about return format, refresh behavior or permissions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single compact sentence with no filler. It is front-loaded with the resource, though the 'Whether ...' phrasing reads as a sentence fragment rather than a direct statement of action.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the burden of explaining the return value; it partially does so by listing the three possible states, but doesn't say whether these come back as a string, an object, or with extra fields. Adequate but leaves a real gap for a zero-param query tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

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 4 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the specific resource (the Suricata IDS/IPS service) and the information returned (running/stopped/disabled), so an agent knows exactly what it queries. It does not differentiate itself from siblings like suricata_alert_status or suricata_settings, leaving some ambiguity about whether this covers daemon state versus alerting state.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no indication of when to call this versus the siblings (suricata_alert_status, suricata_settings, service_list) or any prerequisites/context. The agent must infer usage from the name alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

system_informationB
Read-onlyIdempotent

Hostname, uptime, load, and general system information.

NameRequiredDescriptionDefault

No parameters

TDQS

B3.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, covering the safety profile. The description adds the returned data categories but does not disclose response format, rate limits, or other behavioral context beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single concise sentence with no wasted words, though it is a fragment rather than a front-loaded action statement. It efficiently conveys the main data fields.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter read tool with no output schema, the description should more fully explain what is returned. It names only a few fields and leaves 'general system information' vague, though annotations cover safety.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the description is not expected to document any. Baseline for zero-parameter tools is 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

Lists the data returned (hostname, uptime, load) but lacks a specific verb and uses vague phrasing ('general system information'). It does not differentiate from siblings like system_status or system_resources, which likely overlap.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides no guidance on when to use this tool versus alternatives such as system_status or system_resources. There are no stated conditions, exclusions, or prerequisites.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

system_logB
Read-onlyIdempotent

Recent entries from the OPNsense system log.

Args: limit: number of lines to return (1-1000).

NameRequiredDescriptionDefault
limitNo

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds little beyond that: 'recent' is undefined (time window? rotation? follow behavior?) and the return shape of log entries is undisclosed, though the idempotent/read-only framing means the omission is not risky.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short lines with the resource stated first and the parameter note second; nothing is padded. The 'Args:' docstring residue is slightly mechanical but costs almost no tokens.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter read-only tool with no output schema, the definition covers what goes in but not what comes out — no indication of entry format or whether 'recent' is bounded. Adequate to invoke, thin for interpreting the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the burden, and it does supply the one thing the schema lacks: the valid range 1-1000 for limit and its meaning as a line count. It omits any note on the default of 100, which the schema does provide.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb-less but clear resource: 'Recent entries from the OPNsense system log', which tells an agent exactly what data comes back. It does not, however, distinguish itself from the sibling firewall_log, which is the most likely confusion point.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to call this versus firewall_log or suricata_status, nor any note on cost, freshness, or prerequisites. An agent must infer usage entirely from the tool name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

system_resourcesB
Read-onlyIdempotent

Memory, swap, and disk utilisation of the firewall itself.

NameRequiredDescriptionDefault

No parameters

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint and destructiveHint=false, so the safety profile is fully covered by structured data. The description adds only the scope note ('the firewall itself') and the metric categories; it says nothing about units, freshness, or cost of the call.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single short sentence with no waste, and the resource list is front-loaded. As a bare noun phrase it lacks an explicit verb, which slightly weakens structure.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no parameters and annotations covering safety, the remaining burden is small, but the description never states return format or units (percentages vs bytes) and gives no output schema fallback. Against several similarly named system_* siblings, that leaves the agent guessing at the payload shape.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

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 and the baseline of 4 applies. No misleading parameter implications are present.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names the specific resources returned (memory, swap, disk utilisation) and scopes them to the firewall host itself, so an agent knows what data comes back. It does not, however, distinguish itself from close siblings like system_status or system_information, which plausibly return overlapping host metrics.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance, no mention of alternatives, and no exclusion criteria. The phrase 'of the firewall itself' hints at a scope boundary but never says when to prefer this over system_status or system_information.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

system_statusA
Read-onlyIdempotent

OPNsense firmware version and pending updates (needs the System: Firmware privilege).

NameRequiredDescriptionDefault

No parameters

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive, so the safety profile is covered. The description adds genuinely useful context beyond the annotations: the required privilege scope, which tells the agent an auth failure mode exists. It adds nothing about response shape, but that is minor for a zero-argument status read.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One sentence, front-loaded with what is returned and followed by the access precondition in parentheses. No filler, nothing an agent must scan past.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and no parameters, the description carries most of the burden and does state what the call yields (firmware version plus pending updates) and what privilege it needs. Enough to call it correctly; only the exact return shape is left implicit.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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; the baseline for a no-parameter tool applies. The description adds no argument-level meaning because none is possible here.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific resource (OPNsense firmware version and pending updates), making the read operation unambiguous. It does not, however, distinguish itself from the sibling system_information, which an agent could plausibly pick for a similar question.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied by the privilege note (System: Firmware) — that hints at when the call will succeed but gives no explicit guidance on choosing this over system_information, system_resources, or posture_check.

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.

  1. 21 tool updatesv0.1.0
    • First observedarp_table
    • First observeddhcp_leases
    • First observedfirewall_aliases
    • First observedfirewall_log
    • First observedfirewall_rule_get
    • First observedfirewall_rules
    • First observedfirewall_states
    • First observedinterfaces
    • First observedpolicy_show
    • First observedposture_check
    • First observedraw_get
    • First observedrouting_table
    • First observedsecurity_audit
    • First observedservice_list
    • First observedsuricata_alert_status
    • First observedsuricata_settings
    • First observedsuricata_status
    • First observedsystem_information
    • First observedsystem_log
    • First observedsystem_resources
    • First observedsystem_status

TDQS

B3.4/5.0

Scored across 21 tools

Disambiguation4/5

Most tools target clearly distinct resources (suricata_status/settings/alert_status, firewall_rules/rule_get/log/states are well separated). Some softer overlap exists between posture_check and security_audit (both health/security snapshots) and among system_status/system_information/system_resources, but descriptions give enough signals to choose correctly.

Naming Consistency4/5

All names are snake_case with predictable domain prefixes (system_, service_, suricata_, firewall_, dhcp_) and readable verb_noun forms for actions (posture_check, policy_show, security_audit). A few bare nouns (interfaces, arp_table, routing_table) deviate slightly but remain clear.

Tool Count3/5

21 tools is on the heavy side for a read-only guard server; the suricata and system clusters each add several closely related tools. Every tool does earn a purpose, but the surface sits at the borderline of 'feels heavy'.

Completeness4/5

For a deliberately read-only server it covers system, services, IDS, firewall rules/aliases/logs/states, logs, interfaces, ARP, routing and DHCP well, with raw_get as an escape hatch for gaps. The notable gap is that policy_show references allowed changes but no mutation tools exist, which may confuse agents expecting lifecycle operations.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables natural language interaction and management of pfSense firewalls through Claude and other GenAI applications using the Model Context Protocol. It provides advanced tools for firewall rule configuration, interface management, and intelligent log analysis via a REST API integration.
    1
    MIT
  • F
    license
    Not graded
    quality
    A
    maintenance
    Enables natural-language control of pfSense firewalls from Claude Desktop, Claude Code, or any MCP client, covering firewall rules, NAT, VPN, DNS, DHCP, routing, certificates, users, and diagnostics through 332 wire-format-verified REST API tools. Destructive changes are gated behind explicit confirmation, rate limits, config-revision backups, and audit logging so an AI can safely diagnose and reconfigure a production firewall.
    -