Skip to content

feat(ai): MCP tools for the Infrastructure pages (list_infra, inspect_infra) - #1387

Merged
Makisuo merged 3 commits into
mainfrom
feat/mcp-infra-tools
Oct 10, 2026
Merged

Makisuo merged 3 commits into
mainfrom
feat/mcp-infra-tools

Conversation

@Makisuo

@Makisuo Makisuo commented Oct 10, 2026 •

Copy link
Copy Markdown
Collaborator

What

Agents could only reach infra data through query_data/run_sql. This adds tools built on the same queries as the Infrastructure pages.

  • list_infra: hosts, Kubernetes pods/nodes/workloads and Docker containers, closest to a limit first. No kind gives an overview of every kind that reports. Filters: search, namespace, node, host, workload, status (hot, at_limit, no_limits), include_ended. Shows pod restarts and names the metrics behind each view.
  • inspect_infra: one entity over a window: min/avg/max/last, peak time, trend; a workload's per-pod peaks, a host's per-mount disk use and containers, a node's pods and peer nodes; a note when memory drops after a peak (with the recorded restart count).
  • diagnose_service: adds the Kubernetes workload and pods the service runs on. A failed lookup is reported beside the diagnosis, never instead of it.
  • create_dashboard: accepts resource.<key> group_by on metrics (the query builder already did).
  • Queries: hostFilesystemsQuery (pins state = 'used') and podRestartsQuery (k8s.container.restarts, max - min per container), with benchmark builders.

Testing

  • infra-tools.test.ts against a fixture infra world (src/mcp/__evals__/infra-world.ts), plus six capability tasks in the tool evals.
  • A tool playground (apps/ai/scripts/tool-playground.sh, src/evals/playground/README.md): agents answer eight realistic questions using only the tools, and report every call and what confused them. Four rounds, fixing the tools between them; results are in the README.
  • Scoped: apps/ai, domain, query-engine and web typecheck; related apps/ai and query-engine test files; oxlint and oxfmt on changed files.

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

list_infra lists hosts, Kubernetes pods/nodes/workloads and Docker
containers closest to a limit first, with fleet counts, status filters
(hot, at_limit, no_limits), pod restarts and the metrics behind each
view. inspect_infra reads one entity over a window: min/avg/max/last,
peak time and trend, per-pod peaks for a workload, per-mount disk use
for a host, node peers, and a note when memory drops after a peak.

diagnose_service now shows the workload and pods a service runs on.
create_dashboard accepts resource.<key> group_by on metrics, which the
query builder already supported.

Adds hostFilesystemsQuery (pins state = used) and podRestartsQuery,
a fixture infra world, and a tool playground that lets agents test the
tools by using them (apps/ai/src/evals/playground/README.md).
@coderabbitai

coderabbitai Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 31 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 4 included reviews currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 2a1dcc6a-05b9-4997-8d90-49c246716798

📥 Commits

Reviewing files that changed from the base of the PR and between cce3e33 and d8c5987.


📒 Files selected for processing (26)
  • apps/ai/scripts/tool-playground.sh
  • apps/ai/src/evals/playground/README.md
  • apps/ai/src/evals/playground/tool.playground.ts
  • apps/ai/src/evals/tools/tasks.ts
  • apps/ai/src/evals/tools/tools.eval.ts
  • apps/ai/src/mcp/__evals__/infra-world.ts
  • apps/ai/src/mcp/lib/infra-inspect.ts
  • apps/ai/src/mcp/lib/infra-params.ts
  • apps/ai/src/mcp/lib/infra-render.ts
  • apps/ai/src/mcp/lib/infra.ts
  • apps/ai/src/mcp/resources/instructions.ts
  • apps/ai/src/mcp/tools/__tests__/infra-tools.test.ts
  • apps/ai/src/mcp/tools/create-dashboard.test.ts
  • apps/ai/src/mcp/tools/create-dashboard.ts
  • apps/ai/src/mcp/tools/diagnose-service.ts
  • apps/ai/src/mcp/tools/inspect-infra.ts
  • apps/ai/src/mcp/tools/list-infra.ts
  • apps/ai/src/mcp/tools/registry.ts
  • apps/ai/vitest.playground.config.ts
  • packages/domain/src/mcp-outputs/catalog.ts
  • packages/domain/src/mcp-outputs/index.ts
  • packages/domain/src/mcp-outputs/infra.ts
  • packages/domain/src/mcp-outputs/services.ts
  • packages/query-engine/src/benchmark/builders.ts
  • packages/query-engine/src/ch/index.ts
  • packages/query-engine/src/ch/queries/infra.ts

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@maple-review-bot

maple-review-bot Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Note

A newer push replaced 4de3736 before its review finished. The latest commit is reviewed in a new comment.

Comment thread apps/ai/src/mcp/__evals__/infra-world.ts Fixed
@maple-review-bot

maple-review-bot Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Maple review

🟢 Confidence 7/10 · likely safe to merge
Read every source hunk and the fixture world; restart attribution and the detail SQL rest on a fixture warehouse, not on live data.
quality 90/100 · 1 warning · tests partial · risk medium · 2/2 new units observable · 1 file not read

Adds list_infra and inspect_infra MCP tools over new and existing infra queries, extends diagnose_service with the service's Kubernetes workload and pods, and lets create_dashboard group metrics by resource.<key>. Mostly safe to merge; one pod-restart attribution bug is worth fixing first. The open registry.js error issues (McpQueryError, VcsSourceRepositoryNotFoundError, GithubAppError, IntegrationsUpstreamError) are untouched: the diff only adds two registrations and changes no error path. The __evals__/infra-world.ts fixture and the playground script were read as test support, not production code.

  • list_infra and inspect_infra register two new MCP tools
  • hostFilesystemsQuery and podRestartsQuery join the query engine
  • diagnose_service appends the service's k8s workload and its pods
  • create_dashboard accepts resource.<key> group_by on metrics

Findings

🟠 Warning · F1 · podRestarts sums restarts across namespaces by pod name

correctness · apps/ai/src/mcp/lib/infra.ts:258-263

podRestartsQuery is filtered by k8s.pod.name only (line 255), not by namespace or cluster, and the result is keyed by pod name alone. Two pods with the same name in different namespaces or clusters — e.g. redis-0 in staging and in prod, or in two clusters — get one summed restart count and every one of their rows in list_infra shows that sum. inspect_infra passes the namespace to the same query; the list path does not.

Key the map by pod name plus namespace and pass the listed rows' namespaces into `podRestartsQuery`, or fetch restarts per row with its own namespace.
🤖 Prompt to fix this finding with an AI agent
Findings from an automated review of commit 22602486e0ba7e33a01d403eec827b0f13b09e84. Verify each one against the current code before changing anything, fix only those that still apply, and keep each fix to the lines it names.

---

F1 · Warning · correctness · apps/ai/src/mcp/lib/infra.ts:258-263
`podRestarts` sums restarts across namespaces by pod name
`podRestartsQuery` is filtered by `k8s.pod.name` only (line 255), not by namespace or cluster, and the result is keyed by pod name alone. Two pods with the same name in different namespaces or clusters — e.g. `redis-0` in staging and in prod, or in two clusters — get one summed restart count and every one of their rows in `list_infra` shows that sum. `inspect_infra` passes the namespace to the same query; the list path does not.
Suggested fix: Key the map by pod name plus namespace and pass the listed rows' namespaces into `podRestartsQuery`, or fetch restarts per row with its own namespace.

Production impact

Open errors in the changed files
Issue Service Occurrences File
@maple/api/vcs/VcsSourceRepositoryNotFoundError maple-ai 68 apps/ai/src/mcp/tools/registry.ts
@maple/mcp/errors/McpQueryError maple-chat 42 apps/ai/src/mcp/tools/registry.ts
@maple/mcp/errors/McpQueryError maple-chat 36 apps/ai/src/mcp/tools/registry.ts
@maple/mcp/errors/McpQueryError maple-ai 18 apps/ai/src/mcp/tools/registry.ts
@maple/api/vcs/GithubAppError maple-chat 14 apps/ai/src/mcp/tools/registry.ts
@maple/http/errors/IntegrationsUpstreamError maple-chat 14 apps/ai/src/mcp/tools/registry.ts
@maple/http/errors/IntegrationsUpstreamError maple-chat 11 apps/ai/src/mcp/tools/registry.ts
@maple/mcp/errors/McpQueryError maple-ai 9 apps/ai/src/mcp/tools/registry.ts
@maple/mcp/errors/McpQueryError maple-ai 9 apps/ai/src/mcp/tools/registry.ts
@maple/mcp/errors/McpQueryError maple-chat 8 apps/ai/src/mcp/tools/registry.ts

After this merges, Maple checks whether they stop.

Production traffic of the changed files (last 7 days)
File Calls/day Busiest operations
apps/ai/src/mcp/lib/infra.ts 58 infraPresence 48/day, 2.4% err
listHosts 4/day, 6.7% err
listPods 3/day, 0.0% err
apps/ai/src/mcp/lib/infra-inspect.ts 6 podInfraTimeseries 5/day, 0.0% err
podDetailSummary 1/day, 0.0% err
Telemetry this change adds and removes (2)
  • ➕ span name McpTool.inspectInfra · apps/ai/src/mcp/tools/inspect-infra.ts:111
  • ➕ span name McpTool.listInfra · apps/ai/src/mcp/tools/list-infra.ts:108
What was checked
  • New queries filter OrgId and the window (queries/infra.ts:240, :280)
  • resource.<key> group_by is served by groupByResourceAttributeKey in the metrics builder (queries/metrics.ts:99)
  • diagnose_service wraps the infra lookup in Effect.result, so its failure cannot replace the diagnosis
Observability coverage: 2 of 2 changes observable
Change Kind Observable Evidence
MCP tool entrypoints list_infra / inspect_infra Server yes Handlers carry the repo's Effect.fn("McpTool.listInfra") span and the dispatcher annotates maple.mcp.tool (tools/list-infra.ts:108)
Warehouse reads added by the tools (infraPresence, listHosts, listPods, podRestarts, hostFilesystems) Client yes Each runs through executor.compiledQuery(...) with a profile and context (lib/infra.ts:54, :254)
Files not reviewed (1)

The review ended before it read these diffs, so nothing above vouches for them.

  • apps/ai/src/evals/playground/tool.playground.ts

2260248 · Updated on every push. Reply "won't fix" to dismiss a finding, or mention @maple-review-bot to ask about one.

@maple-review-bot maple-review-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 inline note from Maple's review. The score and summary are in the review comment above.

Comment thread apps/ai/src/mcp/lib/infra.ts
Pod names repeat across namespaces, so list_infra summed restarts of
same-named pods into every one of their rows.
@maple-review-bot

maple-review-bot Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Maple review

🟢 Confidence 9/10 · safe to merge
The one open finding is fixed and pinned by a test that fails without the namespace key; the four files changed since the last review were read in full.
quality 100/100 · no findings · tests covered · risk low · 1/1 new units observable

The last commit fixes podRestarts summing same-named pods across namespaces: the query now groups by namespace and the list keys on namespace plus pod name, with a test that fails without it. The changed files are safe to merge; none of the open registry errors touch this diff.

  • podRestartsQuery selects and groups by k8s.namespace.name
  • podKey matches restarts to a pod by namespace and name
  • Infra fixture answers restarts per namespace

Fixed since the last review

  • ✅ F1 · podRestarts sums restarts across namespaces by pod name

Production impact

Open errors in the changed files
Issue Service Occurrences File
@maple/api/vcs/VcsSourceRepositoryNotFoundError maple-ai 68 apps/ai/src/mcp/tools/registry.ts
@maple/mcp/errors/McpQueryError maple-chat 42 apps/ai/src/mcp/tools/registry.ts
@maple/mcp/errors/McpQueryError maple-chat 36 apps/ai/src/mcp/tools/registry.ts
@maple/mcp/errors/McpQueryError maple-ai 18 apps/ai/src/mcp/tools/registry.ts
@maple/api/vcs/GithubAppError maple-chat 14 apps/ai/src/mcp/tools/registry.ts
@maple/http/errors/IntegrationsUpstreamError maple-chat 14 apps/ai/src/mcp/tools/registry.ts
@maple/http/errors/IntegrationsUpstreamError maple-chat 11 apps/ai/src/mcp/tools/registry.ts
@maple/mcp/errors/McpQueryError maple-ai 9 apps/ai/src/mcp/tools/registry.ts
@maple/mcp/errors/McpQueryError maple-ai 9 apps/ai/src/mcp/tools/registry.ts
@maple/mcp/errors/McpQueryError maple-chat 8 apps/ai/src/mcp/tools/registry.ts

After this merges, Maple checks whether they stop.

Production traffic of the changed files (last 7 days)
File Calls/day Busiest operations
apps/ai/src/mcp/lib/infra.ts 58 infraPresence 48/day, 2.4% err
listHosts 4/day, 6.7% err
listPods 3/day, 0.0% err
apps/ai/src/mcp/lib/infra-inspect.ts 6 podInfraTimeseries 5/day, 0.0% err
podDetailSummary 1/day, 0.0% err
Telemetry this change adds and removes (2)
  • ➕ span name McpTool.inspectInfra · apps/ai/src/mcp/tools/inspect-infra.ts:111
  • ➕ span name McpTool.listInfra · apps/ai/src/mcp/tools/list-infra.ts:108
What was checked
  • podKey reads the same k8s.namespace.name resource attribute as the list row (infra.ts:250, infra.ts:352)
  • Row schema is derived from the SELECT, so the new namespace column decodes (packages/query-engine/src/ch/queries/infra.ts:275)
  • The new test fails under name-only keying: the fixture answers 1 and 7 for the two namespaces (infra-tools.test.ts:70)
Observability coverage: 1 of 1 changes observable
Change Kind Observable Evidence
pod restarts warehouse query outbound yes WarehouseExecutor.compiledQuery with { profile: "aggregation", context: "podRestarts" } (apps/ai/src/mcp/lib/infra.ts:259)

d8c5987 · Updated on every push. Reply "won't fix" to dismiss a finding, or mention @maple-review-bot to ask about one.

@Makisuo
Makisuo merged commit 6a3ef1e into main Oct 10, 2026
39 of 41 checks passed
@Makisuo
Makisuo deleted the feat/mcp-infra-tools branch October 10, 2026 23:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants