Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@ Pangular Inspector inspects a running Angular app and serves what it finds to a

### Commands

| Command | What it runs |
| ---------------------- | ------------------------------------------------------- |
| `pnpm test:devtools` | Package tests |
| `pnpm test:panel` | Panel tests |
| `pnpm test:axe` | Builds a static report and runs axe on every panel view |
| `pnpm typecheck` | TypeScript and template checks for every project |
| `pnpm format:check` | Prettier, including the docs markdown |
| `pnpm skills:check` | Checks the skills and roles in `.claude` |
| `pnpm docs:build` | Builds the docs site with its link guards |
| `pnpm extension:build` | Rebuilds `extension/ui` from `app` |
| `pnpm commit:check` | Checks the commit messages on the branch |
| Command | What it runs |
| ---------------------- | ------------------------------------------------------------------------- |
| `pnpm test:devtools` | Package tests |
| `pnpm test:panel` | Panel tests |
| `pnpm test:axe` | Builds a static report and runs axe on every panel view |
| `pnpm typecheck` | TypeScript and template checks for every project |
| `pnpm format:check` | Prettier, including the docs markdown |
| `pnpm skills:check` | Checks the skills and roles in `.claude` and the skills the package ships |
| `pnpm docs:build` | Builds the docs site with its link guards |
| `pnpm extension:build` | Rebuilds `extension/ui` from `app` |
| `pnpm commit:check` | Checks the commit messages on the branch |

The words this project uses for its own concepts (overlay, collector, hub, devframe, agent tool and so on) are defined in `docs/CONTEXT.md`. Use them the same way in code, docs and issues.

Expand Down
92 changes: 92 additions & 0 deletions apps/docs/src/content/agents/browser-agents.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
---
title: Browser agents
description: The overlay registers the read-only agent tools on the page through WebMCP and Chrome DevTools for agents, so a browser agent finds them without MCP setup.
---

<ngmd-hero title="Browser agents" gradient>
An agent that drives the browser finds the read-only devtools tools on the page itself. No MCP client config, no token.
</ngmd-hero>

# Browser agents

Turn it on with `agent: { browserTools: true }` in your [config](../getting-started/configuration.md#inspectors-and-agent-tools). It is off by default, because any script on the page could then call the tools.

When it is on and the overlay connects, it registers the `read` [agent tools](./tools.md) on the page in two ways:

| Mechanism | What the page does | Who finds the tools |
| -------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
| WebMCP | Calls `document.modelContext.registerTool()` for each tool, or `navigator.modelContext.registerTool()` (earlier drafts) | A browser with WebMCP, a WebMCP polyfill or extension, and in-page agents |
| Chrome DevTools for agents | Answers the `devtoolstooldiscovery` event on `window` with one tool group, **Pangular Inspector** | The Chrome DevTools MCP server, through `list_3p_developer_tools` |

Each call goes from the page to the devtools server, which runs the same handler an MCP client gets. The tools are the ones the [MCP server](./mcp-server.md) lists, under the same names, such as `pangular_inspect-component`.

## Which tools the page registers

Only tools in the `read` [safety tier](./tools.md#action-tools). Action and destructive tools, such as `navigate`, `fill-form` or `clear-recordings`, never reach the page.

Of the `read` tools, the page registers two kinds. The first answer for one page and take `page` or `pageId`. The second read your source, such as `get-routes`, `get-components` and `build-meta`. The following tools stay with the [MCP server](./mcp-server.md) only:

| Tool | Why it stays off the page |
| ---------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| `list-pages` | It lists every tab that reports. |
| `list-ssr-requests`, `explain-ssr-request`, `list-ssr-overrides`, `list-http-rules`, `analog-server-calls` | They answer about the whole server, for every tab. |
| `screenshot-component` | A page tool answers with text, not an image, and the capture draws the whole component. |
| `highlight` | It draws on the page and changes the selection in open panels. |
| `open-in-panel` | It switches the panels that are open. |

The config decides the rest, as for MCP clients:

| Option | Effect on the page tools |
| -------------------- | ------------------------------------------------------------------------------------------------------- |
| `inspectors.<name>` | An inspector that is off has no tools on the page. |
| `agent.tools.<name>` | `false` leaves that inspector's tools off the page. |
| `agent.readOnly` | `change-detection` and `hydration` join as `read` tools, without the arguments that act. |
| `agent.browserTools` | Off by default: nothing is registered on the page. `true` turns it on. The MCP server keeps every tool. |

See [Configuration](../getting-started/configuration.md#inspectors-and-agent-tools).

## How the tools answer

- A tool that takes `page` or `pageId` always answers for the page that registered it. A `page` or `pageId` the agent passes is replaced with that page's id, so a page never reads another tab. When the page has not reported that data, the answer says so without naming other tabs.
- The answer is the markdown or JSON an MCP client gets. Secret names, JWTs and bearer tokens are masked, as in every answer. See [Redaction](../security.md).
- Answers over 100,000 characters are cut, with a note to narrow the call.
- A WebMCP call resolves to `{content: [{type: 'text', text}]}`. A refused or failed call rejects with the reason.

The WebMCP registration carries the `readOnlyHint`, `untrustedContentHint` and `debugging` annotations. `debugging` marks them as developer tools rather than features of your app, and the Chrome DevTools MCP server lists WebMCP tools with it under `list_3p_developer_tools`. When the browser has WebMCP of its own, the `devtoolstooldiscovery` group leaves out the tools WebMCP already registered, so Chrome DevTools for agents lists each tool once.

## Use them from Chrome DevTools for agents

<ngmd-workflow>
<ngmd-step title="Start the app">
Run your app in development with the overlay, and open it in the Chrome that the Chrome DevTools MCP server controls.
</ngmd-step>
<ngmd-step title="Turn on third-party tools">
Start the Chrome DevTools MCP server with <code>--categoryExperimentalThirdParty=true</code>. The category is off by default.
</ngmd-step>
<ngmd-step title="List and call">
Ask the agent to call <code>list_3p_developer_tools</code>. The <strong>Pangular Inspector</strong> group lists the tools. The agent runs one with <code>execute_3p_developer_tool</code>.
</ngmd-step>
</ngmd-workflow>

## When the page registers them

| Event | What happens |
| ----------------------------------------------- | ---------------------------------------------------- |
| The overlay connects | It asks the server for the tools and registers them. |
| `pagehide` | It unregisters them. |
| The page comes back from the back/forward cache | It registers them again. |
| `disposeOverlay()` or a second `initOverlay()` | It unregisters them. |

Without WebMCP, the page only listens for `devtoolstooldiscovery`. It writes nothing to your app's DOM. The [Forms](../inspectors/forms.md) tab leaves these tools out of its WebMCP list, which shows the tools of your app.

<ngmd-callout type="warning" title="Any script on the page can call them">
In-page agents and other scripts can list WebMCP tools and run them. The tools don't change your app's data, but they read the server's view of your page, including the source scan, and <code>inspect-component</code> selects the instance it reads in open panels. Leave <code>agent.browserTools</code> off if your development page loads scripts you don't trust.
</ngmd-callout>

## Where to next

<ngmd-pill-row>
<ngmd-pill href="/agents/tools" title="Tools"></ngmd-pill>
<ngmd-pill href="/agents/skills" title="Agent skills"></ngmd-pill>
<ngmd-pill href="/getting-started/configuration" title="Configuration"></ngmd-pill>
</ngmd-pill-row>
45 changes: 24 additions & 21 deletions apps/docs/src/content/agents/mcp-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,27 +247,30 @@ The server registers tools with a colon, as `pangular:get-routes`. MCP clients s

### Read and action tools

Each tool has a safety tier: `read`, `action` or `destructive`. The server marks `read` tools as read-only for your client, and `destructive` tools as destructive. Fifteen tools act on the app, so the server does not mark them read-only:

| Tool | Tier | Reference |
| ------------------------ | ------------- | ----------------------------------------------------- |
| `navigate` | `action` | [Act on the router](./tools.md#act-on-the-router) |
| `dispatch-ngrx-action` | `action` | [Dispatch an action](./tools.md#dispatch-an-action) |
| `form-action` | `action` | [Act on a form](./tools.md#act-on-a-form) |
| `fill-form` | `action` | [Act on a form](./tools.md#act-on-a-form) |
| `set-http-rule` | `action` | [Fault rules](./tools.md#fault-rules) |
| `remove-http-rule` | `action` | [Fault rules](./tools.md#fault-rules) |
| `set-component-property` | `action` | [Edit a component](./tools.md#edit-a-component) |
| `set-signal` | `action` | [Edit a component](./tools.md#edit-a-component) |
| `watch-signal` | `action` | [watch-signal](./tools.md#watch-signal) |
| `record-pipes` | `action` | [Record pipe calls](./tools.md#record-pipe-calls) |
| `track-subscriptions` | `action` | [Track subscriptions](./tools.md#track-subscriptions) |
| `change-detection` | `action` | [change-detection](./tools.md#change-detection) |
| `hydration` | `action` | [hydration](./tools.md#hydration) |
| `clear-recordings` | `destructive` | [Clear recordings](./tools.md#clear-recordings) |
| `analog-call-api` | `destructive` | [Call a server route](./tools.md#call-a-server-route) |

Your client can ask you before it runs them. To drop them from the server, set `agent.readOnly`, which keeps only the `read` tools. `change-detection` stays without its `record` argument, as a `read` tool. See [Inspectors and agent tools](../getting-started/configuration.md#inspectors-and-agent-tools).
Each tool has a safety tier: `read`, `action` or `destructive`. The server marks `read` tools as read-only for your client, and `destructive` tools as destructive. Eighteen tools act on the app, so the server does not mark them read-only:

| Tool | Tier | Reference |
| ------------------------ | ------------- | ----------------------------------------------------------------------------- |
| `navigate` | `action` | [Act on the router](./tools.md#act-on-the-router) |
| `dispatch-ngrx-action` | `action` | [Dispatch an action](./tools.md#dispatch-an-action) |
| `form-action` | `action` | [Act on a form](./tools.md#act-on-a-form) |
| `fill-form` | `action` | [Act on a form](./tools.md#act-on-a-form) |
| `set-http-rule` | `action` | [Fault rules](./tools.md#fault-rules) |
| `remove-http-rule` | `action` | [Fault rules](./tools.md#fault-rules) |
| `set-ssr-override` | `action` | [TransferState and SSR overrides](./tools.md#transferstate-and-ssr-overrides) |
| `remove-ssr-override` | `action` | [TransferState and SSR overrides](./tools.md#transferstate-and-ssr-overrides) |
| `set-component-property` | `action` | [Edit a component](./tools.md#edit-a-component) |
| `set-signal` | `action` | [Edit a component](./tools.md#edit-a-component) |
| `watch-signal` | `action` | [watch-signal](./tools.md#watch-signal) |
| `record-pipes` | `action` | [Record pipe calls](./tools.md#record-pipe-calls) |
| `track-subscriptions` | `action` | [Track subscriptions](./tools.md#track-subscriptions) |
| `change-detection` | `action` | [change-detection](./tools.md#change-detection) |
| `hydration` | `action` | [hydration](./tools.md#hydration) |
| `audit` | `action` | [audit](./tools.md#audit) |
| `clear-recordings` | `destructive` | [Clear recordings](./tools.md#clear-recordings) |
| `analog-call-api` | `destructive` | [Call a server route](./tools.md#call-a-server-route) |

Your client can ask you before it runs them. To drop them from the server, set `agent.readOnly`, which keeps only the `read` tools. `change-detection` stays without its `record` argument, `hydration` without its `overlay` argument and `audit` without its `axe` argument, as `read` tools. See [Inspectors and agent tools](../getting-started/configuration.md#inspectors-and-agent-tools).

### Pages and tabs

Expand Down
Loading
Loading