Skip to content

feat(mcp): add a wait-for agent tool - #413

Merged
erkamyaman merged 1 commit into
mainfrom
feat/mcp-wait-for
Oct 15, 2026
Merged

erkamyaman merged 1 commit into
mainfrom
feat/mcp-wait-for

Conversation

@erkamyaman

@erkamyaman erkamyaman commented Oct 15, 2026 •

Copy link
Copy Markdown
Member

What and why

The "general wait-for tool" item from #372.

After a click or a navigation, an agent had to call other tools in a loop until the page caught up. pangular:wait-for blocks until a condition holds, up to timeoutMs (default 5000, kept between 100 and 30000), then answers with what it saw. It is a read tool: it only reads what the collectors already pushed to the server and sends nothing to the page.

condition Holds when Argument
component a component matching selector is rendered selector
component-gone no component matches selector selector
navigation no navigation is in progress, at a URL matching url when given url (optional)
http-call an HttpClient call matching url, or any, finished after the wait started url (optional)
error a new error group, or a higher count on one, with Angular code code when given code (optional)
  • It wakes on the updated events of the component tree, router and HTTP states, and also re-reads every 200ms (the errors state has no change event). It renews the activity lease every 2s so pages keep pushing during a long wait. Every timer and listener is removed before it answers.
  • On timeout it answers Timed out after Nms waiting for …. Last state: …, not an error.
  • Bad arguments (missing or unknown condition, a blank selector, an unknown page, no page reporting that data) get a markdown answer, like the selector guard on inspect-component.
  • Answers that carry page text start with the untrusted-text notice.
  • page / pageId work like the other page tools.

Inspector gating

Each condition needs its own inspector, so the entry lists components, router, http and errors. A new anyInspector field on AgentEntry keeps the tool while any of them is on for agents (otherwise components alone would hide it). The condition enum lists only the conditions whose inspector is on, and the tool is not registered when none is.

Left out

  • "No pending HTTP requests" and "app stable": calls are only recorded once they finish and stability is never pushed, so both would need collector changes.
  • navigation without url can hold before a navigation that was just triggered reaches the page. The docs say so and recommend passing url.

Docs: a wait-for section in agents/tools.md (tool count, conditions and arguments), the structured-output table in agents/mcp-server.md, the page-text row in security.md, the anyInspector row in the contributing guide, and a line in the shipped pangular-inspector skill.

Refs #372.

How it was verified

  • pnpm commit:check
  • pnpm format:check
  • pnpm typecheck
  • pnpm test:devtools (3133). New wait-for.test.ts (17 tests): each condition through the real devframe with push-component-tree, push-router, push-http and push-errors; the timeout answer; argument checks; inspector gating; cleanup with fake timers (vi.getTimerCount() back to zero on success, timeout and a throwing check); timeout clamping. agent-metadata and tool-metadata fixtures updated.
  • pnpm skills:check
  • Docs in apps/docs updated and pnpm docs:build passes
  • No change in app, so no extension:build

Summary by CodeRabbit

  • New Features
    • Added a wait-for tool that waits for components to appear or disappear, navigation to finish, HTTP calls to complete, or new errors to occur. It returns the matching or latest state when the wait ends, including on timeout.
    • The tool is available when at least one supported inspector is enabled and only offers conditions supported by enabled inspectors.
  • Documentation
    • Updated tool counts, usage guidance, output details, configuration behavior, and security notices to cover wait-for.

Agents that click or navigate no longer have to poll other tools in a loop. pangular:wait-for blocks, up to timeoutMs, until a component appears or goes, a navigation settles, an HttpClient call finishes or a new error arrives. It only reads what the collectors already pushed.

Refs #372.
@github-actions github-actions Bot added area: package The ng-devtools package (packages/ng-devtools) area: agents MCP server, agent tools and resources area: docs The documentation site labels Oct 15, 2026
@coderabbitai

coderabbitai Bot commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 3b929bf2-ccb4-462e-a9e9-bae60f31f9b0
📥 Commits

Reviewing files that changed from the base of the PR and between f76a56b and 9e55908.

📒 Files selected for processing: 11
  • apps/docs/src/content/agents/mcp-server.md
  • apps/docs/src/content/agents/tools.md
  • apps/docs/src/content/contributing/development.md
  • apps/docs/src/content/security.md
  • packages/devtools/skills/pangular-inspector/SKILL.md
  • packages/devtools/src/__tests__/fixtures/agent-metadata-derived.json
  • packages/devtools/src/__tests__/tool-metadata.test.ts
  • packages/devtools/src/__tests__/wait-for.test.ts
  • packages/devtools/src/config.ts
  • packages/devtools/src/devframe.ts
  • packages/devtools/src/rpc/wait-for.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 7 remain after this review.

📝 Walkthrough

The devtools agent adds pangular:wait-for for component, navigation, HTTP-call, and error conditions. The tool checks inspector data, waits for a match or timeout, and returns a Markdown result. Inspector configuration controls tool availability and which conditions it offers.

Changes: Wait-for agent tool

Layer / File(s) Summary
Availability and input contract
packages/devtools/src/config.ts, packages/devtools/src/rpc/wait-for.ts, packages/devtools/src/__tests__/fixtures/agent-metadata-derived.json, packages/devtools/src/__tests__/tool-metadata.test.ts, apps/docs/src/content/contributing/development.md
Adds anyInspector availability handling and configures wait-for for components, router, HTTP, and errors. Defines its supported sources, timeout normalization, input and output schemas, and metadata expectations.
Wait checks and results
packages/devtools/src/rpc/wait-for.ts, packages/devtools/src/__tests__/wait-for.test.ts
Implements immediate, event-driven, and polling checks for supported conditions. Returns a matched or last-observed state and cleans up timers and listeners. Tests cover condition handling, timeouts, validation, and cleanup.
Registration and documentation
packages/devtools/src/devframe.ts, apps/docs/src/content/agents/*, apps/docs/src/content/security.md, packages/devtools/skills/pangular-inspector/SKILL.md
Connects the tool to configured inspector data and updates tool count, availability, structured output, security notices, and verification instructions.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant MCPClient
  participant WaitForTool as pangular:wait-for
  participant InspectorState as PangularInspector state
  MCPClient->>WaitForTool: Submit condition and optional filters
  WaitForTool->>InspectorState: Check current reports and subscribe to updates
  InspectorState-->>WaitForTool: Provide reports and change events
  WaitForTool-->>MCPClient: Return matched or timed-out Markdown state
Loading
Merge Risk: ⚪ Minimal · up to 9e559

The wait-for tool is ready to merge after normal checks; no concrete behavior issue remains identified.

Security architecture risk: 🔵 Low · up to 9e559

The new capability preserves read-only access and per-feature permissions. One result path returns application-controlled component names without the data-only warning used elsewhere, creating a limited instruction-injection risk rather than new direct write authority.

Retained concerns

  • Low · security · inferred: The new component wait path returns page-reported names, tags, and IDs as unmarked response text. A malicious or compromised reporting page could place instruction-like content in those fields and have it reach the caller without the data-only notice applied to navigation, HTTP, and error results. Page ownership restricts whose report is accepted, but does not make its contents trusted. This is an additional unmarked response path, not a demonstrated execution or authorization bypass.
Security review details

Security Blast Radius

  • observed — A supplied page ID restricts reads to that exact reporting page. Without it, component, HTTP, and error probes can inspect all reporting pages available to their configured sources; navigation uses the most recent eligible router page. The inspected operation reads these stores rather than gaining page-write authority.

Security Findings and Attack Paths

  • inferred — A page controlling its accepted component report can retain a matching instance ID while placing instruction-like text in the reported name. The component probe interpolates that name directly, and the handler returns it without the untrusted prefix because this probe omits fromPage. This supports an instruction-confusion risk; it does not demonstrate that a caller follows the text or gains additional privileges.

Trust Boundaries and Controls

  • observed — Navigation, HTTP, and error probes explicitly mark their results as page-derived. The shared helper then prepends a data-not-instructions notice. Component responses instead follow an identifier-only exception similar to the pre-existing highlight response; the documentation reflects that distinction. The exception is counterevidence to an accidental policy bypass, but does not itself validate reported strings.

Resilience and Maintainability Implications

  • inferred — No caller-cancellation signal is represented in the inspected wait interface or passed to waitUntil. An abandoned invocation can therefore retain polling, subscriptions, and lease renewal until satisfaction or its capped timeout. This is bounded per invocation; aggregate exhaustion and transport-level cancellation behavior were not established.
Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 36.36% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 11 functions across 5 files. (6 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely identifies the main change: adding the wait-for agent tool for MCP.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 36.36% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 11 functions across 5 files. (6 skipped: 6 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@cloudflare-workers-and-pages

Copy link
Copy Markdown

🚀 Deploying Preview to Cloudflare 🚀

Preview Deployments by commit

Status Deployment URL Commit Updated (UTC) See this deployment's details
  • Build: Failed ❌

View logs ↗
9e55908 2026-10-15T21:02:41.857Z View logs ↗

@nx-cloud

nx-cloud Bot commented Oct 15, 2026

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit 9e55908

Command Status Duration Result
nx affected -t test build ✅ Succeeded 2m 26s View ↗

💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗


☁️ Nx Cloud last updated this comment at 2026-10-15 21:04:15 UTC

@erkamyaman
erkamyaman merged commit c0b1c57 into main Oct 15, 2026
8 of 10 checks passed
@erkamyaman
erkamyaman deleted the feat/mcp-wait-for branch October 15, 2026 21:10
@erkamyaman erkamyaman mentioned this pull request Oct 15, 2026
7 tasks done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: agents MCP server, agent tools and resources area: docs The documentation site area: package The ng-devtools package (packages/ng-devtools)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant