On this page ▾
MCP server
The devtools expose their inspectors to coding agents as MCP tools and resources. An agent can list your routes, read the live component tree, explain why a form is invalid, or navigate the app.
There are two ways to connect. Pick one based on the data your agent needs.
Pick a transport
ng-devtools mcp for your project folder. The server scans your source. No page ever connects to it.
/__devframes/__mcp on the server that runs your app. Pages open in a browser report to it, so the live tools work.
| Transport | Live page data | Setup |
|---|---|---|
stdio (ng-devtools mcp) |
No. Source scan tools only. | A command in your MCP client config. |
HTTP (/__devframes/__mcp) |
Yes, with the app open in a browser. | A URL on your app's dev server. |
Connect over stdio
The package ships an ng-devtools binary. Its mcp command starts an MCP server on stdin and stdout.
Add the stdio server to your client
claude mcp add ng-devtools -- npx @santoshyadavdev/ng-devtools mcp --root /path/to/your-app// .cursor/mcp.json
{
"mcpServers": {
"ng-devtools": {
"command": "npx",
"args": ["@santoshyadavdev/ng-devtools", "mcp", "--root", "${workspaceFolder}"]
}
}
}// .vscode/mcp.json
{
"servers": {
"ng-devtools": {
"type": "stdio",
"command": "npx",
"args": ["@santoshyadavdev/ng-devtools", "mcp", "--root", "${workspaceFolder}"]
}
}
}Point it at the project folder
The server scans the folder it starts in, and your client picks that folder. Some clients start servers in /. Pass --root with the root of your Angular or Analog project, the folder with package.json and angular.json, or set NG_DEVTOOLS_ROOT. Cursor and VS Code expand ${workspaceFolder} to the open folder.
If the folder has no angular.json and no package.json that depends on @angular/core, the server prints a warning on stderr. Your client shows it in the MCP server log.
Configure the stdio server
The stdio server reads the devtools options from ng-devtools.config.json in the project folder, from the file you pass with --config, or from NG_DEVTOOLS_CONFIG. --read-only sets agent.readOnly. See Flags for every command.
pnpm devtools:mcp runs the same server against the demo app.
What stdio can answer
Over stdio, the source scan tools work: get-routes, get-components, get-signals, get-providers, get-ngrx-store, get-pipes and build-meta. So do the tools that read files only, like lint-pipes, explain-pipe, explain-render-mode, analog-routes and analog-lint.
The stdio server leaves out the tools and resources that need the running app, such as highlight, navigate, form-action, fill-form, the forms and router tools, analog-current-page, analog-server-calls and analog-call-api. Use HTTP for those.
Connect over HTTP
When the devtools are embedded in your app's server, the same tools are served over HTTP. This endpoint sees the pages that connect to that server.
Find your endpoint
The path depends on how you mount the devtools. Use the port your server actually runs on.
| Setup | Endpoint |
|---|---|
| Express hub | http://localhost:4000/__devframes/__mcp |
| Vite plugin | http://localhost:5173/__devframes/__mcp |
| Standalone CLI | http://localhost:9999/__mcp |
The standalone CLI uses port 9999 by default. If that port is taken and you did not pass --port, it picks a free port. Use the URL it prints.
If you mount the devtools panel without the hub, at /__ng-devtools/, the endpoint is /__ng-devtools/__mcp.
Send an Origin header
Origin header, such as http://localhost:4000. Requests without one get 403 Forbidden. With the Vite plugin, the request must also come from a loopback address. If your MCP client does not send an Origin header, add it in the client config.
The header value is the origin of your dev server. Every example below sets it.
Send a token
If the hub asks for the one-time code, the HTTP endpoint also asks for a bearer token. Requests without the right token get 401.
| Setup | Token required |
|---|---|
| Express hub | Yes, unless you pass auth: false or your own mcp option. |
| Vite plugin | Only when the one-time code is on. See the plugin's auth option. |
The hub prints a generated token in the terminal when it starts. The token changes when the server process restarts, but not when ng serve rebuilds server.ts. To keep the same token across restarts, set NG_DEVTOOLS_MCP_TOKEN in the environment of the server. The hub then uses that value and prints nothing.
Send the token in an Authorization: Bearer <token> header, next to the Origin header. If your setup needs no token, leave the Authorization header out.
The stdio server never needs a token.
Add the HTTP endpoint to your client
// .mcp.json
{
"mcpServers": {
"ng-devtools": {
"type": "http",
"url": "http://localhost:4000/__devframes/__mcp",
"headers": {
"Authorization": "Bearer ${NG_DEVTOOLS_MCP_TOKEN}",
"Origin": "http://localhost:4000"
}
}
}
}// .cursor/mcp.json
{
"mcpServers": {
"ng-devtools": {
"url": "http://localhost:4000/__devframes/__mcp",
"headers": {
"Authorization": "Bearer ${env:NG_DEVTOOLS_MCP_TOKEN}",
"Origin": "http://localhost:4000"
}
}
}
}// .vscode/mcp.json
{
"inputs": [
{
"type": "promptString",
"id": "ng-devtools-token",
"description": "ng-devtools MCP token",
"password": true
}
],
"servers": {
"ng-devtools": {
"type": "http",
"url": "http://localhost:4000/__devframes/__mcp",
"headers": {
"Authorization": "Bearer ${input:ng-devtools-token}",
"Origin": "http://localhost:4000"
}
}
}
}The Claude Code and Cursor examples read the token from NG_DEVTOOLS_MCP_TOKEN, so set the same value for the server and the client. VS Code asks for the token the first time it starts the server.
Open the app in a browser
The live tools read what the page reports. Without an open page, they have nothing to answer with.
ng-devtools dev.
explain-form-invalid on the connected page.
How tools behave
Tool names
The server registers tools with a colon, as ng-devtools:get-routes. MCP clients see them with an underscore, as ng-devtools_get-routes. Calls with either form work.
Read and action tools
The server marks read-only tools as read-only for your client. Six tools act on the app, so the server does not mark them:
| Tool | Reference |
|---|---|
highlight |
Components, signals and DI |
navigate |
Act on the router |
dispatch-ngrx-action |
Dispatch an action |
form-action |
Act on a form |
fill-form |
Act on a form |
analog-call-api |
Call a server route |
Your client can ask you before it runs them. To drop them from the server, set agent.readOnly. See Inspectors and agent tools.
Pages and tabs
Each browser tab reports on its own and gets a page id, and so does an Angular Native app. list-pages lists them with their platform. Tools that read live data use the most recent page by default. Pass page to pick another tab (inspect-providers, highlight, inspect-component and defer-blocks also accept pageId). An id that no tab reports gets an answer that lists the tabs that do, instead of data from another tab. The server drops pages that stop reporting after a short time.