Skip to main content
Glama
Alex88Ryabov

@alex-apps/ng-token-saver

by Alex88Ryabov

ng-token-saver

npm version weekly downloads node license

An MCP server that lets an AI agent understand Angular templates by asking the same compiler that builds the project, instead of guessing from file text. The token saving is measured, not promised.

Angular ships a first-class language server, but no official AI integration exposes it — the Angular CLI MCP (ng mcp) works at the docs-and-build level and does not touch templates. This server is that missing layer, and it answers for the Angular version the project actually runs.

Everything below marked as measured was produced by running code against six real Angular workspaces (17.3.12, 18.2.14, 19.2.25, 20.3.26, 21.2.18, 22.0.8) and two production projects. Every number can be reproduced with the commands in Reproducing the measurements.

Quick start

The language server ships as a regular dependency — nothing to install besides the package:

npm install -g @alex-apps/ng-token-saver

Claude Code:

claude mcp add ng-token-saver -- ng-token-saver

Codex CLI:

codex mcp add ng-token-saver -- ng-token-saver

Any other MCP client:

{ "mcpServers": { "ng-token-saver": { "command": "ng-token-saver" } } }

Or skip the install and let the client fetch it through npx:

{ "mcpServers": { "ng-token-saver": { "command": "npx", "args": ["-y", "@alex-apps/ng-token-saver"] } } }

In Cursor that npx form is one click:

Add to Cursor

The npm and npx paths are verified by running: the packed tarball (79 kB, dist only) was installed into a clean prefix and all four tool kinds answered through a real MCP client, and the npx form connects in 1.2–2.0 s from a warm npm cache (the very first run on a machine also downloads the dependency tree — the language server alone unpacks to 13.6 MB).

A first question to ask it — the contract of a component whose members are scattered across an extends chain. Asked for fixtures/v17/src/app/derived-card.component.ts (a fixture in this repository), ng_component_info answers, verbatim:

{"found":true,"angularVersion":"17.3.12","className":"DerivedCardComponent","kind":"component","selector":"app-derived-card","standalone":true,"inlineTemplate":true,"styleUrls":[],"imports":[],"hostDirectives":[],"extends":"BasePanel","ancestors":["BasePanel","BaseWidget"],"inputs":[{"name":"accent","type":"boolean"},{"name":"heading","type":"string"},{"name":"disabled","type":"boolean"}],"outputs":[{"name":"blurred","type":"void"}],"publicMembers":[{"name":"focus","kind":"method","signature":"focus(): void","noop":true},{"name":"collapse","kind":"method","signature":"collapse(animated: boolean): void","noop":true}]}

624 characters, 305 ms on the session's first call (it loads the project's own TypeScript), single-digit milliseconds after. The asked file declares one input and an extends clause; heading, disabled, the output and both methods live in BasePanel and BaseWidget and are resolved statically, and "noop": true on focus() is the subclass shadowing it with an empty body — the kind of fact that otherwise costs a whole file read per ancestor.

Configs for Cursor, VS Code, Windsurf, Codex CLI and JetBrains, the Node floor, and running from source are in Requirements and setup.

Related MCP server: agent-workspace-mcp

The two problems it solves

1. No template awareness. grep over an .html file cannot tell you where {{ user().fullName }} is declared, and no amount of reading gives you NG2339 Property 'emailAddress' does not exist on type 'UserVm'. That is compiler output, not text.

2. Version drift. The AI context files on angular.dev (llms.txt) describe only the newest major and carry no version markers; the versioned archive sites serve none at all. On v17–v21 they hand the agent instructions that produce APIs which do not exist. Measured examples are in Version facts.

Tools

Six tools, 1001 characters of descriptions in total. Answers are dense JSON with no markdown.

Tool

What it answers

Needs the language server

ng_template_definition

where a symbol under this template position is declared

yes

ng_template_diagnostics

Angular compiler errors for a template, or for a files batch; an entry anchored in the companion .ts carries file

yes

ng_component_info

the public contract of a component or directive

no

ng_workspace_map

projects, versions, strictTemplates and zone.js per project

no

ng_version_rules

what exists and what does not in this project's Angular version

no

ng_find_usages

where a component, directive, pipe or service is used; with input — where that input is bound

no

Four of the six never start the language server, so they answer in milliseconds and keep working on workspaces where the server refuses to load.

Measured: contract instead of the whole file

ng_component_info returns the public contract of a component rather than its source. Measured across two production codebases through a real MCP client:

Nx monorepo

CLI workspace*

Angular / TypeScript

19.2.18 / 5.8.3

17.3.8 / 5.3.3

Components in the tally

1298

407

Parse errors

0

0

Sources

5 404 708 chars

1 735 223 chars

Contracts (base-class members included)

1 759 331 chars

463 563 chars

Saved

67%

73%

Saved in tokens (o200k_base proxy)

67%

71%

Contract shorter than source

1201 of 1298 (93%)

386 of 407 (95%)

Flagged as partial

1 of 1298

3 of 407

First call (loads the project's TypeScript)

306 ms

564 ms

* measured with the pre-0.1.2 wire format; the current format is leaner, so this saving is a floor.

The largest component in the monorepo shrinks from 177 863 to 10 770 characters while listing 117 contract members. Contracts include members inherited from base classes — the extends chain is resolved through relative imports, tsconfig path aliases and barrels. Before that resolver, 91 of 1298 monorepo contracts were flagged as partial; now 1 is.

Three caveats that travel with these numbers:

  • Tokens are counted through a proxy — OpenAI's o200k_base, since Claude's tokenizer is not public; cl100k_base agrees within one point on this data. Characters are exact.

  • The baseline is reading the whole file, which is what an agent does by default.

  • JSON tokenizes slightly worse than TypeScript, so token savings sit a point or two below character savings. The table carries both.

On small components there is no saving at all: a 17-line component produces a 578-character contract against a 315-character source. The contract grows with the number of members, the source with method bodies — and on production code the second wins almost always.

Measured: rename and diagnose

Renaming an input across usages. The grep path an agent actually takes — read the component file to learn the selector, then grep the selector and the binding spellings repo-wide — against ng_component_info plus ng_find_usages with its input filter, which returns only the tags that bind the name, each entry pointing at the binding itself. On the production monorepo, 6243 files scanned:

Component

grep path

bridge

saved (o200k)

577 usages, mask bound on 5 tags

50 527 tokens

1 035 tokens

98%

466 usages, icon bound on 463 tags

41 698 tokens

22 566 tokens

46%

1211 usages, name bound on 1134 tags

129 227 tokens

30 650 tokens

76%*

* the tool returns at most 500 entries per answer, and the answer says so.

The saving is decided by how many of the usages actually bind the input: mask is bound on 5 of 568 tags, and grep still prints every selector line plus 67 binding-shaped lines from across the repo — 62 of them somebody else's mask — while the bridge answers with exactly those five sites.

Diagnosing a template that will not compile. A whole-project compiler listing costs 395 tokens and 1321 ms; one ng_template_diagnostics call answers with the asked file's diagnostics in 81 tokens, 1 ms warm. The gap only widens with project size: the listing grows with the project, the answer does not. After an edit, fresh diagnostics arrive as a 340–400 ms push — against a rebuild.

Version facts

ng_version_rules contains no rule taken from documentation: the data comes from importing the packages actually installed in each fixture and from running the compiler.

The zoneless provider is renamed between v19 and v20.

API

v17

v18

v19

v20

v21

v22

provideExperimentalZonelessChangeDetection

yes

yes

provideZonelessChangeDetection

yes

yes

yes

Advice to "enable zoneless" without a version breaks on three majors out of six.

Existing is not the same as ready. The @experimental and @developerPreview tags live only in declaration JSDoc and are invisible at runtime:

API

v17

v18

v19

v20

v21

v22

input, output, model, viewChild, contentChild

preview

preview

stable

stable

stable

stable

effect, toObservable

preview

preview

preview

stable

stable

stable

linkedSignal, afterRenderEffect

preview

stable

stable

stable

resource, rxResource, httpResource

experimental

experimental

experimental

stable

So "rewrite @Input() as input()" on a v17 or v18 project means moving to a non-public API, and resource() was experimental all the way through v21. A batch of signal APIs appears exactly at v19: linkedSignal, resource, rxResource, httpResource, afterRenderEffect, provideAppInitializer.

Two documentation claims that measurement contradicted: standalone becomes the default at v19, not v20; and *ngIf is not removed in 22.0.8 — it reports hint NG6385 and keeps working, with NgIf still exported from @angular/common.

Compiler gates, read in the 22.0.8 bundle and confirmed by running it — all keyed on --angularCoreVersion, and with no version passed the newest semantics are assumed:

Feature

Gate

@if / @for / @switch blocks

≥ 17.0.0

signals in two-way bindings

≥ 17.2.0-0

@let

≥ 18.1.0

implicit standalone

≥ 19.0.0

DOM event type assertion

≥ 20.2.0

Also measured: Signal Forms (@angular/forms/signals) exist only from v21 and are stable on 22.0.8; AbstractControl.events from v18; TestBed.tick from v20.

Outside the measured v17–v22 range ng_version_rules returns nothing and says so — extrapolating "it was in v22, so it is in v23" is exactly the failure it exists to prevent.

Honesty as a feature

An incomplete answer says so, in words, inside the answer:

  • A contract merges base-class members and host-directive exposures, resolved statically through relative imports, tsconfig aliases and barrels. Where the walk cannot continue — a base class from a package, a mixin call — the answer carries incomplete, naming the class and the file to ask about next.

  • ng_version_rules reports notMeasured topics, and a caveat when your minor differs from the measured one.

  • ng_find_usages labels declarations as declaration, admits when class-name matches were found without resolving imports, and names selector twins — a second declaration of the same selector elsewhere in the workspace — instead of silently mixing their usages.

  • ng_template_diagnostics separates three states that all look like an empty list: the template is clean; the server is silently down (caught by a canary probe); or template checking is off for this project — then the answer carries checksDisabled naming the tsconfig responsible. In the measured monorepo strictTemplates is off in two of seven applications, so the distinction is not theoretical.

What this is not

  • Not better than a careful grep at finding usages. grep -rn "<app-widget" finds the same 62 usages. What ng_find_usages adds: the selector and class name are derived from the file for you, usage kinds are labelled, all four attribute-binding spellings are covered, and path scopes the scan — 33 selectors in the measured monorepo are declared in two applications at once, and an unscoped search would mix them.

  • Not a replacement for the Angular CLI MCP — a different layer. ng mcp covers docs, best practices and build orchestration; none of its nine tools touches templates or the language server. The two complement each other.

  • Not a type checker of its own. The LSP-backed tools deliver the project's own compiler output, undistorted.

Known gaps are recorded, not hidden: a base class from a package or behind a mixin call stops the ancestor walk (1 of 1298 components in the measured monorepo), Nx projects with inferred targets come without tsConfig, and pipe twins are not detected.

Requirements and setup

  • Node ≥ 18.20.8 — the measured floor: the published package answered on clean Node 18.20.8, 20.20.2 and 22.x. This is about the MCP server process only — your project keeps building on its own Node. To give just the server a newer runtime, point the client config at that binary: "command": "C:\\node22\\node.exe".

From source (instead of npm):

  • The project's own dependencies: npm install, then npm run build.

  • The shipped language-server branch lives in tools/servers/ls22 and needs npm ci there once.

  • In every client config, replace the ng-token-saver command with node <path>/dist/index.js; for Claude Code: claude mcp add ng-token-saver -- node <path>/dist/index.js.

node_modules folders are not committed, including the twelve inside the stand. To restore the full measurement environment:

npm install && npm run build
cd tools/servers/ls22 && npm ci        # the branch actually shipped
cd fixtures/v22 && npm ci              # repeat per fixture you want to run

Clients

The server is a plain stdio MCP server with no client-specific features, so any MCP client can launch it; installation and Claude Code registration are in Quick start.

Cursor — the one-click button in Quick start, or the same mcpServers JSON as in Quick start, in ~/.cursor/mcp.json (all projects) or .cursor/mcp.json (one project).

Windsurf — the same JSON, in ~/.codeium/windsurf/mcp_config.json.

VS Code (Copilot agent mode).vscode/mcp.json; the key is servers and the entry takes a type:

{ "servers": { "ng-token-saver": { "type": "stdio", "command": "ng-token-saver" } } }

Codex CLIcodex mcp add ng-token-saver -- ng-token-saver, or ~/.codex/config.toml:

[mcp_servers.ng-token-saver]
command = "ng-token-saver"

JetBrains AI Assistant / Junie — Settings → Tools → AI Assistant → Model Context Protocol accepts the same JSON as Quick start's; for Junie, additionally enable "Pass custom MCP servers".

Configuration, both variables optional:

  • NG_TOKEN_SAVER_IDLE_MS — a language-server session unused this long shuts its ngserver down; the next call pays the cold start again. Default 900000 (15 minutes); 0 keeps sessions alive until the server exits. A session with a call in flight is never shut down.

  • NG_TOKEN_SAVER_SERVERS_DIR — where the language-server branch lives, if not in tools/servers next to the build.

Reproducing the measurements

npm test                                  build plus 164 unit tests (node:test, no dependencies)
npm run smoke                             end-to-end check with a real MCP client over stdio
npm run bench:settle                      whether a pause after didOpen is needed (it is not)
npm run bench:standalone                  where standalone becomes the default (v17..v22)
npm run bench:api                         which Angular APIs exist in which majors, and their stability
npm run bench:contract <project root>     contract size against reading whole files (--tokens adds token counts)
npm run bench:rename <component> <input>  the grep path against the bridge for an input rename
npm run bench:diagnose                    a compiler listing against one diagnostics call
npm run bench:matrix                      resolution probes across a fixture
npm run bench:negative                    what the server returns when things break
npm run bench:didchange                   diagnostics timing after an edit

The stand is fixtures/v17..v22 — six real Angular workspaces, each with its own node_modules and its own pinned TypeScript, plus fixtures/negative/* for failure cases.

Status

All six tools verified on the six fixtures and on two production codebases — 1298 and 407 components, zero parse errors — plus one Angular 16 project to check that out-of-range refusals are structured rather than silent. 164 unit tests, all green.

Measured latency: the two LSP-backed tools pay 8–28 s of cold start on the first call and answer in 2–9 ms after it; the four static tools answer in 250–600 ms on the first call and in milliseconds once the project's TypeScript is cached. A session idle for 15 minutes shuts its language server down, and the next call pays the cold start again — see NG_TOKEN_SAVER_IDLE_MS above.

License

GPL-3.0-or-later — see LICENSE. Copyright (C) 2026 Alex Ryabov. Use and modify freely; derivative works must stay open under the same license.

Available Tools

6 tools
ng_component_infoAngular: component contractA

Public contract of a component or directive: inputs, outputs, class members, decorator metadata. Accepts .ts or .html. Reads the source; ngserver is not needed.

ParametersJSON Schema
NameRequiredDescriptionDefault
fileYesPath to the component (.ts) or to its template (.html)

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the burden of behavioral disclosure. It explicitly states 'Reads the source' indicating a read-only operation, and 'ngserver is not needed' describing a key dependency trait. This is valuable context beyond the schema, though it stops short of detailing error handling or return behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with the core purpose. The first sentence lists what the contract includes, and the second covers accepted inputs and a key behavioral note. Every sentence contributes value with no unnecessary detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter tool with no output schema, the description adequately covers purpose, input types, and a key behavioral trait (ngserver not needed). It is complete enough for an agent to understand what the tool does and when to invoke it, though it omits potential edge cases like file-not-found behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already fully describes the only parameter 'file' with 'Path to the component (.ts) or to its template (.html)', giving 100% coverage. The description repeats this by saying 'Accepts .ts or .html', adding little new meaning. Baseline 3 is appropriate since the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool provides the public contract of a component or directive, listing specific elements (inputs, outputs, class members, decorator metadata). This distinguishes it from sibling tools like ng_template_definition and ng_find_usages, making its purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives useful context: it accepts .ts or .html files and reads source without needing ngserver. However, it does not explicitly state when to choose this tool over alternatives or provide exclusion criteria, so the guidance is implied rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ng_find_usagesAngular: find usagesA

Usages of a component, directive, pipe or service across the workspace: elements, attribute selectors, pipes and class references. Accepts a file path or a selector.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathNoScope the search to this folder (a file means its folder); default is the whole workspace
inputNoOnly tag usages binding this input/output; entries then point at the binding
limitNoHow many usages to return, 100 by default
selectorOrFileYesPath to the declaring .ts, or the selector itself: app-user-card, [appDrag], money

TDQS

A3.5/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of disclosing behavioral traits. It states what the tool searches for and that it accepts a file path or selector, but it does not disclose whether the operation is read-only, how results are returned, whether it follows workspace boundaries, or any performance or permission implications. For a search tool, the lack of a clear read-only guarantee or output format disclosure is a notable gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, well-structured sentence that front-loads the core function before listing supported types and input formats. Every clause adds useful information, with no filler, redundancy, or unnecessary detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description effectively covers the tool's purpose and input format, which is essential. However, because there is no output schema, the description should ideally explain what a usage result looks like (e.g., file locations, line numbers, snippets). This information is absent, leaving the agent to guess the return structure. The presence of configurable parameters like limit and input adds behavioral nuance not explained in the description.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all four parameters. The description adds only a high-level summary ('Accepts a file path or a selector') that mirrors selectorOrFile's schema description. It provides no additional meaning beyond the schema, so the score stays at the baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: finding usages of components, directives, pipes, or services across the workspace. It names specific resource types and explicitly mentions the two input forms (file path or selector), making both the action and scope unmistakable. This distinguishes it from sibling tools that address other Angular concerns.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the intended use — when you need to locate usages of a symbol — and states the accepted input formats. However, it does not explicitly contrast this with sibling tools like ng_component_info or ng_template_definition, nor does it mention when not to use it. There is no alternative guidance beyond the obvious purpose.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ng_template_definitionAngular: declaration of a template symbolA

From a position in an Angular template (.html or inline in .ts) to its TypeScript declaration. line and character are 0-based, as in LSP.

ParametersJSON Schema
NameRequiredDescriptionDefault
fileYesPath to the template: .html, or .ts with an inline template
lineYes
characterYes

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the burden of behavioral disclosure. It adds useful context about 0-based line/character coordinates and support for .html or inline .ts templates, but it does not disclose what happens when no declaration is found, the return format, or any error behavior. This is a moderate gap for a tool with no annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no wasted words. It efficiently communicates the core transformation and coordinate convention without extraneous information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is relatively simple, but the absence of an output schema means the description should explain what the caller receives (e.g., declaration location, range, or null). It also doesn't mention edge cases like invalid positions or unresolved symbols. Given these gaps and the existence of sibling tools, the description is not fully complete, though it covers the essential purpose and input semantics.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is low (33% — only 'file' has a description). The description compensates by clarifying the 0-based LSP-compatible semantics of line and character, and by specifying valid file types (.html or .ts with inline template). This adds meaningful value beyond the schema, though the description doesn't detail file path formats.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: mapping a position in Angular template files (.html or inline .ts) to its TypeScript declaration. This specific verb-resource pairing distinguishes it from sibling tools like ng_find_usages (usages) and ng_template_diagnostics (diagnostics).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage through the title 'declaration of a template symbol' and by describing the input position, but it does not explicitly state when to choose this tool over alternatives, nor does it mention any exclusions or prerequisites. Usage guidance is understood but not stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ng_template_diagnosticsAngular: template errorsC

Angular compiler errors for a template after an edit. Accepts .html or .ts; files checks a batch. An entry anchored in the companion file names it in file. An empty list means "no errors" only when the server is healthy.

ParametersJSON Schema
NameRequiredDescriptionDefault
fileNoPath to the template or to the component
filesNoBatch of up to 20 templates; the answer groups diagnostics per file

TDQS

C2.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden of behavioral disclosure. It adds valuable caveats about the empty list meaning 'no errors' only when the server is healthy and hints at output structure via 'entry anchored in the companion file'. However, it does not explain side effects, required permissions, or error conditions beyond server health.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness2/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is short but poorly written. Phrases like 'files checks a batch' are ungrammatical, and 'An entry anchored in the companion file names it in file' is cryptic and adds confusion rather than clarity. The useful 'server healthy' caveat is buried in an unclear sentence.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema and no annotations, the description is insufficient to fully understand the tool's behavior. It lacks details on the response format, error listing structure, or what happens when both 'file' and 'files' are omitted. The tool is a diagnostic tool with moderate complexity, but the description does not adequately cover it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description supplements the schema by stating accepted file extensions (.html or .ts) and that 'files' handles batch checks. Since schema coverage is 100%, this extra context is helpful but not extensive; it does not clarify parameter precedence or batch limits.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening phrase 'Angular compiler errors for a template after an edit' clearly indicates the tool reports compiler diagnostics for templates. This differentiates it from sibling tools like ng_component_info or ng_find_usages, though the rest of the description is grammatically confusing.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No explicit guidance on when to use this tool versus alternatives is provided. The phrase 'after an edit' implies a context, but there is no mention of when not to use it or how it compares to sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ng_version_rulesAngular: rules for the project versionB

What exists and what does not in this project's Angular version: template syntax, signal APIs, zoneless, DI. Every rule was measured on the v17-v22 stand.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathNoAny file or folder inside the workspace; defaults to the working directory
topicNoNarrow the answer to one topic

TDQS

B3.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden for behavioral disclosure. It only adds that 'Every rule was measured on the v17-v22 stand', which hints at reliability but does not clarify core behaviors: whether the tool is read-only, how it analyzes the project, or what happens for versions outside v17-v22. No mention of side effects, required permissions, or return format.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is short, with two sentences and no fluff. The first sentence front-loads the core purpose. The second sentence, however, uses the vague phrase 'measured on the v17-v22 stand', which may confuse readers; it earns a minor penalty for clarity while remaining concise overall.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description should help infer why the result is useful. The text gives a general sense of what the tool reports (existence/non-existence of features) but does not specify the format or granularity of the answer. For a simple query tool with optional parameters, this is minimally complete but not fully transparent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the parameters are fully documented in the input schema. The description enriches the topic parameter by listing examples (template syntax, signals, DI) but not all enum values (components, control-flow, forms, testing). It does not add details about the path parameter beyond the schema. Thus it meets the baseline but does not significantly exceed it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the resource (the project's Angular version) and the general purpose ('what exists and what does not') while naming specific areas (template syntax, signal APIs, zoneless, DI). This distinguishes it from sibling tools that focus on component info, templates, diagnostics, workspace mapping, or usage finding. However, it lacks a strong imperative verb like 'list' or 'check', making it slightly less crisp than an ideal purpose statement.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage when one needs to know whether an Angular feature is available in the project's version, but it does not explicitly state when to use this tool instead of alternatives. It also does not mention exclusions or complementary tools. Since the need is inferable from the phrasing, it earns a midpoint score.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ng_workspace_mapAngular: workspace mapA

Workspace projects, Angular/CLI/TypeScript versions, strictTemplates and zone.js per project. Understands angular.json, Nx and solution style. Call once per session.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathNoAny file or folder inside the workspace; defaults to the working directory

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden. It explains that the tool understands multiple workspace configurations and lists the information it provides, but it does not disclose return format, side effects, or why it should only be called once per session. The 'Call once per session' hint implies caching or heaviness, but lacks detail.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise sentences with no fluff. The first sentence lists the core content, the second adds context about config styles and usage frequency. All information is relevant and front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has no output schema, but the description enumerates the main data categories (projects, versions, strictTemplates, zone.js) and config styles. For a read-only mapping tool with a single optional parameter, this adequately sets expectations. It could benefit from stating return shape, but the sibling tools make the use case clear.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% (the single optional path parameter is fully described). The description adds no parameter-specific information, so baseline 3 is appropriate. The path meaning is already clear from the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states what the tool provides: workspace projects, versions, strictTemplates, and zone.js per project. It doesn't use an explicit verb like 'lists' or 'returns', but the noun-phrase structure conveys the resource and scope. It implicitly distinguishes from sibling tools by focusing on workspace-level overview rather than component/template specifics.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The instruction 'Call once per session' provides explicit usage guidance. Mentioning that it understands angular.json, Nx, and solution style indicates when it is applicable. It does not explicitly state when not to use or name alternatives, but the guidance is sufficient for this simple tool.

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.

  1. 6 tool updatesv0.1.7
    • First observedng_component_info
    • First observedng_find_usages
    • First observedng_template_definition
    • First observedng_template_diagnostics
    • First observedng_version_rules
    • First observedng_workspace_map

TDQS

A3.8/5.0

Scored across 6 tools

Disambiguation5/5

Each tool targets a distinct aspect of Angular development: component metadata, template positions, template diagnostics, workspace configuration, version-specific rules, and cross-reference usages. There is no overlap or ambiguity between them.

Naming Consistency5/5

All tools follow a consistent 'ng_' prefix with snake_case names that clearly indicate their purpose. The naming pattern is uniform across all six tools, making it easy to predict tool functionality from the name alone.

Tool Count5/5

With exactly six tools, the server is appropriately scoped for Angular code analysis. Each tool serves a distinct purpose without redundancy, and the count is within the ideal range.

Completeness5/5

The tool set covers the core workflows for Angular analysis: understanding components, navigating from templates to definitions, checking diagnostics, mapping workspace structure, understanding version features, and finding usages. Minor gaps like batch processes are addressed by the batch capability in diagnostics, and the set feels complete for a read-only analysis server.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    A Model Context Protocol server that provides Angular project analysis and refactoring capabilities, enabling LLMs to analyze component usage patterns, dependency structures, and perform safe refactoring with breaking change detection.
    4
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    A TypeScript-aware MCP server that provides coding agents with repository discovery, code intelligence, and web project context for local codebases. It enables deep symbol navigation, diagnostic reporting, and structural analysis of monorepos without requiring full IDE integration.
    7
    5 npm
    1
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    An MCP server that provides structure-aware code analysis (symbol trees, dependencies, docs) to reduce AI agent token consumption by up to 99%, along with Git commit intelligence.
    MIT