Skip to main content
Glama

grounded-kql-mcp

An MCP server that answers network questions with deterministic, pre-shaped KQL against Azure Log Analytics custom tables — correlating firewall, VNet flow, on-premises Cisco IOS and Cisco ISE logs to answer the question an engineer actually asks: why can't A reach B?

The agent never writes KQL. It picks a tool and fills typed parameters; the server renders the query. That is the whole design, and the reason this is safe to point at a production workspace.

Runs with no Azure dependency at all (stdlib only), and against a real Log Analytics workspace by flipping one environment variable.

Why it is built this way

The tool catalog is the authorization surface. There is no free-form KQL entry point. The agent picks a tool and fills typed parameters; src/kqlmcp/query.py renders the query. That is what keeps the blast radius of the server's identity bounded by tools.py rather than by whatever the model decides to write — and it is the argument that matters in a security review.

Two backends, one tool contract. local runs the same tool semantics over generated CSVs in stdlib SQLite; azure runs the rendered KQL against a real workspace. Both return the KQL, so a local demo shows exactly the query that would run in production.

Credential resolution is pluggable. Today: application identity (managed identity in Azure, az login locally) with Log Analytics Reader on one workspace. The same tool contract accepts a per-user delegated credential for a tenant-wide, RBAC-scoped deployment — see docs/design.md.

Related MCP server: berserk-mcp

Quick start (no Azure needed)

python -m venv .venv && . .venv/bin/activate     # Windows: .venv\Scripts\activate
pip install -e .                                  # mcp is the only dependency
python data/generate_logs.py                      # writes data/out/*.csv
python smoke_test.py                              # all six scenarios should pass

Run the server:

python -m kqlmcp.server --transport stdio                              # Claude Desktop / VS Code
python -m kqlmcp.server --transport http --host 0.0.0.0 --port 8080   # any MCP client over HTTP

HTTP mode serves streamable HTTP at /mcp. SSE is deprecated in the MCP spec and deliberately not supported.

Claude Desktop

claude_desktop_config.json:

{
  "mcpServers": {
    "kqlmcp": {
      "command": "C:\\path\\to\\grounded-kql-mcp\\.venv\\Scripts\\python.exe",
      "args": ["-m", "kqlmcp.server", "--transport", "stdio"],
      "env": {
        "PYTHONPATH": "C:\\path\\to\\grounded-kql-mcp\\src",
        "KQLMCP_BACKEND": "local"
      }
    }
  }
}

VS Code

.vscode/mcp.json:

{
  "servers": {
    "kqlmcp": {
      "type": "stdio",
      "command": "${workspaceFolder}/.venv/Scripts/python.exe",
      "args": ["-m", "kqlmcp.server", "--transport", "stdio"],
      "env": { "PYTHONPATH": "${workspaceFolder}/src", "KQLMCP_BACKEND": "local" }
    }
  }
}

Switching to a real workspace

pwsh ./infra/provision.ps1 -ResourceGroup rg-kqlmcp -Location westeurope
pip install -e ".[azure]"
python ./infra/ingest.py       # uses the values provision.ps1 printed

Then set KQLMCP_BACKEND=azure and KQLMCP_LA_WORKSPACE_ID=<customer id>. Nothing else changes — same tools, same output shape.

The ingested data is perishable by design, and does not refresh itself. data/generate_logs.py writes a rolling window ending at generation time, Log Analytics rows don't move once ingested, and every tool — trace_connection included — defaults to a 1440-minute (24h) window (D-017). Generate and ingest right before you intend to query — data ingested more than a day earlier is invisible to default time windows, not broken, just outside the window a default query looks at. (The local backend doesn't have this property: its container regenerates the dataset at every start, so it can't go stale. The Azure path has no equivalent — there's nothing to regenerate at, since the data already lives in the workspace.) When a hop's query does come back empty, trace_connection now runs one bounded 30-day follow-up per miss to tell you whether that means "never happened" or "outside your window" (D-017).

infra/ingest.py also refuses to run a second time against a workspace whose tables already hold rows in that window — custom-table rows can't practically be deleted, so a repeat run would silently double the dataset. Pass --append to add anyway, or tear down and re-provision for a clean workspace.

Adding your own KQL queries

This project's tool catalog is deliberately closed: there is no free-form KQL entry point, and every tool goes through the same typed pipeline (QuerySpecFilter/Aggto_kql/to_sql in src/kqlmcp/query.py). Adding a new query means adding a new tool function to src/kqlmcp/tools.py, not writing raw KQL anywhere the agent can reach.

The fastest way to do that correctly is to fill in docs/new-query-template.yaml with:

  • the table you want to query (must already be in src/kqlmcp/schemas.py, or described as a new table if not)

  • the parameters the tool should accept, and which real column/operator each one maps to

  • a reference KQL query you've already run by hand in Log Analytics, as proof the question is answerable against that data

Then hand the filled-in file to Claude Code (or another AI coding agent) working in this repo, pointing it at CLAUDE.md's conventions and an existing tool such as search_firewall_sessions as a pattern to follow. Review the generated function before trusting it — in particular, confirm every IP-typed parameter routes through _valid_ip() the same way src_ip/dst_ip do elsewhere — then run

python data/generate_logs.py && python smoke_test.py

as a baseline check against the local/SQLite backend before pointing the new tool at a real workspace.

This only works for questions expressible as a single QuerySpec: a filtered/projected row search, or a group-by aggregation, over one table. If your reference query needs something the IR can't express — joins across tables, window functions, multi-stage let statements — that's a sign it needs new capability in query.py itself, not just a new tool.

The tools

Tool

Answers

describe_environment

what topology and tables exist

trace_connection

why can't A reach B — correlates ISE → IOS → firewall → NIC

search_flows

did traffic leave / arrive at a NIC

search_firewall_sessions

what did the hub firewall decide, under which rule

search_onprem_device_logs

was it stopped on-premises before reaching Azure

lookup_user_sessions

who was using this on-premises IP

top_denied_traffic

ranked denies by rule, source, destination, application

traffic_volume

top talkers by bytes

Layout

src/kqlmcp/
  topology.py     reference hub-and-spoke + on-prem estate (single source of truth)
  schemas.py      custom table definitions -> generator, SQLite DDL, Azure table JSON
  query.py        query IR + KQL and SQLite renderers
  tools.py        the grounded tool catalog
  server.py       MCP server (stdio + streamable HTTP)
  backends/       local_sqlite.py | azure_la.py (pluggable credential)
data/generate_logs.py   seeded synthetic logs with six planted scenarios
infra/                  provision.ps1, ingest.py, emit_table_schemas.py
docs/                   feasibility note, demo script, new-query-template.yaml

License

Apache-2.0. The synthetic data, topology and vendor log shapes are illustrative and do not describe any particular organisation's network.

Available Tools

8 tools
describe_environmentA

Describe the network topology and the available log tables. Call this first when you are unsure which addresses, VMs or tables exist.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.9/5.0
Behavior3/5

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

With no annotations, the description carries the full disclosure burden. 'Describe' strongly implies a read-only, discovery operation, but the description never states that it is side-effect free, whether it is expensive/cached, or how fresh the topology data is. It adds the useful 'call first' ordering hint, which is more than the schema provides, but leaves the core behavioral profile implicit.

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, both front-loaded: the first states what it returns, the second states when to call it. No filler or repetition.

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 values need no explanation, and with no parameters the input side is trivially complete. The only remaining gap is the unstated read-only/cost profile, which a zero-argument discovery tool could reasonably be expected to declare.

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 clarify and the baseline is 4. The mention of 'addresses, VMs or tables' refers to discoverable content, not inputs, so it does not mislead about 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 gives a specific verb+resource: it describes the network topology and the available log tables, which is clearly distinct in kind from the sibling search_/trace_/lookup_ tools. It stops short of naming any sibling explicitly, so the differentiation is inferable 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.

Usage Guidelines4/5

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

It gives an explicit trigger: 'Call this first when you are unsure which addresses, VMs or tables exist.' That is a concrete when-to-use condition, but there is no stated when-not-to-use or explicit pointer to which sibling to call once the environment is known.

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

lookup_user_sessionsB

Cisco ISE authentication events. Give an endpoint_ip to find who was using an on-premises address, or a user_name to find their endpoints. result is Passed or Failed.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
resultNo
user_nameNo
endpoint_ipNo
since_minutesNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.4/5.0
Behavior3/5

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 the domain (authentication events) and the result domain (Passed/Failed), which is useful. It says nothing about permissions, retention windows, pagination, or why limit/since_minutes exist, leaving notable gaps.

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?

Three tight sentences with no filler; the domain statement is front-loaded and the two query modes follow immediately. Slightly terse rather than wasteful.

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?

An output schema exists, so return formatting need not be explained. Still, with zero required params and 0% schema coverage, ambiguity about default behavior and the unmentioned limit/since_minutes params leaves the definition short of complete.

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 must compensate for all five params. It adds real meaning for endpoint_ip, user_name, and the result value set (Passed/Failed), but omits limit and since_minutes entirely, so two parameters remain undocumented anywhere.

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 the resource domain (Cisco ISE authentication events) and the two lookup modes precisely: endpoint_ip -> user, user_name -> endpoints. An agent can grasp what it returns without opening the schema. It doesn't distinguish itself from siblings like search_onprem_device_logs, keeping it below a 5.

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?

Gives implied usage guidance by explaining which parameter selects which query path (endpoint_ip vs user_name), which is genuinely helpful. However there is no statement of when to prefer this over the other search/trace siblings, and no exclusions or prerequisites.

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

search_firewall_sessionsC

Search PaloAlto sessions on the hub firewalls. action is allow, deny, drop or reset-both. Returns the security rule that made the decision.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
actionNo
dst_ipNo
src_ipNo
dst_portNo
dst_zoneNo
src_zoneNo
rule_nameNo
applicationNo
since_minutesNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.9/5.0
Behavior2/5

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 mentions that results include the deciding security rule, which is useful. However, it omits permissions, rate limits, default behavior of since_minutes/limit, and whether the search spans all sessions or applies defaults. For a 10-parameter search tool with zero annotation coverage this is thin.

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, front-loaded with the search target and followed by action values and return content. No wasted words, though it is perhaps too sparse to be fully useful.

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 10 parameters at 0% schema coverage and no annotations, the description leaves too much unstated. It mentions the output (deciding rule) and one action value set, but does not explain filters, defaults, or scope. An output schema exists, so return-value explanation isn't required, but the input side is inadequately covered.

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

Parameters2/5

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. The action parameter is partially documented by giving allowed values (allow, deny, drop, reset-both), but the other nine parameters (src_ip, dst_ip, ports, zones, rule_name, application, limit, since_minutes) receive no syntax, semantics, or default explanations. The description does not carry the required load.

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 (search) plus resource (PaloAlto sessions on hub firewalls), which is clear and scoped. It does not explicitly distinguish itself from sibling search_flows or lookup_user_sessions, but the firewall-session framing is specific enough for an agent 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 Guidelines3/5

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

Implicit context is given ('hub firewalls', security-rule focus), but there is no explicit when-to-use vs when-not guidance and no mention of the sibling tools an agent might confuse it with, such as search_flows. Adequate but with clear gaps.

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

search_flowsC

Search Azure VNet flow logs. direction is Inbound or Outbound; action is Allow or Deny. Answers whether traffic left or arrived at a NIC.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
actionNo
dst_ipNo
src_ipNo
vm_nameNo
dst_portNo
directionNo
vnet_nameNo
since_minutesNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.7/5.0
Behavior2/5

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

No annotations are provided, so the description carries the full behavioral burden, and it falls short: it never states the tool is a read-only query, says nothing about the 1440-minute default lookback window, result limits, or pagination, and gives no sense of cost or rate. The only behavioral content is the enumerated semantics of direction and action values.

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?

Three short sentences with no filler, and the resource being searched is front-loaded before the field semantics. It is efficient, though the tight size leaves little room for the parameter coverage the rest of the definition needs.

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?

An output schema exists, so return values need not be explained, but with 9 optional filters at 0% schema coverage and zero annotations, the description is not complete enough to invoke the tool confidently. The most likely invocation mistakes — how to scope by VM/VNet or IP, and how the default time window behaves — are unaddressed.

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

Parameters2/5

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

Schema description coverage is 0% across 9 parameters, and the description only documents two of them (direction as Inbound/Outbound, action as Allow/Deny). Filters such as src_ip, dst_ip, dst_port, vm_name, vnet_name, limit and since_minutes are left entirely for the agent to infer from parameter names.

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 states a specific verb and resource ('Search Azure VNet flow logs') and even frames the analytic question it answers ('whether traffic left or arrived at a NIC'). The named log source ('VNet flow logs') implicitly separates it from siblings like search_firewall_sessions and search_onprem_device_logs, 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.

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 choose this tool over search_firewall_sessions, trace_connection, or the other search_* siblings, and no exclusions or prerequisites are stated. The 'answers whether traffic left or arrived at a NIC' line hints at the use case but never routes the agent to an alternative.

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

search_onprem_device_logsC

Search Cisco IOS syslog from on-premises routers and switches: ACL permit and deny hits, interface state changes. action is permitted or denied.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
actionNo
dst_ipNo
src_ipNo
acl_nameNo
device_nameNo
min_severityNo
since_minutesNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.9/5.0
Behavior3/5

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

With no annotations, the description carries the full burden; it adds real value by naming the log source and clarifying that 'action is permitted or denied', which the schema does not. However it says nothing about pagination, result volume, time-window behavior, or any safety/access profile.

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 tight sentences with the resource and event scope front-loaded and no filler. Structure is efficient, though given the parameter gaps the terseness costs more than it saves.

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?

For an 8-parameter tool with zero annotation and zero schema-description coverage, the description leaves most filter semantics and their defaults unexplained. The output schema covers return values, but the agent still lacks enough to invoke the filters correctly beyond 'action'.

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

Parameters2/5

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

Schema description coverage is 0% across 8 parameters, so the description must compensate, yet it only disambiguates the 'action' parameter ('permitted or denied'). Filters like min_severity, since_minutes, acl_name, src_ip/dst_ip, and defaults (limit=50, since_minutes=1440) are left entirely undocumented.

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 ('Search Cisco IOS syslog from on-premises routers and switches') and enumerates the event types covered (ACL permit/deny hits, interface state changes). This clearly distinguishes it from firewall-session tools, though it never names a sibling to contrast against.

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: nothing tells the agent to prefer this over search_firewall_sessions, search_flows, or top_denied_traffic, and no prerequisites are stated. Only the described data source implicitly hints at scope.

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

top_denied_trafficC

Rank firewall denies. group_by is one of RuleName, SrcIp, DstIp, Application, DstPort.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
group_byNoRuleName
since_minutesNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.9/5.0
Behavior2/5

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

No annotations are provided, so the description carries the full behavioral burden. It does not say that this is a read-only aggregation, how the time window (since_minutes, defaulting to 1440) scopes the counts, what limit truncates, or whether results are ordered descending by count. Only the group_by vocabulary is disclosed.

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, front-loaded with the operation before the parameter detail, with no filler. It is arguably under-specified rather than over-long, but nothing present is wasted.

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?

An output schema exists, so return values need not be described, and the group_by domain is covered. Still, for a three-parameter tool with zero schema descriptions and zero annotations, the description leaves the time-window semantics, the limit behavior, and the read-only nature unstated.

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 must compensate, and it does partially by enumerating the five legal group_by values, which the schema does not encode as an enum. However, limit and since_minutes are left entirely unexplained, and the meaning of the 1440-minute default (a 24-hour window) is never stated.

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?

"Rank firewall denies" gives a specific verb (rank) plus resource (firewall denies), so an agent immediately knows this returns a top-N aggregation rather than raw sessions. It does not explicitly name a sibling or state how it differs from traffic_volume, but the resource noun is distinctive enough to separate it from the search_* tools.

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 reach for this tool versus traffic_volume (volume rather than denies) or search_firewall_sessions (raw sessions rather than ranked aggregates). The agent must infer the selection condition 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.

trace_connectionA

Trace one conversation across every log source on its path and report where it stopped. Use this for 'why can't A reach B' questions. Correlates Cisco ISE identity, on-premises Cisco IOS ACLs, hub PaloAlto firewall sessions and VNet flow logs at both NICs.

ParametersJSON Schema
NameRequiredDescriptionDefault
dst_ipYes
src_ipYes
dst_portNo
since_minutesNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior3/5

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 this aggregates across four distinct source families (ISE identity, IOS ACLs, PaloAlto sessions, VNet flow logs at both NICs), which tells the agent this is a broad, potentially expensive fan-out query. However, it omits permissions, latency/cost expectations, and what a 'stopped' result looks like.

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 tight sentences, front-loaded with the core verb and scope, then the trigger question, then the sources touched. Every sentence earns its place with no filler.

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?

An output schema exists, so return formatting need not be described, and the cross-source scope is well covered. The gap is parameter-level: neither the meaning of dst_port nor the time window implied by since_minutes is explained, which matters for a correlation query whose results depend heavily on the lookback period.

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

Parameters2/5

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

Schema description coverage is 0% across four parameters, and the description compensates for none of them. src_ip/dst_ip are inferable from the narrative, but dst_port is never mentioned and since_minutes (default 1440) is entirely absent, so the agent has no guidance on the time window that governs the trace.

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

Purpose5/5

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

States a specific verb ('trace') and resource ('one conversation') with an explicit scope: every log source on the path, reporting where it stopped. The description also implicitly separates it from the single-source siblings (search_flows, search_firewall_sessions) by naming itself as the cross-source correlator.

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?

Gives an unambiguous trigger: 'why can't A reach B' questions. That is a clear when-to-use signal. It stops short of naming a specific alternative tool or stating when NOT to use it (e.g., for bulk traffic ranking you should use traffic_volume), so it is strong but not exhaustive.

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

traffic_volumeB

Top talkers by bytes from the flow logs. group_by is one of VmName, VnetName, SrcIp, DstIp, DstPort, Direction.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
group_byNoVmName
since_minutesNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.2/5.0
Behavior2/5

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

No annotations are provided, so the description carries the full burden and largely drops it. It does not state that this is a read-only query, does not mention authentication or data-source constraints (which flow logs), and gives no behavioral context beyond the enumeration of group_by values.

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, front-loaded with the core purpose and followed by the only non-obvious constraint. No filler, though it is terse to the point of under-specifying the remaining parameters.

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?

An output schema exists, so return values need not be described. But with zero schema description coverage, the description only compensates for one of three parameters and omits the read-only nature and data-window semantics that limit/since_minutes imply.

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% and the schema declares no enums, so the description's enumeration of valid group_by values (VmName, VnetName, SrcIp, DstIp, DstPort, Direction) is genuinely valuable. However, the other two parameters (limit, since_minutes) are left entirely undocumented in both places.

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 and metric: 'Top talkers by bytes from the flow logs.' This distinguishes it from siblings like search_flows and top_denied_traffic, though the sibling differentiation is only implicit in the word 'bytes' rather than explicitly stated.

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 description ('top talkers by bytes'), but there is no explicit when-to-use guidance, no mention of when to prefer top_denied_traffic or search_flows, and no prerequisites or exclusion conditions.

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. 8 tool updatesv0.1.0
    • First observeddescribe_environment
    • First observedlookup_user_sessions
    • First observedsearch_firewall_sessions
    • First observedsearch_flows
    • First observedsearch_onprem_device_logs
    • First observedtop_denied_traffic
    • First observedtrace_connection
    • First observedtraffic_volume

TDQS

B3.3/5.0

Scored across 8 tools

Disambiguation4/5

Each tool has a distinct purpose: environment discovery, connection tracing, and specialized searches on different log sources. The two flow log tools (search_flows and traffic_volume) differ in scope (detailed search vs. aggregate top talkers), but an agent might occasionally confuse them when seeking traffic summaries. Overall boundaries are clear.

Naming Consistency4/5

Most names follow a verb_noun pattern (describe_environment, trace_connection, search_flows, etc.), but 'traffic_volume' lacks a verb and 'top_denied_traffic' uses a different structure. The inconsistency is minor and names remain readable.

Tool Count5/5

8 tools are well-scoped for a network troubleshooting server covering multiple log sources. Each tool serves a distinct investigative need without redundancy, fitting the typical 3-15 range.

Completeness3/5

The set covers discovery, tracing, and searches across logs, but lacks operations for modifying or configuring network elements (e.g., create/update rules, manage devices). For a diagnostic-focused server, completeness is partial; it's read-only and missing lifecycle operations.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides AI assistants with direct access to multi-vendor network devices for tasks like configuration management, health checks, and topology discovery through 35 specialized tools. It enables natural language control over platforms including Cisco, Juniper, and Nokia using SSH, NETCONF, and SNMP protocols.
    11
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Enables LLMs to answer Berserk observability questions by calling verified KQL tools instead of hand-authoring queries, with role-based tool filtering and automated query discovery.
    35
    2
    MIT