kong-ai-gateway-mcp
Provides read-only diagnostic tools for investigating a Kong Gateway through its Admin API. It exposes fourteen bounded, schema-validated MCP tools (e.g. find_route_by_path, get_route, get_service, list_plugins_for_route, list_global_plugins, get_consumer, list_upstreams, check_upstream_health, diff_config) and a deterministic diagnostic engine that applies eleven pure rules over Kong-collected evidence to produce findings such as NO_AUTH_PLUGIN, diagnose routes and explain authentication failures, with scoped plugin resolution, upstream health checks, and context-bounded, credential-stripped responses. The agent sequences these tools to answer questions like "Why is authentication failing on /payments?" without ever inventing gateway facts.
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., "@kong-ai-gateway-mcpWhy is authentication failing on /payments?"
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.
Kong AI Gateway Diagnostics
An MCP server that lets an LLM agent investigate a Kong Gateway through fourteen read-only, bounded, schema-validated tools, with a deterministic diagnostic engine producing the facts, a bounded agent loop producing the explanation, and an evaluation harness measuring whether it works.
User: Why is authentication failing on /payments?
Agent: find_route_by_path({"path":"/payments"}) -> route:payments-prod
Agent: diagnose_route({"route":"route:payments-prod"}) -> NO_AUTH_PLUGIN (HIGH), CONFIRMED
Agent: Authentication is not failing on /payments because no authentication plugin
is attached or enabled for that route at all. Kong is passing every request
through without requiring credentials. [evidence, next steps, limitations]
3 steps · 2 tool calls · 12,977 tokens · $0.0046 · 5.0 sKong is the source of truth. The model selects tools, sequences the investigation and writes the explanation; it never produces a fact.
Status: a working reference implementation, verified against a local Kong 3.9.3 and the live Gemini API. It is not deployed anywhere and has not been used in production.
Problem
Debugging an API gateway is a sequence of narrow questions against a large, structured
configuration: which route serves this path, which service does it point to, which
plugins actually apply once you account for scope precedence, is the upstream healthy,
does this consumer hold the credential the route requires. Each question is a specific
Admin API call. The failure modes are not exotic -- a disabled plugin that still shows in
the UI, a route attached to the wrong service, a 503 that means "wrong address" rather
than "backend down" -- but they are easy to miss when eyeballing JSON, and the obvious
first hypothesis is often wrong.
An LLM is good at sequencing an investigation from a vague description. It is bad at being trusted with infrastructure state. This project is about getting the first property without paying for the second.
Related MCP server: semley
Why MCP?
The Model Context Protocol gives the model a fixed vocabulary of operations, each with a
schema, a description of when to use it, and a bounded result -- instead of an HTTP
client and a URL. That makes the entire attack and blast surface enumerable (see
src/mcp/registry.ts), lets the same tools serve any MCP client
and this repository's own agent from one definition, and puts a protocol-enforced
validation boundary between the model and the gateway. There is deliberately no
execute_kong_api_call tool and never will be
(decisions.md).
Architecture
flowchart LR
Client["AI client<br/>(Claude Desktop, IDE, or npm run agent)"]
subgraph S["kong-ai-gateway-mcp"]
direction TB
MCP["MCP tools (14, read-only)"]
Ctx["Context management<br/>references · summaries · limits"]
Diag["Diagnostic engine<br/>evidence collector · pure rules"]
Kong["Kong client<br/>typed · GET only · bounded"]
Safety["Safety: permissions · audit"]
Tel["Telemetry: logs · metrics · cost"]
MCP --> Ctx --> Diag --> Kong
MCP -.-> Safety
MCP -.-> Tel
end
subgraph A["Agent + evaluation (needs an LLM key)"]
Loop["Bounded agent loop"] --> Prov["LLM provider interface"] --> Gem["Gemini provider"]
Eval["Evaluation harness<br/>28 cases · deterministic scorer"] --> Loop
end
Client -- MCP / stdio --> MCP
Loop -- in-process --> MCP
Kong -- Admin API --> KG[(Kong 3.9<br/>+ Postgres)]
Gem --> API[(Gemini API)]The tool layer runs without any LLM. Full component map, data flow and responsibilities in docs/architecture.md.
Features
MCP tooling -- 14 tools on the official TypeScript SDK v2 (
@modelcontextprotocol/server):find_route_by_path,get_route,get_service,list_services,list_routes_for_service,list_plugins_for_route,list_global_plugins,get_consumer,list_consumers,list_upstreams,check_upstream_health,diff_config,diagnose_route,explain_auth_failure. Every description states what the tool does, when to use it, what it returns, and its limits.Kong integration -- a typed client with explicit methods only, Zod-validated responses, a stable error taxonomy, response and page-count ceilings, and credential values stripped at the boundary. Kong is treated as authoritative.
Deterministic diagnostics -- eleven pure rules over an evidence bundle that can only be filled from Kong. Absence is asserted only when every relevant scope was read. Runs in ~64 ms with no model. Detects all ten seeded defects and reports the healthy control as clean.
Agentic investigation -- a loop this project owns (not the SDK's), with a step limit, identical-call detection, a cumulative context budget, and a halt path that produces an explicit "diagnosis incomplete" rather than a guess.
Context management -- references instead of embedded entities, allowlisted plugin config projection, announced truncation, cursor pagination written for a model, progressive and conditional collection. Measured: a single-route diagnosis is 11% of the raw configuration dump.
Safety controls -- no write method exists in
src/; write tools are gated at registration; the server refuses to start withENABLE_WRITE_TOOLS=truebecause none are implemented; secrets are stopped at each boundary they cross, with a test for each.Evaluation -- 28 cases, three difficulties, varied phrasings, false-positive controls, a deterministic scorer with no LLM judge, quota-aware and resumable runs, JSON and Markdown reports.
Observability -- structured JSON logs (stderr only; stdout is the protocol), per-call telemetry with three correlation ids, a separate audit log, nearest-rank percentiles, provider-reported tokens, and cost that says "unavailable" rather than guessing.
Provider abstraction -- one-method
LlmProviderinterface;@google/genaiimported in exactly one file; two Gemini-specific protocol requirements discovered during development were absorbed without touching the agent, tools or evaluation.
Demo
Actual output of npm run agent -- --trace "Why is authentication failing on /payments?"
against the seeded gateway and gemini-3.5-flash-lite (run captured on 2026-09-12):
Investigation trace:
Step 1 (llm 1602ms, finish=tool_calls)
-> find_route_by_path({"path":"/payments"}) ok 30ms 209B
Step 2 (llm 1317ms, finish=tool_calls)
-> diagnose_route({"route":"route:payments-prod"}) ok 64ms 3162B
Step 3 (llm 1971ms, finish=stop)
DIAGNOSIS
**Diagnosis:**
Authentication is not failing on `/payments` because **no authentication plugin is
attached or enabled** for that route at all. Kong is currently passing all requests to
`/payments` through without requiring any credentials.
**Evidence:**
- The route `payments-prod` (serving `/payments`) has only a `cors` plugin attached at
the route scope.
- There are no service-level plugins on `payments-api`.
- The global plugins active on the gateway are `request-size-limiting` and
`correlation-id`.
- None of these are authentication plugins (`key-auth`, `jwt`, `basic-auth`, etc.).
**What to do next:**
1. Confirm with your team whether the `/payments` endpoint is intentionally public.
2. If authentication *should* be required, configure and enable an appropriate
authentication plugin (such as `key-auth` or `jwt`) on the route or its backing
service.
**Limitations:**
This diagnosis reflects gateway configuration only. If clients are receiving 401 or 403
responses when calling `/payments`, those responses are coming from the upstream backend
service (`http://payments-upstream:8080/v1`), not from Kong itself.
RUN METRICS
steps 3 / 10
tool calls 2 (0 error(s))
repeated calls 0
tools used find_route_by_path, diagnose_route
tool latency avg/p95 46.5ms / 64ms
llm calls 3 (avg 1630ms)
tokens 12677 in / 300 out / 12977 total
estimated cost $0.004553
context used 3371 / 50000 chars
wall clock 4993msThe question's premise is wrong -- nothing is rejecting requests -- and the agent
corrects it from evidence rather than accepting it. The diagnose_route result it
reasoned over is the same structured object an MCP client would receive:
{
"confidence": "CONFIRMED",
"summary": "No enabled authentication plugin applies to route route:payments-prod. ...",
"findingCount": 2,
"findings": [
{
"code": "NO_AUTH_PLUGIN",
"category": "AUTHENTICATION",
"severity": "HIGH",
"entityType": "route",
"entityRef": "route:payments-prod",
"observedState": "No enabled authentication plugin applies to route route:payments-prod. No authentication plugin is attached at route, service or global scope.",
"expectedState": "A route serving protected resources should have an enabled authentication plugin (key-auth, jwt, basic-auth, oauth2, ...) at route, service or global scope.",
"evidence": [
"Route-scoped plugins: cors.",
"Service-scoped plugins: none.",
"Global plugins: request-size-limiting, correlation-id."
],
"recommendedNextStep": "Kong forwards every request to /payments without authenticating it, ..."
}
],
"observed": { "route": { "ref": "route:payments-prod", ... }, "effectivePlugins": [ ... ] },
"gaps": [],
"suggestedNextSteps": [ ... ]
}Installation
Requirements: Node.js >= 20, npm, Docker with Compose v2.
git clone <this repository>
cd kong-ai-gateway-mcp
npm install
cp .env.example .env # defaults work for the local Kong; add GEMINI_API_KEY for the agentVerify the toolchain without Docker or an API key:
npm run check # lint + typecheck + 140 unit testsRunning Kong
npm run kong:up # docker compose up -d (Postgres, migrations, Kong 3.9)
npm run seed # 12 services, 12 routes, 4 upstreams, 7 consumers, 20 plugins,
# 10 intentional defects; waits for health-check verdicts
npm run health # PASS/FAIL for Admin API, proxy, seed statePorts on the host: 8000 proxy, 8443 proxy TLS, 127.0.0.1:8001 Admin API,
127.0.0.1:8002 Kong Manager. The Admin API is an unauthenticated control plane and is
bound to loopback only. Postgres is not published.
Other lifecycle commands: npm run kong:down, npm run kong:reset (destroys volumes),
npm run kong:logs, npm run seed:reset (deletes every seeded entity first; the seed is
idempotent either way).
What is seeded and why each defect exists: docs/scenarios.md.
Running the MCP server
npm run dev # tsx, stdio transport
# or
npm run build && npm start # node dist/server.jsRegister with an MCP client by pointing it at the built server. For Claude Desktop, in
claude_desktop_config.json:
{
"mcpServers": {
"kong-diagnostics": {
"command": "node",
"args": ["/absolute/path/to/kong-ai-gateway-mcp/dist/server.js"],
"env": { "KONG_ADMIN_URL": "http://localhost:8001" }
}
}
}The server needs no LLM key. It probes Kong at startup and logs a warning (not an error)
if the gateway is not yet up; tools return structured UNREACHABLE errors until it is.
Point clients at node dist/server.js (or npx tsx src/server.ts) directly, not at
npm run ...: npm prints a script banner to stdout, which is the protocol channel.
npm run dev is for driving the server by hand; it deliberately does not use watch mode
(see MCP-STDOUT-001 in the failure modes).
Running the agent
Requires GEMINI_API_KEY in .env.
npm run agent -- "Why is authentication failing on /payments?"
npm run agent -- --trace "Clients hitting /orders get 429 immediately. What's going on?"
npm run agent -- --json "Is /shipping protected?" # full run record as JSONExit code is 0 for a complete diagnosis and 1 when the run was cut off by a limit or a provider error -- in which case the answer says so explicitly.
Running evaluation
npm run eval # all 28 cases -> evals/results/run-NNN.{json,md}
npm run eval -- --case auth-001 # one case (repeatable flag)
npm run eval -- --difficulty hard
npm run eval -- --scenario UPSTREAM-UNHEALTHY-001
npm run eval -- --dry-run # validate the dataset, run nothing
npm run eval -- --resume run-003 # finish a run the provider's daily quota cut shortConfiguration
All variables are validated at startup by src/config/env.ts.
Blank values fall through to defaults.
Variable | Default | Purpose |
|
| Admin API base URL |
|
| used only by |
|
| per-request timeout to Kong |
|
| provider for the agent and evaluation |
| (unset) | required for |
|
| any model the key can access; pricing must be declared in |
|
| pino level; audit events always emit |
| (unset) | additional JSON log destination; stderr always |
|
| must stay false: no write tool is implemented and the server refuses to start otherwise |
|
| cap on any list in a tool result |
|
| cap on a single serialized tool result |
|
| LLM calls per run |
|
| identical (tool, arguments) calls per run |
|
| cumulative tool-result characters per run |
.env is gitignored. Nothing in the project prints a key; redactConfig reduces it to
[set] / [unset].
Evaluation
Methodology. One case per user question; 28 cases across 11 scenarios and three difficulties. Scoring is deterministic -- no LLM judge. A case passes when the deterministic engine produced every expected finding code during the run, the answer contains every expected fact, contains no named wrong conclusion, and the run finished within its limits. Cases the provider's daily quota prevents from running are marked SKIPPED and excluded from every rate rather than counted as failures.
Results of the current run (run-003, dataset 1.2.0, gemini-3.5-flash-lite,
Kong 3.9.3, 2026-09-12):
Passed | 28 / 28 (easy 6/6, medium 14/14, hard 8/8) |
Finding recall / fact match / completion | 100% / 100% / 100% |
Steps per case | mean 3.5 (min 3, max 9) |
Tool calls per case | mean 2.57; repeated calls: 0 |
Duration per case | median 5.4 s; mean 20.5 s (nine cases include 30-60 s of free-tier rate-limit backoff); retry-free median 4.5 s |
Tokens | 425,710 total, 15,204 per case |
Estimated cost | $0.1496 total, $0.0053 per case |
Two earlier runs are kept: run-001 scored 22/28 and run-002 26/28, and in both every miss was either a provider rate-limit loss or a correct answer the substring scorer marked wrong. No case in any run failed because the agent gave a wrong diagnosis. How the scorer was fixed, and what these numbers do and do not show, is in docs/evaluation.md. Per-case results and every verbatim answer: evals/results/run-003.md.
Observability
Structured JSON to stderr (and LOG_FILE), never stdout. Every tool call records
requestId, traceId, taskId, tool, duration, status, error category, result size and
whether it was a repeat; every LLM call records provider, model, duration,
provider-reported tokens, finish reason and estimated cost. A separate audit log records
each invocation with sanitized arguments at warn. Metrics (call counts, success rate,
mean / p50 / p95 latency, repeat rate, tokens, cost) are computed only from recorded
calls. Details: docs/observability.md.
Failure Modes
Twelve failures were observed while building this and are documented with symptom, root cause, impact, mitigation and regression test -- including a halt path that would have returned an empty answer, a cost calculation off by 10x, a per-day quota mistaken for a rate limit, a Gemini 3 protocol requirement that broke every case after its first tool call, and a scorer that marked correct answers wrong. Twenty-three more were deliberately provoked and verified. docs/failure-modes.md.
Security
docs/security.md -- threat model, the five boundaries at which secrets are stopped (each with its test), execution limits, the read-only guarantee and how it is structural, what prompt injection is and is not mitigated, and what is not handled.
Architecture Decisions
docs/decisions.md -- fourteen decisions in context / decision / alternatives / trade-offs / consequences form, each tied to something in this repository.
Context Management
docs/context-management.md -- the mechanisms and the measurements behind them.
Testing
npm test # 140 unit tests; no Docker, no network
npm run test:integration # 27 tests against live seeded Kong, incl. MCP over real stdio
npm run test:e2e # 3 tests: question -> agent -> tool -> Kong -> diagnosis (needs a key)
npm run test:allIntegration and e2e suites skip themselves with a message when their dependency is
absent, so npm test passes on a fresh clone.
Limitations
Read-only. The agent can find a problem but not fix it. The write flow (confirmation token, preview diff, audit, rollback) is designed and documented, not built.
Rules must be written. The engine detects the defect classes it has rules for (eleven). A novel class is invisible until someone adds a rule; the model cannot discover it from a summary that omitted the relevant field.
find_route_by_pathmatches whole paths. It does not simulate Kong's prefix or regex routing.One provider. Gemini only. Anthropic and OpenAI are one file each away, but that file does not exist yet.
Free-tier constraints shaped the harness. Per-minute rate limits add 30-60 s to some cases; some models have a 20-request daily quota. The harness handles both honestly but a paid tier would give cleaner latency numbers.
Scoring is substring-based. It is a regression net for named facts and named wrong conclusions, not a judge of prose quality.
Prompt injection through gateway data is not detected. It is defanged (no write path, typed arguments, facts from rules) but not detected or filtered.
Kong 3.9.x only has been tested.
Sample size. 28 cases, one model, one full run per dataset version. Enough to demonstrate and to catch regressions; not enough to state a stable percentage.
Roadmap
Possible, not promised:
Confirmation-gated write tools (enable a plugin, fix a route path) with preview and audit, behind
ENABLE_WRITE_TOOLS.Anthropic and OpenAI providers.
Rules for more defect classes: certificate/SNI mismatches, plugin ordering conflicts, consumer-scoped plugin overrides.
A second full evaluation run per model to establish variance, and evaluation across models.
OpenTelemetry export for tool and LLM spans.
Human feedback on answers, feeding the case set.
Other gateways behind the same tool contract.
License
MIT.
Available Tools
14 toolscheck_upstream_healthCheck upstream target healthARead-onlyIdempotent
Reports Kong's own health verdict for each target of an upstream.
USE WHEN: a route returns 503, or you have ruled out authentication and routing and need to
know whether the backend pool is actually serving. Reach this tool from a service whose
host names a Kong upstream.
CRITICAL DISTINCTION between the verdicts this returns: HEALTHY probed and responding UNHEALTHY address is correct, backend is failing -> availability problem DNS_ERROR address cannot be resolved -> configuration problem HEALTHCHECKS_OFF Kong is not probing at all -> health is UNKNOWN, not healthy
Do not read HEALTHCHECKS_OFF as "fine". It means no information.
RETURNS: targets each with target, health, weight and a meaning line; plus
healthchecksEnabled, verdict and canServeTraffic.
LIMITATIONS: reports the gateway's view only, and that view is only as fresh as Kong's last probe or proxied request for this upstream. A freshly created or rebuilt target is reported HEALTHY before the first probe runs, and an idle upstream can show a stale HEALTHY for a target that is actually down. If a HEALTHY verdict contradicts other evidence (e.g. 503s), say so rather than treating it as proof the backend is up.
| Name | Required | Description | Default |
|---|---|---|---|
| upstream | Yes | Upstream name, id, or `upstream:<name>` reference. When a service's `host` field names a Kong upstream, pass that host value here. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, idempotent, non-destructive behavior, but the description adds substantial operational context: the meaning of each verdict, the critical warning that HEALTHCHECKS_OFF means unknown rather than healthy, staleness limitations, and the possibility of contradictory evidence. This far exceeds annotation coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with purpose, then structured into USE WHEN, verdict distinctions, RETURNS, and LIMITATIONS. Despite its length, every section earns its place and uses formatting to aid scanning.
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?
Even without an output schema, the description explains the return fields (targets, healthchecksEnabled, verdict, canServeTraffic) and the nuance of each verdict. Nothing an agent needs to interpret results or decide when to call this tool is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds practical mapping guidance: 'When a service's host field names a Kong upstream, pass that host value here.' That helps the agent translate a service configuration into the correct upstream parameter value.
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+resource: reports Kong's own health verdict for each target of an upstream. It clearly distinguishes this read-only health probe from siblings like diagnose_route and list_upstreams by focusing on the gateway's target-level verdict.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit trigger conditions (route returns 503, auth/routing ruled out) and the exact context required (service whose host names a Kong upstream). This is a textbook when-to-use statement that leaves no ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
diagnose_routeRun a full diagnostic on a routeARead-onlyIdempotent
Runs a complete, rule-based diagnostic on one route and returns structured findings.
This is the highest-value tool in this server and usually the right SECOND call, after find_route_by_path. It performs the whole investigation a careful engineer would -- resolve the route, resolve its service, collect plugins at all three scopes, check upstream target health, check the named consumer's credentials and ACL groups, compare against the declared configuration baseline -- and applies the diagnostic rules to the result.
USE WHEN: the user reports a problem with a route or path. Prefer it over assembling the same picture yourself from get_route + list_plugins_for_route + check_upstream_health: it is one call instead of four, and it will not mistake "not collected" for "not present".
Pass consumer whenever the user named a specific client. Without it, consumer-specific
causes are invisible and the diagnosis will look clean when it is not.
RETURNS: confidence CONFIRMED | PARTIAL | INSUFFICIENT_EVIDENCE summary one-sentence verdict findings[] each with code, severity, observedState, expectedState, evidence[], recommendedNextStep observed what Kong actually reports (route, service, effective plugins, consumer, upstream) gaps[] evidence that could not be collected, and what that prevents concluding suggestedNextSteps[]
HOW TO READ IT: every finding is derived from Kong by deterministic rules -- these are facts,
not guesses. Report them as such, and cite the evidence entries. Respect confidence:
PARTIAL means something could not be read and a further problem may be hidden there. Zero
findings with CONFIRMED means the route is genuinely fine; say so rather than inventing a
cause.
LIMITATIONS: inspects gateway configuration and Kong's own health verdicts only. It does not send traffic, read gateway logs, or observe live request behaviour. A backend that returns HTTP 500 on every request looks perfectly healthy here.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | URL path the user named, e.g. "/payments". Use this when the user described a path. | |
| route | No | Route name or `route:<name>` reference, when you already know it. | |
| consumer | No | Consumer username to check credentials and ACL membership for. Supply this whenever the user named a specific client, since consumer-specific causes (missing credential, wrong ACL group) cannot be detected without it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, yet the description adds substantial non-obvious behavior: it will not mistake 'not collected' for 'not present', confidence may be PARTIAL meaning a cause could be hidden, and the LIMITATIONS paragraph discloses it does not send traffic, read logs, or observe live behavior (so an HTTP 500 backend looks healthy). That is exactly the kind of context annotations cannot carry.
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?
Long but strongly front-loaded and organized under USE WHEN / RETURNS / HOW TO READ IT / LIMITATIONS headers, so it is scannable rather than padded. The RETURNS inventory is justified by the absence of an output schema, though some lines (e.g. the repeated consumer warning) are mildly redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description fully compensates by enumerating the return fields (confidence, summary, findings[], observed, gaps[], suggestedNextSteps) and teaching how to interpret confidence and zero-finding results. Nothing needed to call or read the tool correctly is missing.
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 100%, so path/route/consumer are already well documented, including the consequence of omitting consumer. The description restates the consumer guidance but adds no syntax or format detail beyond the schema, so baseline 3 is appropriate.
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 ('Runs a complete, rule-based diagnostic on one route') and explicitly positions itself against siblings, calling itself the right SECOND call after find_route_by_path. An agent can distinguish it from get_route or check_upstream_health without opening any schema.
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?
Explicit USE WHEN clause ('the user reports a problem with a route or path') plus a named alternative set (get_route + list_plugins_for_route + check_upstream_health) and the condition that selects this tool over them (one call instead of four). Also gives a conditional invocation rule for the consumer parameter.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
diff_configDiff live Kong against the declared baselineARead-onlyIdempotent
Compares what Kong is actually running against the declared configuration baseline in kong/seed/baseline.json, and reports every difference.
USE WHEN: something is configured but behaving unexpectedly, and you need to know whether the live configuration matches what was intended. Especially effective for problems with no local symptom -- a route attached to the wrong service, a dropped HTTP method, a changed upstream address -- where the entity looks perfectly valid in isolation.
Pass entity to scope the comparison to one route or service. A whole-gateway diff is much
larger and usually buries the relevant line.
RETURNS: drift[], each entry naming the entity, the attribute, the baseline value, the Kong
value and the operational impact; plus inSync and driftCount.
IMPORTANT: a difference does NOT establish which side is wrong. The baseline may be out of date just as easily as the gateway may have drifted. Report the difference and what it causes; do not assert that Kong is misconfigured on the strength of this tool alone.
LIMITATIONS: the baseline covers services (host/port/protocol), routes (service, paths, methods, required plugins) and upstreams (targets). Plugin configuration VALUES are not compared -- only whether a required plugin is present and enabled.
| Name | Required | Description | Default |
|---|---|---|---|
| scope | No | Which entity class to compare (default "all"). Narrow this when a full diff would be larger than you need. | |
| entity | No | Restrict the comparison to one named entity, e.g. "search-prod" or "payments-api". Strongly preferred when investigating a specific problem -- a gateway-wide diff is much larger and mostly irrelevant. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/openWorld/non-destructive, so safety is covered — yet the description adds real behavioral context beyond them: a difference does not establish which side is wrong, and the LIMITATIONS block states exactly which fields are (services/routes/upstreams) and are not (plugin config values) compared. This is materially useful for interpreting results.
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?
Front-loaded one-line purpose, then labeled blocks (USE WHEN / RETURNS / IMPORTANT / LIMITATIONS). Length is justified by the number of distinct concerns (routing, interpretation caveat, coverage limits) and no sentence is 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?
No output schema exists, so the description carries the return contract itself (drift[] with entity, attribute, baseline value, Kong value, impact; plus inSync and driftCount). Combined with the interpretation caveat and coverage limitations, an agent has everything needed to call and reason about the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and both params are documented in-schema, so the baseline is 3. The description adds genuine decision semantics beyond that: it explains why to pass `entity` (whole-gateway diff buries the relevant line) and recommends scoping as the preferred mode, which the schema description only hints at.
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 (compares/diffs) and resource (live Kong running config vs. declared baseline in kong/seed/baseline.json), and the sibling set is all read-only inspection tools — none of which diff against a baseline. An agent can distinguish this from get_route/diagnose_route without opening a schema.
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?
Explicit USE WHEN clause ('configured but behaving unexpectedly'), plus the diagnostic pattern it excels at (no local symptom, entity valid in isolation). It also names the preferred scoping strategy versus the whole-gateway alternative, giving both when-to-use and how-to-narrow guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
explain_auth_failureExplain an authentication or authorization failureARead-onlyIdempotent
Focused analysis of why requests to a route are being rejected, narrowed to the authentication and authorization chain.
USE WHEN: the reported symptom is specifically a 401 or 403, or the user says credentials are being rejected. For a broader or vaguer problem, use diagnose_route.
Walks the chain in the order Kong evaluates it and reports where it breaks:
does a route serve this path?
is an authentication plugin attached, and is it ENABLED?
does the named consumer exist?
does that consumer hold a credential of the required type? -> 401 if not
does an acl plugin apply, and is the consumer in an allowed group? -> 403 if not
RETURNS: chain with a per-step verdict, plus the authentication and authorization findings
and a likelyCause.
LIMITATIONS: reasons from configuration, not from observed traffic. It cannot tell you whether a client is sending a malformed header or an expired token -- only what the gateway is configured to require.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | URL path, e.g. "/payments". | |
| route | No | Route name or `route:<name>` reference. | |
| consumer | No | Username of the client that is failing to authenticate, if known. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent annotations, the description discloses the evaluation order Kong walks, the exact failure-to-status mapping (401 vs 403 per step), and a clear LIMITATIONS section stating it reasons from configuration rather than observed traffic.
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?
Front-loaded purpose, labeled USE WHEN, RETURN, and LIMITATIONS sections, and a numbered chain where every line conveys a distinct decision rule. Dense but zero waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, yet the RETURNS paragraph names the key fields (chain, findings, likelyCause), and the limitations cover what the tool cannot do. All parameters are optional and no prerequisite is omitted.
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 100%, so the three parameters are already documented in the schema itself; the description implies their roles through the chain but adds no syntax or format detail, warranting the baseline 3.
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 ('explain') and resource ('authentication or authorization failure'), and immediately narrows scope to the auth chain, explicitly distinguishing itself from the broader diagnose_route sibling.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The USE WHEN block names the exact selecting symptoms (401 or 403, rejected credentials) and names the alternative (diagnose_route) for vaguer problems, leaving nothing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_route_by_pathFind the route serving a URL pathARead-onlyIdempotent
Resolves a URL path to the Kong route (or routes) that serve it.
USE WHEN: the user describes a problem in terms of a path -- "auth is failing on /payments", "/orders returns 429". This is almost always the correct FIRST tool for such a question, because everything else needs a route identifier.
RETURNS: matches, each a route summary with a ref to pass to get_route,
list_plugins_for_route or diagnose_route. When nothing matches, returns matches: [] plus
suggestions listing configured paths that closely resemble the one requested -- a near-miss
there usually means a typo in the route definition.
LIMITATIONS: matches whole path values only, not Kong prefix-matching semantics, so a request to /payments/v2 handled by a /payments route will not match here. More than one match means the path is genuinely ambiguous in Kong and is worth investigating in itself.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | The URL path a client requests, exactly as the user described it. Example: "/payments". A leading slash is added if you omit it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnly/idempotent/non-destructive, and the description goes well beyond them: it discloses the whole-path-not-prefix matching limitation, the near-miss `suggestions` behavior on empty matches, and the meaning of multiple matches. That is genuinely useful behavior the agent could not 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded one-line purpose followed by labeled USE WHEN, RETURNS and LIMITATIONS blocks. Every sentence carries routing or behavioral information; nothing is padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by describing the return shape (`matches` with `ref`, empty-array plus `suggestions` case) and the downstream tools the `ref` feeds into. An agent has everything needed to call it and chain it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single `path` parameter is already 100% documented in the schema, including the leading-slash normalization and an example. The description reinforces but adds no new syntax or format meaning beyond the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (resolves) and resource (a URL path to the Kong route(s) serving it), and the title/description pair makes clear it is a path-to-route lookup rather than a route fetch. An agent can distinguish it from get_route, list_routes_for_service and diagnose_route without opening a schema.
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?
Explicit 'USE WHEN' section with concrete example phrasing ('auth is failing on /payments', '/orders returns 429') and an explicit routing rule: this is almost always the correct FIRST tool because everything else needs a route identifier. That is when-to-use plus the reasoning that picks it over siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_consumerGet a consumer with credential and group stateARead-onlyIdempotent
Retrieves one Kong consumer together with what it can actually authenticate and authorize with: how many credentials of each type it holds, and which ACL groups it belongs to.
USE WHEN: a specific client is failing while others succeed, or you need to distinguish a 401 from a 403. The two have different causes and this tool separates them:
no credential of the type the route requires -> 401, authentication fails
credential present but wrong ACL group -> 403, authorization fails
RETURNS: consumer (ref, username, customId), credentialCounts per credential type, and
aclGroups.
SECURITY: credential COUNTS only. Key values, passwords and secrets are never returned by this tool and are not available through any tool in this server.
LIMITATIONS: does not say which routes the consumer may reach -- that depends on the plugins on each route. Pair with list_plugins_for_route, or use diagnose_route with a consumer name to have both sides checked together.
| Name | Required | Description | Default |
|---|---|---|---|
| consumer | Yes | Consumer username, id, or `consumer:<username>` reference. Example: "partner-integration" or "consumer:partner-integration". |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive), and the description adds substantive context beyond them: the SECURITY note that only counts are returned and secrets are unavailable anywhere in the server, plus a LIMITATIONS note that route reachability depends on per-route plugins. That is exactly the kind of constraint annotations cannot express.
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?
Labeled sections (USE WHEN, RETURNS, SECURITY, LIMITATIONS) front-load purpose and decision logic. Despite the length, each section carries distinct information — return shape, a security guarantee, and a scoping caveat — so no sentence is padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description compensates by enumerating the returned fields (`consumer`, `credentialCounts`, `aclGroups`). Combined with the auth-failure framing and the pointer to diagnose_route, an agent has everything needed to call and interpret this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single parameter already documents the accepted forms with an example. The description adds nothing about the `consumer` argument, so the baseline 3 for schema-driven params is correct.
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?
Specific verb+resource ('Retrieves one Kong consumer') with a scope qualifier that separates it from the sibling list_consumers: it returns credential-type counts and ACL group membership, not just identity. An agent can distinguish it from list_consumers, get_route, and get_service without opening schemas.
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?
An explicit USE WHEN section names the concrete trigger (one client failing while others succeed) and frames the 401-vs-403 decision this tool resolves. It also names alternatives (list_plugins_for_route, diagnose_route) and the condition under which to prefer them.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_routeGet one Kong routeARead-onlyIdempotent
Retrieves a single Kong route and the service it is attached to.
USE WHEN: you already know the route name or have a route: reference from another tool,
and need its paths, methods, hosts, protocols, or which service handles it.
DO NOT USE with a URL path such as "/payments" -- route names and route paths are different things, and this tool takes the name. Use find_route_by_path to go from a path to a route.
RETURNS: route with ref, paths, methods, hosts, protocols, stripPath, and
serviceRef naming the owning service.
LIMITATIONS: does not return plugins. A route can look entirely correct here while being unauthenticated -- call list_plugins_for_route to see what actually applies to it.
| Name | Required | Description | Default |
|---|---|---|---|
| route | Yes | Route name, id, or a `route:<name>` reference. Example: "payments-prod" or "route:payments-prod". This is NOT a URL path -- for a path like /payments use find_route_by_path. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safe-read profile (readOnlyHint, idempotentHint, destructiveHint=false), but the description adds genuinely new behavioral context: the tool does not return plugins and a route can appear correct while being unauthenticated, with a pointer to list_plugins_for_route. It stops short of describing response format or error behavior, so it is strong but not exhaustive.
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?
Uses labeled sections (USE WHEN, DO NOT USE, RETURNS, LIMITATIONS) with the core purpose front-loaded in the first sentence. Every sentence carries actionable content 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?
For a single-parameter read tool with no output schema, the description covers identity, inputs, expected return fields, and a non-obvious limitation plus remediation. Nothing an agent needs in order to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema already states the 'not a URL path' constraint, so the baseline is 3. The description reinforces this semantically by clarifying that route names and route paths are distinct concepts and that this tool takes the name, which meaningfully helps the agent pass a valid value.
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 ('Retrieves a single Kong route and the service it is attached to') and explicitly distinguishes itself from find_route_by_path by clarifying that names and paths are different. An agent can select this tool without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The USE WHEN section names the trigger condition (known route name or `route:` reference) and enumerates the fields needed, while DO NOT USE explicitly excludes URL paths and routes the agent to find_route_by_path. This is textbook when/when-not/alternative guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_serviceGet one Kong serviceARead-onlyIdempotent
Retrieves the full configuration of a single Kong service.
USE WHEN: you have identified a service and need its backend address, protocol, path prefix, retry policy or timeouts. Typically the step after get_route tells you which service a route belongs to.
DO NOT USE to find out which plugins apply -- plugins live on a separate endpoint; use list_plugins_for_route, which already accounts for service-level inheritance.
RETURNS: one service with ref, host, port, path, protocol, retries and the three
timeout values.
LIMITATIONS: does not list the routes attached to the service, and does not tell you whether
host names a Kong upstream or a plain DNS hostname. If you need target health, pass the
host to check_upstream_health.
| Name | Required | Description | Default |
|---|---|---|---|
| service | Yes | Service name, id, or a `service:<name>` reference returned by another tool. Example: "payments-api" or "service:payments-api". |
TDQS
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 non-obvious behavioral context: what it does not reveal (attached routes, whether host is an upstream or plain DNS) and a concrete next step (check_upstream_health). It stops short of discussing errors or auth requirements, hence a 4.
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?
Labeled sections (USE WHEN / DO NOT USE / RETURNS / LIMITATIONS) make the content scannable and front-load the core purpose in one sentence. Every sentence carries routing or constraint information; none is 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?
With no output schema, the description enumerates the returned fields and discloses two important limitations plus a follow-up tool. For a single-resource read tool this covers everything an agent needs to call and interpret it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single `service` parameter already documents accepted forms (name, id, service:<name>). The description adds nothing about the identifier format, so the baseline 3 applies – the schema carries this dimension.
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 (retrieves) and resource (single Kong service's full configuration), and explicitly scopes it against siblings by ruling out plugin lookup and route listing. An agent can distinguish it from get_route, list_services, and list_plugins_for_route without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides an explicit USE WHEN trigger (you have identified a service and need backend address/protocol/path/retry/timeouts) plus a named alternative and condition for DO NOT USE (plugins -> list_plugins_for_route). This is the when/when-not/alternatives pattern at full strength.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_consumersList Kong consumersARead-onlyIdempotent
Lists the consumers (API clients) registered in Kong.
USE WHEN: you need to find the right consumer name before calling get_consumer, or to confirm whether a client the user named exists at all. A client that is not registered as a consumer cannot authenticate, which is a different problem from a missing credential.
RETURNS: items with ref, username and customId, plus a page object.
LIMITATIONS: no credentials and no group membership -- call get_consumer for one consumer.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum items to return (1-100, default 25). Prefer a small value and narrow the query instead of paging through everything. | |
| cursor | No | Opaque cursor from a previous result's `nextCursor`. Omit for the first page. Only use a cursor this tool returned -- cursors cannot be constructed. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already carry readOnly/ idempotent/ non-destructive/ openWorld, so the safety profile is covered. The description adds genuine value beyond that: it discloses the return shape, and the LIMITATIONS line states that credentials and group membership are not included, pointing to get_consumer instead. It stops short of pagination behavior or how to obtain nextCursor, keeping it below a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four labeled sections (statement, USE WHEN, RETURNS, LIMITATIONS) that are front-loaded and tightly worded. Every sentence carries distinct information with no repetition of the schema or annotations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, but the description compensates by naming the returned fields (items with ref, username, customId, plus page) and its exclusions. For a two-parameter read-only list tool this is fully sufficient to invoke correctly.
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 100%, so both limit and cursor are already fully documented in the schema (including the cursor-opacity warning). The description adds nothing about parameters, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (lists Kong consumers, with '(API clients)' clarifying the domain term), and implicitly distinguishes itself from get_consumer by framing itself as the discovery step before it.
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?
Explicit USE WHEN clause covering both finding a consumer name and confirming existence, plus a clear handoff to get_consumer for single-consumer detail. It also distinguishes a missing consumer from a missing credential, which is a real routing decision.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_global_pluginsList globally applied pluginsARead-onlyIdempotent
Lists plugins applied to every request, i.e. those with no service, route or consumer scope.
USE WHEN: you need to rule out a gateway-wide plugin before concluding that a route lacks something. A global key-auth would protect every route without appearing on any of them.
RETURNS: plugins with ref, name, enabled and relevant config, plus pluginCount.
LIMITATIONS: global scope only. To see everything affecting one route including inheritance, use list_plugins_for_route, which covers this case already.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false and openWorldHint=true, so safety is covered. The description adds non-obvious behavioral context the annotations cannot: the exact result shape (`plugins` with ref/name/enabled/config plus `pluginCount`) and the scope boundary of what is returned.
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?
Front-loaded one-line purpose followed by labeled USE WHEN, RETURNS and LIMITATIONS sections. Every sentence carries information — no restatement of the title and 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?
With no output schema, the RETURNS block supplies the missing return-value information, and LIMITATIONS covers the scope trap. For a zero-parameter read tool with full annotation coverage, nothing an agent needs in order to call it correctly is absent.
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 by the rubric the baseline is 4. There is nothing for the description to clarify, and it correctly avoids inventing filter parameters that do not exist.
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 ('Lists plugins applied to every request') and pins down the scope precisely: plugins with no service, route or consumer scope. It explicitly distinguishes itself from the sibling list_plugins_for_route, so an agent can choose without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The USE WHEN block gives a concrete diagnostic scenario (ruling out a gateway-wide plugin before concluding a route lacks something) with a worked example of global key-auth. The LIMITATIONS block names the alternative tool (list_plugins_for_route) and the condition that selects it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_plugins_for_routeList plugins affecting a routeARead-onlyIdempotent
Lists every plugin that affects a route, resolved across all three Kong scopes.
USE WHEN: investigating authentication, rate limiting, CORS, ACL or any other plugin-driven behaviour. This is the tool that answers "is this route protected, and by what".
IMPORTANT -- three things this resolves that a raw plugin list does not:
Scope precedence. Kong applies the most specific instance of a plugin: route beats service beats global.
effectivePluginsreflects that;shadowedlists instances that exist but never run.Disabled plugins. A plugin with enabled=false is still returned by Kong and still shows in Kong Manager, but does nothing. Check the
enabledfield, not mere presence.Authentication summary.
authenticationstates plainly whether any ENABLED auth plugin applies, which is usually the actual question.
RETURNS: effectivePlugins (what actually runs, each with ref, name, enabled, scope
and relevant config), shadowed, and an authentication summary object.
LIMITATIONS: plugin config is filtered to diagnostically relevant keys; secret-bearing
fields are never returned. Consumer-scoped plugin instances are listed but their effect
depends on which consumer is calling.
| Name | Required | Description | Default |
|---|---|---|---|
| route | Yes | Route name, id, or `route:<name>` reference, e.g. "route:payments-prod". | |
| includeInherited | No | Also return plugins the route inherits from its service and from global scope (default true). Leave this true when asking "is this route protected" -- a route with no plugins of its own can still be covered by a service-level or global plugin. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, and the description adds substantial context beyond them: shadowed vs effective instances, the enabled=false trap, and the fact that secret-bearing config keys are stripped. It does not disclose pagination or performance characteristics, so it falls just short of the top.
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?
Front-loaded with a one-line purpose, then clearly labelled USE WHEN / IMPORTANT / RETURNS / LIMITATIONS sections. Slightly long overall, but each block is scannable and none is pure padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description takes on the return-value burden and does so: it names effectivePlugins, shadowed, and the authentication summary, and warns that config is filtered and consumer-scoped instances depend on the caller. The one limitation that matters for interpretation is stated explicitly.
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 100%, including a detailed note on includeInherited's default and why to keep it true, so the schema does the heavy lifting. The description never refers to the `route` parameter's accepted formats or the includeInherited flag directly, so it adds no parameter meaning beyond the schema baseline.
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?
Opens with a specific verb+resource ('Lists every plugin that affects a route') plus a scope qualifier ('resolved across all three Kong scopes') that distinguishes it from list_global_plugins and list_routes_for_service. An agent can tell immediately this is the route-scoped, precedence-resolving plugin view.
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?
Explicit 'USE WHEN' clause enumerates concrete triggers (authentication, rate limiting, CORS, ACL, plugin-driven behaviour) and states the question it answers ('is this route protected, and by what'). It also contrasts itself against 'a raw plugin list', effectively routing the agent away from shallower sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_routes_for_serviceList the routes attached to a serviceARead-onlyIdempotent
Lists every route attached to one Kong service.
USE WHEN: you need to know how traffic reaches a service, or to check whether a service has any route at all. A service with zero routes is unreachable through the gateway, which is a real and easily missed misconfiguration.
RETURNS: routes, each with ref, paths and methods, plus routeCount.
LIMITATIONS: does not return plugins for those routes.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum routes to return (default 25). | |
| service | Yes | Service name, id, or `service:<name>` reference. |
TDQS
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 genuine behavioral value beyond that: the zero-route-unreachable insight and the explicit limitation that route plugins are not returned. No auth or rate-limit context, so not a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded opening sentence followed by clearly labeled USE WHEN / RETURNS / LIMITATIONS sections. Every line carries information, and the RETURNS section is warranted because no output schema exists.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description supplies the return shape (ref, paths, methods, routeCount) and an important limitation. Combined with full schema coverage of both parameters, an agent has everything needed to call it correctly.
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 100% with only two parameters, and the description adds no additional meaning about the 'service' reference format or the 'limit' cap. Baseline 3 applies when the schema does the heavy lifting.
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 ('Lists every route attached to one Kong service') with clear scope, distinguishing it from single-route siblings like get_route and find_route_by_path. An agent can tell what it retrieves without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'USE WHEN' block gives explicit triggering conditions, including a non-obvious one (a service with zero routes is unreachable). It does not name the alternative siblings (get_route, find_route_by_path, diagnose_route) to route between them, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_servicesList Kong servicesARead-onlyIdempotent
Lists the services configured in Kong, one compact summary each.
USE WHEN: you need to discover what exists in the gateway, or map a vague name a user gave ("the payments API") onto a real service. Also useful to confirm a service exists before investigating further.
DO NOT USE to investigate a specific route or path. If the user named a path such as /payments, call find_route_by_path instead -- it goes straight to the relevant entity rather than making you scan a list.
RETURNS: items, each with ref (pass to other tools), name, target (where the service
sends traffic) and enabled; plus a page object with hasMore and nextCursor.
LIMITATIONS: summaries only -- no plugins, no routes, no timeouts. Use get_service for the full record of one service. A page that reports hasMore=true is NOT the complete set.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum items to return (1-100, default 25). Prefer a small value and narrow the query instead of paging through everything. | |
| cursor | No | Opaque cursor from a previous result's `nextCursor`. Omit for the first page. Only use a cursor this tool returned -- cursors cannot be constructed. | |
| nameContains | No | Case-insensitive substring filter on the service name, e.g. "payment". Use this rather than paging through every service when you already know roughly what you are looking for. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover the safety profile (readOnly, idempotent, non-destructive, openWorld), and the description goes well beyond them: it discloses the return shape, that entries are summaries only (no plugins/routes/timeouts), points to get_service for the full record, and warns that hasMore=true does not mean the complete set.
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?
Header-delimited blocks (USE WHEN / DO NOT USE / RETURNS / LIMITATIONS) front-load the routing decision, and every line carries actionable content. Length is justified by the paging and summary-vs-full-record caveats.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description carries the return-value burden and does so fully: item fields, page fields, and the summary/full distinction. Nothing an agent needs to call this correctly and interpret results is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, so the baseline is 3. The description adds value by explaining that `ref` is the handle to pass to other tools and by reinforcing the paging contract (hasMore/nextCursor), which connects the schema fields to real workflow semantics rather than restating them.
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+resource ('Lists the services configured in Kong') and immediately scopes the granularity to 'one compact summary each'. Explicitly differentiates itself from find_route_by_path and get_service in later sections, so an agent can place it precisely among siblings.
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?
Has explicit USE WHEN (discover entities, map a vague user name, confirm existence) and DO NOT USE (route/path investigation) with the named alternative find_route_by_path and the reason it is better. This is textbook when/when-not/alternative guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_upstreamsList Kong upstreamsARead-onlyIdempotent
Lists the upstreams (load-balanced backend pools) configured in Kong.
USE WHEN: you need to know which upstream a service name refers to, or which upstreams have health checking configured at all.
RETURNS: upstreams with ref, name, algorithm and healthchecksConfigured.
LIMITATIONS: no targets and no health. Use check_upstream_health for one upstream.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum upstreams to return (default 25). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint, so the safety profile is covered. The description adds genuinely new context beyond that: the returned field set and the negative disclosure that targets and health data are absent, which prevents a wasted follow-up call.
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?
Four labeled blocks (core statement, USE WHEN, RETURNS, LIMITATIONS) with no filler sentences. The purpose is front-loaded in the first line and each subsequent line carries distinct information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, yet RETURNS enumerates the exact fields the caller receives, and LIMITATIONS covers the main failure of expectation for this tool type. Everything needed to select and call it correctly is present.
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 100% and the single 'limit' parameter is fully documented in the schema with its default and bounds. The description adds nothing about pagination or limit behavior, so the baseline 3 is appropriate.
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 ('Lists the upstreams') and immediately clarifies the domain term with '(load-balanced backend pools) configured in Kong'. It is clearly distinguishable from the sibling check_upstream_health, which the LIMITATIONS section names 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?
'USE WHEN' gives two concrete triggers: resolving which upstream a service name maps to, and finding which upstreams have health checking configured. LIMITATIONS routes the agent to check_upstream_health for single-upstream health, so the alternative is explicit rather than inferred.
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.
14 tool updates
v0.1.0- First observed
check_upstream_health - First observed
diagnose_route - First observed
diff_config - First observed
explain_auth_failure - First observed
find_route_by_path - First observed
get_consumer - First observed
get_route - First observed
get_service - First observed
list_consumers - First observed
list_global_plugins - First observed
list_plugins_for_route - First observed
list_routes_for_service - First observed
list_services - First observed
list_upstreams
TDQS
Scored across 14 tools
Tools target distinct Kong entities and actions, and descriptions explicitly steer between similar options such as find_route_by_path vs get_route and diagnose_route vs explain_auth_failure. However, the composite diagnostic tools overlap with the lower-level get/list tools, so an agent could still be unsure whether to assemble evidence manually or use the high-level diagnostic.
All 14 tools use consistent snake_case and a verb-first pattern (find_, list_, get_, check_, diff_, diagnose_, explain_). There are no mixed conventions or ambiguous suffixes.
14 tools is well within the expected 3–15 range for a Kong diagnostic surface. Each tool maps to a meaningful entity or check, with no obvious bloat or thin coverage.
The set covers core diagnostic paths: route resolution, service/consumer/upstream lookup, plugin scoping, health checks, config diff, and high-level diagnosis. Minor gaps remain, such as no general list_routes or get_upstream, but core route/auth troubleshooting workflows are largely complete.
Maintenance
Related MCP Connectors
Gateway between LLM agents and world data through eight tools and a bundled endpoint catalog.
Zero-trust gateway for AI agents: score tool calls, verify agent cards, enforce policy, audit.
LLM Orchestration Observability Agent
Data + AI observability — monitor and troubleshoot production-grade agents and the context they use.
Related MCP Servers
- FlicenseNot gradedqualityBmaintenanceEnables querying and managing AI logs through tools like listing logs, retrieving jobs, and performing AI-powered chat queries. Also provides access to gateway security reports and guardrail testing.-
- AlicenseNot gradedqualityBmaintenanceEnables autonomous SRE incident investigation by allowing users to describe incidents in natural language. The agent follows a governed state machine to gather read-only evidence and produce grounded conclusions.MIT
- FlicenseNot gradedqualityDmaintenanceA Kubernetes diagnostic agent that provides on-demand root cause analysis and human-in-the-loop remediation via Slack, using LLM reasoning with OPA-bounded security controls.1-
- AlicenseNot gradedqualityBmaintenanceEnables agents to interrogate payment routing decisions through six tools: route transactions, explain decisions, simulate scenarios, inspect segment evidence, normalize decline codes, and review backtest summaries. It provides read-only access to the routing engine, allowing natural-language queries without modifying any decisions.MIT