Audience: Backend & tool authors who need to understand how the MCP server is wired together so they can extend it with new tools, prompts, or transports.
The Angular MCP Server is a Node.js process that wraps the generic Model Context Protocol SDK and exposes Angular-specific analysis & refactoring tools.
It follows a clean, layered design:
- Transport & Core (MCP SDK) – HTTP/SSE transport, request routing, JSON-schema validation.
- Server Wrapper (
AngularMcpServerWrapper) – registers prompts, tools, and resources; injects workspace-specific paths. - Tools Layer (
src/lib/tools/**) – thin adapters delegating to shared analysis libraries. - Shared Libraries (
packages/shared/**) – AST utilities, DS coverage, generic helpers.
graph TD
subgraph Editor / LLM Client
A[CallTool / ListTools] -->|HTTP + SSE| B(McpServer Core)
end
B --> C{Request Router}
C -->|tools| D[Tools Registry]
C -->|prompts| E[Prompts Registry]
C -->|resources| F[Resources Provider]
D --> G[Individual Tool Handler]
G --> H[Shared Libs & Workspace FS]
- The client sends a
CallToolrequest. McpServervalidates the request against JSON Schema.AngularMcpServerWrapperroutes it to the correct handler inside Tools Registry.- The handler performs analysis (often via shared libs) and returns structured content.
- The response streams back.
- CLI Invocation (see
.cursor/mcp.json):node packages/angular-mcp/dist/main.js --workspaceRoot=/abs/path ...
main.ts→AngularMcpServerWrapper.create()- Config Validation (
AngularMcpServerOptionsSchema) – checks absolute/relative paths. - File Existence Validation – ensures Storybook docs & DS mapping files are present.
- Server Setup – registers capabilities & calls:
registerPrompts()registerTools()registerResources()
- Server starts listening.
packages/angular-mcp-server/
src/
lib/
angular-mcp-server.ts # Wrapper class (core of the server)
tools/
ds/ # DS-specific tool categories
shared/ # Internal helpers
prompts/ # Prompt schemas & impls
validation/ # Zod schemas & file checks
index.ts # Re-export of wrapper
| Extension | Where to Add | Boilerplate |
|---|---|---|
| Tool | src/lib/tools/** |
1. Create my-awesome.tool.ts exporting ToolsConfig[]. 2. Add it to the export list in tools/ds/tools.ts (or another category). |
| Prompt | prompts/prompt-registry.ts |
1. Append schema to PROMPTS. 2. Provide implementation in PROMPTS_IMPL. |
| Resource Provider | registerResources() |
Extend logic to aggregate custom docs or design-system assets. |
All tools share the ToolsConfig interface (@push-based/models) that bundles:
schema(name, description, arguments, return type)handler(request)async function.
The MCP SDK auto-validates every call against the schema – no manual parsing required.
| Option | Type | Description |
|---|---|---|
workspaceRoot |
absolute path | Root of the Nx/Angular workspace. |
ds.storybookDocsRoot |
relative path | Path (from root) to Storybook MDX/Docs for DS components. |
ds.deprecatedCssClassesPath |
relative path | JS file mapping components → deprecated CSS classes. |
ds.uiRoot |
relative path | Folder containing raw design-system component source. |
ds.generatedStylesRoot |
relative path | Directory containing generated design token CSS files. Enables token-aware features when provided. |
These options control how design tokens are discovered, organised, and categorised. All have defaults and are only relevant when ds.generatedStylesRoot is configured.
| Option | Type | Default | Description |
|---|---|---|---|
ds.tokens.filePattern |
string | **/semantic.css |
Glob pattern to discover token files inside generatedStylesRoot. |
ds.tokens.propertyPrefix |
string | null | null |
When set, only properties starting with this prefix are loaded into the token dataset. Note: setting this to a single prefix (e.g. --semantic-) means the report-audit-token-usage tool will only validate and detect overrides for tokens matching that prefix. Leave as null to load all tokens and let the tool derive all prefixes automatically (e.g. --semantic- and --ds-). |
ds.tokens.scopeStrategy |
enum | flat |
flat or brand-theme. Controls how directory structure maps to token scope metadata. flat: no scope. brand-theme: path segments → brand/theme scope keys. |
ds.tokens.categoryInference |
enum | by-prefix |
by-prefix, by-value, or none. Controls how tokens are assigned categories. |
ds.tokens.categoryPrefixMap |
Record | { color: '--semantic-color', ... } |
Category → prefix mapping (used with by-prefix). |
Validation is handled via Zod in angular-mcp-server-options.schema.ts.
The token dataset stores one flat array of all loaded TokenEntry objects. At construction time, four index maps are built from that array for efficient lookups:
| Index | Type | Behaviour |
|---|---|---|
byName |
Map<name, TokenEntry> |
Last-write-wins — only one entry per token name. When the same token appears in multiple brand files, only the last processed entry is kept. |
byValue |
Map<value, TokenEntry[]> |
All entries with that resolved value are kept. Enables reverse-lookup ("which tokens resolve to #86b521?"). |
byCategory |
Map<category, TokenEntry[]> |
All entries in that category are kept. |
byScopeKey |
Map<scopeKey, Map<scopeValue, TokenEntry[]>> |
All entries matching a scope dimension are kept. Enables scoped queries like "all tokens where brand = acme". |
For example, if --semantic-color-primary appears in 30 brand files with different values, the tokens array has 30 entries. byValue and byScopeKey keep all 30. byName only keeps the last one processed.
models (types & schemas)
├─ utils
├─ styles-ast-utils
│ └─ scss-value-parser (extracts property-value pairs per selector from SCSS)
├─ angular-ast-utils
└─ ds-component-coverage (top-level plugin)
The angular-mcp-server package also contains shared token infrastructure:
tools/ds/shared/utils/
├─ css-custom-property-parser.ts (regex-based CSS --* extraction)
├─ token-dataset.ts (queryable token data structure)
├─ token-dataset-loader.ts (file discovery, scope, categorisation)
└─ regex-helpers.ts (shared regex patterns)
These libraries provide AST parsing, file operations, token loading, and DS analysis. Tools import them directly; they are framework-agnostic and can be unit-tested in isolation.
packages/minimal-repo/** contains miniature Angular apps used by unit/integration tests. They are not part of production code but useful when debugging a new tool.
- Identify functionality and pick/create an appropriate shared library function.
- Generate a JSON-schema with arguments & result shape (can use Zod helper).
- Implement handler logic (avoid heavy FS operations in main thread; prefer async).
- Export via
ToolsConfig[]and append to category list. - Write unit tests.
- Update
docs/tools.mdonce published.