grounded-kql-mcp
Integrates with Cisco IOS and Cisco ISE logs to correlate on-premises network events and support connectivity troubleshooting across on-prem devices, firewall, and Azure VNet flow data.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@grounded-kql-mcpwhy can't 10.0.10.15 reach 10.0.20.8 on port 443?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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 passRun 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 HTTPHTTP 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 printedThen 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
(QuerySpec → Filter/Agg → to_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.pyas 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 |
| what topology and tables exist |
| why can't A reach B — correlates ISE → IOS → firewall → NIC |
| did traffic leave / arrive at a NIC |
| what did the hub firewall decide, under which rule |
| was it stopped on-premises before reaching Azure |
| who was using this on-premises IP |
| ranked denies by rule, source, destination, application |
| 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.yamlLicense
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 toolsdescribe_environmentA
Describe the network topology and the available log tables. Call this first when you are unsure which addresses, VMs or tables exist.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| result | No | ||
| user_name | No | ||
| endpoint_ip | No | ||
| since_minutes | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It 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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| action | No | ||
| dst_ip | No | ||
| src_ip | No | ||
| dst_port | No | ||
| dst_zone | No | ||
| src_zone | No | ||
| rule_name | No | ||
| application | No | ||
| since_minutes | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It 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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| action | No | ||
| dst_ip | No | ||
| src_ip | No | ||
| vm_name | No | ||
| dst_port | No | ||
| direction | No | ||
| vnet_name | No | ||
| since_minutes | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full 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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| action | No | ||
| dst_ip | No | ||
| src_ip | No | ||
| acl_name | No | ||
| device_name | No | ||
| min_severity | No | ||
| since_minutes | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden; it 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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| group_by | No | RuleName | |
| since_minutes | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full 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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| dst_ip | Yes | ||
| src_ip | Yes | ||
| dst_port | No | ||
| since_minutes | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It usefully discloses that 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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| group_by | No | VmName | |
| since_minutes | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden 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.
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.
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.
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.
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.
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.
8 tool updates
v0.1.0- First observed
describe_environment - First observed
lookup_user_sessions - First observed
search_firewall_sessions - First observed
search_flows - First observed
search_onprem_device_logs - First observed
top_denied_traffic - First observed
trace_connection - First observed
traffic_volume
TDQS
Scored across 8 tools
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.
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.
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.
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
Related MCP Connectors
Find best-fit tools for any problem, vetted for prompt-injection risk before your agent trusts them
Zero-trust gateway for AI agents: score tool calls, verify agent cards, enforce policy, audit.
LLM Orchestration Observability Agent
LLM Observability & Orchestration Agent
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceProvides 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.11MIT
- AlicenseAqualityBmaintenanceEnables 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.352MIT
- AlicenseAqualityBmaintenanceExposes network-monitoring tools (query metrics, analyze windows, compare, logs, status, runbooks, speed tests) as an MCP server for agentic workflows. Designed with evaluation suites, cost-aware model routing, and semantic tool retrieval.1MIT
- AlicenseNot gradedqualityCmaintenanceEnables LLM agents to triage network incidents by fetching device telemetry, inspecting syslogs, and executing traffic reroutes through MCP tools.MIT