@expressivecss/mcp-server 0.2.2 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "expressivecss-mcp",
3
3
  "displayName": "ExpressiveCSS MCP",
4
- "version": "0.2.2",
4
+ "version": "0.3.1",
5
5
  "description": "ExpressiveCSS workflow server with Setup Expert, Rules Enforcer, Creative Director, Page Arcjitect, Component Syntax Expert, and Quality Inspector.",
6
6
  "author": {
7
7
  "name": "BaezFJ",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "expressivecss-mcp",
3
3
  "displayName": "ExpressiveCSS MCP",
4
- "version": "0.2.2",
4
+ "version": "0.3.1",
5
5
  "description": "ExpressiveCSS workflow server with Setup Expert, Rules Enforcer, Creative Director, Page Arcjitect, Component Syntax Expert, and Quality Inspector.",
6
6
  "author": {
7
7
  "name": "BaezFJ",
package/CHANGELOG.md CHANGED
@@ -1,5 +1,96 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.1 - 2026-10-08
4
+
5
+ - Fix `npx @expressivecss/mcp-server`, which failed with "could not determine
6
+ executable to run" from 0.2.0 onward because the package has two bins. A
7
+ `mcp-server` bin now starts the server, so the documented client config works.
8
+ The `expressivecss-mcp` bin is unchanged.
9
+ - The server and `expressivecss-lint` start about 0.3 s faster. jsdom now loads
10
+ the first time a check inspects markup instead of at startup.
11
+ - The catalogue, guides and rules cover 29 more components: accordion, aura,
12
+ avatar, the eight chart types, command palette, countdown, data table,
13
+ drop zone, empty state, KPI, marquee, message, message scroller, popover,
14
+ questionnaire, rating, rich text editor, skeleton, stat, stepper, timeline
15
+ and tree.
16
+ - Bundled framework guidance: ExpressiveCSS 0.13.1.
17
+
18
+ ## 0.3.0 - 2026-10-06
19
+
20
+ - Breaking: guidance tools now cap each result at 64 KiB of UTF-8 by
21
+ default. A response that used to arrive whole can now omit whole
22
+ units and list them in `responseBudget`. To return larger responses, set
23
+ `EXPRESSIVECSS_MCP_MAX_RESPONSE_BYTES` in the server's environment. The
24
+ limit is described in its own entry below.
25
+
26
+ - Add argument completion to the component resource templates. Both templates
27
+ complete canonical slugs by case-insensitive prefix, and
28
+ `component_guide_section` also completes section names. Aliases are not
29
+ matched. Results use the SDK limit of 100 values with `total` and `hasMore`.
30
+ Unknown template references return `-32602`. Completion reads only the
31
+ bundled catalogue and stays outside the response byte budget. Tool arguments
32
+ are not completed.
33
+
34
+ - Add versioned component guide resources for the current bundled snapshot.
35
+ The `component_guide` template returns a whole guide with its complete
36
+ contract, syntax, rules, Options and Methods. `component_guide_section`
37
+ returns one of those sections. `resources/list` lists every whole-guide URI.
38
+ Reads share the operator byte budget and deliver sections whole. A read that
39
+ cannot fit returns `-32001` with the section URIs that fit and the sections
40
+ that need a larger budget. Aliases, unknown names and unavailable snapshot
41
+ identities return `-32002`. Budget errors now name the URI that was read.
42
+
43
+ - Add a read-only `component_catalog` resource for the current bundled snapshot,
44
+ identified by framework version and contract source hash. JSON contents reuse
45
+ the complete compact catalogue and retain unknown consumer compatibility.
46
+ Reads use the existing operator byte budget and deliver every entry whole or
47
+ return protocol error `-32001` with a sufficient restart budget. Discovery
48
+ remains available under small budgets; unknown resource identities return
49
+ `-32002`. Existing tools, QA policy and package versions remain unchanged.
50
+
51
+ - Guidance tools enforce a configurable 64 KiB UTF-8 limit on the complete
52
+ serialized tool result, including text and structured content. Typed
53
+ `responseBudget` metadata accounts for whole-unit omissions and narrower
54
+ recovery requests. Indivisible guidance or accounting that cannot fit produces
55
+ an explicit budget error; impossible minimal results use JSON-RPC error
56
+ `-32001`. Setup, creative, both page aliases, syntax and catalogue share the
57
+ limit; QA limits and evidence behavior remain unchanged. Syntax code is whole
58
+ or omitted, and retained contract-prose limits have explicit disclosure.
59
+
60
+ - `component_syntax_expert` accepts `detail: "compact"` or `"detailed"`, with
61
+ detailed as the backward-compatible default. Compact retains complete rules,
62
+ identity and shared evidence while omitting contract prose and syntax examples.
63
+ Requested Options/Methods and explicit foundations work in both modes.
64
+ `includeCapabilities` overrides component capability detail, which defaults
65
+ off in compact and on in detailed. Effective selectors and schema-validated
66
+ `omittedFields` identify intentional omissions and their reasons. Retrieve
67
+ omitted detail through the supported selectors. Existing version/provenance
68
+ safety checks remain. Contract summaries retain their disclosed prose limit;
69
+ examples now use whole delivery or explicit budget omission.
70
+
71
+ - `component_catalog` accepts optional `query` and `limit` to search existing
72
+ names, aliases and compact descriptions. Exact matches precede labelled
73
+ heuristic matches. Search defaults to 10 results, permits at most 50 and
74
+ reports total/omitted counts, truncation and explicit empty results. Full
75
+ listings and compatibility/provenance evidence remain unchanged.
76
+
77
+ - Add read-only `component_catalog` for complete compact component listings,
78
+ existing aliases and runtime ownership, documentation links and bundled
79
+ version/source hash. Optional explicit targets receive compatibility and
80
+ provenance checks; omitted targets remain unchecked.
81
+
82
+ - `component_syntax_expert` accepts `sections: ["methods"]` or both `"options"`
83
+ and `"methods"` once each. Requested Methods return complete bundled Markdown
84
+ or an explicit absent-section record. Defaults and compatibility/provenance
85
+ evidence remain unchanged.
86
+ - `component_syntax_expert` accepts `sections: ["options"]` to return complete
87
+ bundled Options Markdown or an explicit absent-section record. Existing
88
+ requests omit these records; compatibility and provenance evidence are unchanged.
89
+ - `component_syntax_expert` returns complete component rules in source order,
90
+ including rules previously omitted by the eight-rule cap. Generic fallback
91
+ advice remains unchanged.
92
+ - Bundled framework guidance: ExpressiveCSS 0.12.0.
93
+
3
94
  ## 0.2.2 - 2026-10-01
4
95
 
5
96
  - Semantics findings from `rules_enforcer`, `quality_inspector`, and
package/README.md CHANGED
@@ -11,11 +11,215 @@ This folder contains a self-hosted MCP server for the ExpressiveCSS design-to-QA
11
11
 
12
12
  The server bundles generated component guides, selection data, contract metadata, and the normative semantics data. All component guidance comes from this synchronized package data. A framework source checkout contributes only target-version and contract-provenance evidence, so local prose cannot replace the packaged guidance.
13
13
 
14
+ `component_syntax_expert` returns every rule from each found component's bundled Rules section, in source order. Guides without rule bullets retain generic authoring advice. Looking up rules does not establish component-rule conformance.
15
+
16
+ ## Selectable syntax detail
17
+
18
+ `detail` accepts `"compact"` or `"detailed"` and defaults to `"detailed"`.
19
+ Existing request forms and defaults remain valid. Both modes retain complete
20
+ rules for delivered components, identity, sources, lookup results and shared
21
+ compatibility/provenance evidence. The aggregate budget below can omit whole
22
+ fields or components with explicit accounting.
23
+
24
+ | Component field | Compact | Detailed |
25
+ | --- | --- | --- |
26
+ | `file`, `slug`, `title`, `source`, `docs`, `rules` | Included | Included |
27
+ | `contract`, `syntax` | Omitted | Contract summary and whole syntax example, subject to budget |
28
+ | `options`, `methods` | Included only when requested through `sections` | Same |
29
+ | `capability` | Omitted by default | Included by default |
30
+
31
+ The optional boolean `includeCapabilities` overrides the component capability
32
+ default in either mode. Explicit `sections` requests work in both modes and
33
+ retain complete documented Markdown or explicit absence. Explicit `foundations`
34
+ requests remain effective even with `includeCapabilities: false`; that selector
35
+ controls only component capability records.
36
+
37
+ ```json
38
+ {
39
+ "components": ["date-picker", "autocomplete"],
40
+ "detail": "compact",
41
+ "sections": ["options", "methods"],
42
+ "includeCapabilities": true
43
+ }
44
+ ```
45
+
46
+ Ordinary results report effective `detail` and `includeCapabilities`. Each found
47
+ component adds `omittedFields`, with one record per intentionally omitted field:
48
+
49
+ ```json
50
+ {
51
+ "field": "syntax",
52
+ "reason": "compact-detail"
53
+ }
54
+ ```
55
+
56
+ Fields are reported in `contract`, `syntax`, `options`, `methods`, `capability`
57
+ order. Compact prose/example omissions use `compact-detail`. Unrequested API
58
+ sections and disabled component capability detail use `not-requested`. Requested
59
+ API records with `status: "absent"` and included null capability records are
60
+ delivered results, so they have no omission record. The syntax output schema
61
+ validates selector values and omission fields/reasons. Byte omissions use
62
+ `byte-budget`. A contract summary longer than 900 characters reports
63
+ `length-limit`, with its shortened prose still present. A disabled syntax tool
64
+ retains its shared blocked envelope and budget metadata without retrieval fields.
65
+
66
+ Recover omitted prose/examples with `detail: "detailed"`, API sections with
67
+ `sections`, and component capability records with `includeCapabilities: true`.
68
+ Version/provenance checks still block unsafe capability data. Detail selection
69
+ does not change compatibility or missing-name lookup. Budget omissions make
70
+ delivery partial or erroneous. Text and structured content describe the same result.
71
+
72
+ Detailed output retains the contract summary limit of 900 characters with
73
+ explicit disclosure. Read the linked component documentation for full contract
74
+ prose; increasing the byte budget does not remove this summary limit. Syntax
75
+ examples, rules and requested API sections are whole or explicitly omitted.
76
+ Generic fallback advice remains nonnormative, and retrieval does not verify
77
+ consumer interaction, visual or accessibility behavior.
78
+
79
+ ## Aggregate response budget and recovery
80
+
81
+ `EXPRESSIVECSS_MCP_MAX_RESPONSE_BYTES` defaults to 65,536 bytes, or 64 KiB.
82
+ Set it in the server's environment to a positive safe integer in decimal digits.
83
+ Empty values, zero, signed numbers, fractions, whitespace, exponents and unsafe
84
+ integers fail startup. Clients cannot override this operator setting.
85
+
86
+ The budget applies to `setup_expert`, `creative_director`, `page_architect`,
87
+ `page_arcjitect`, `component_syntax_expert` and `component_catalog`, including
88
+ disabled-tool and SDK validation-error results. `rules_enforcer` and
89
+ `quality_inspector` retain their existing QA limits and evidence behavior.
90
+ The [catalogue resource](#versioned-catalogue-resource) and
91
+ [component resources](#versioned-component-resources) use the same setting to
92
+ bound successful resource-read results, with complete delivery or a protocol
93
+ error. Discovery lists are outside the content budget.
94
+
95
+ The exact measurement is `Buffer.byteLength(JSON.stringify(result), 'utf8')`.
96
+ It counts the entire wire tool-result object, including JSON escapes, text,
97
+ structured content, metadata and `isError`. These tools use compact JSON text
98
+ and duplicate the same payload in structured content. The outer JSON-RPC
99
+ envelope and stdio framing are excluded. A final transport check covers errors
100
+ the SDK creates before or after a handler runs.
101
+
102
+ Affected structured results add `responseBudget`:
103
+
104
+ | Field | Meaning |
105
+ | --- | --- |
106
+ | `maxBytes` | Effective operator budget. |
107
+ | `delivery` | `complete`, `partial` or `error` for the requested projection. |
108
+ | `omissions` | Every byte-omitted unit, with its identity, `reason: "byte-budget"` and recovery index. |
109
+ | `recoveries` | Typed retry requests or advice to increase the operator budget. |
110
+
111
+ Syntax omission identities include original request position and name, canonical
112
+ slug when known and field when applicable. Delivered components have
113
+ `requestIndex` for repeated or mixed known/unknown requests. Selector omissions
114
+ remain in `found[].omittedFields`; budget omissions also identify fields there.
115
+ Unknown components, absent API sections and blocked capabilities retain their
116
+ existing distinct meanings. `foundCount` and catalogue `count` count only
117
+ delivered records.
118
+
119
+ Reduction is deterministic. Syntax drops whole optional capability records,
120
+ contract summaries and examples before whole requested Options/Methods, then
121
+ whole components and foundations. It works backwards through each collection
122
+ so retained records preserve their original order. A delivered component always
123
+ retains all its rules in source order. Catalogue and creative reductions remove
124
+ whole trailing entries while preserving ranking. Page architecture and its
125
+ skeleton are indivisible. Setup checks can fail explicitly when they cannot fit.
126
+ Compatibility, provenance, performed checks and evidence limits remain truthful.
127
+ Budget omissions never imply complete coverage or browser approval.
128
+
129
+ For `delivery: "partial"`, execute a referenced recovery request:
130
+
131
+ ```json
132
+ {
133
+ "action": "retry",
134
+ "request": {
135
+ "name": "component_syntax_expert",
136
+ "arguments": {
137
+ "projectRoot": "/absolute/path/to/project",
138
+ "workflowId": "example-workflow",
139
+ "components": ["autocomplete"],
140
+ "detail": "compact",
141
+ "includeCapabilities": false,
142
+ "sections": ["methods"]
143
+ }
144
+ }
145
+ }
146
+ ```
147
+
148
+ Catalogue recovery uses an exact slug query with `limit: 1`, preserving any
149
+ explicit target. It omits the optional workflow correlation ID because
150
+ catalogue retrieval has no workflow state. Search-limit omissions and byte
151
+ omissions have separate accounting. Catalogue tool recovery adds no pagination
152
+ and does not require resource support in the client.
153
+
154
+ Creative recovery reranks a concise goal naming the omitted component with
155
+ `maxSuggestions: 1`, preserving target and workflow context. Ranking scores and
156
+ explanations can change with the narrower goal. The server offers this request
157
+ only when it returns the named suggestion whole within the same budget.
158
+
159
+ If an indivisible unit or the complete omission accounting cannot fit,
160
+ `delivery: "error"` and `isError: true` advise an operator budget increase.
161
+ Error results can retain whole reference records but make no successful-delivery
162
+ claim. If even a minimal truthful result with essential evidence cannot fit,
163
+ the server returns JSON-RPC error `-32001` with no tool-result object. The
164
+ protocol error envelope is outside the tool-result budget. Do not retry that
165
+ failure expecting same-budget success. Increase the server setting and restart,
166
+ then repeat the request. A budget of 1 is valid and exercises this failure path.
167
+
168
+ ## Requested runtime API sections
169
+
170
+ To request documented runtime Options, add `sections: ["options"]`:
171
+
172
+ ```json
173
+ {
174
+ "components": ["date-picker", "cards"],
175
+ "sections": ["options"]
176
+ }
177
+ ```
178
+
179
+ Each found component adds an `options` record. A documented section returns
180
+ `{ "status": "documented", "markdown": "..." }` with its complete bundled Markdown
181
+ body, including tables and nested guidance. Datepicker includes its visibility
182
+ and docked-display options. A missing or empty section returns
183
+ `{ "status": "absent", "markdown": null }`; this means the bundled guide has no
184
+ documented Options section, not that the component has no configuration.
185
+ Cards is one such guide.
186
+
187
+ To request documented runtime Methods, use `sections: ["methods"]`. Select both
188
+ sections with `sections: ["options", "methods"]`:
189
+
190
+ ```json
191
+ {
192
+ "components": ["autocomplete", "cards"],
193
+ "sections": ["options", "methods"]
194
+ }
195
+ ```
196
+
197
+ Each found component adds a `methods` record when selected. Documented Methods
198
+ return their complete bundled Markdown in the same `{ "status": "documented",
199
+ "markdown": "..." }` shape. Autocomplete includes `.destroy()` and its cleanup
200
+ guidance. A missing or empty Methods section returns `{ "status": "absent",
201
+ "markdown": null }`. This describes the guide's documentation; it does not
202
+ establish that the runtime has no methods. Cards reports absence.
203
+
204
+ Existing requests such as `{ "components": ["date-picker"] }` retain their fields.
205
+ Omitting `sections` or using `sections: []` omits both optional records. Options-only
206
+ selection omits `methods`; Methods-only selection omits `options`. The selector
207
+ accepts either supported name once, or both in either order with the same result.
208
+ Unknown names, duplicate entries and arrays over two entries are rejected.
209
+ Component and foundation request limits remain unchanged. Unknown component names
210
+ keep their existing `missing` result.
211
+
212
+ Requested Options and Methods remain bundled reference data when target-version or
213
+ provenance checks block a result. They do not change compatibility, capability
214
+ evidence or availability, and do not verify runtime or accessibility behavior.
215
+
14
216
  A resolved version matching the bundled contract reports `documentationMode: "bundled"` and `bundledContractSafe: true`. `documentationSources.bundled` identifies the contract version and source hash. This resolver does not verify the public website, so `currentDocsSafe` and `documentationSources.current.available` remain false even on a match. Use matching bundled guidance, installed sources, or a proven release tag for version-specific claims.
15
217
 
16
218
  ## Material capability evidence
17
219
 
18
- `component_syntax_expert` adds a scoped `capability` record to each found component.
220
+ `component_syntax_expert` adds a scoped `capability` record to each found component
221
+ when component capability detail is enabled. Detailed mode enables it by default;
222
+ compact mode omits it by default. `includeCapabilities` overrides either default.
19
223
  For foundations, pass `foundations: ["typography", "shape", "motion"]`; component
20
224
  names are optional for this request. Results distinguish documented scope,
21
225
  pinned source review, feature/integration gaps, mapped checks and recorded results.
@@ -29,6 +233,276 @@ does not rerun tests or re-review sources. The optional Markdown
29
233
  [roadmap](https://github.com/BaezFJ/ExpressiveCSS/blob/master/skills/expressivecss/references/capability-roadmap.md) and packaged
30
234
  `capability-roadmap.json` come from the same catalogue.
31
235
 
236
+ ## Component catalogue
237
+
238
+ Call `component_catalog` with `{}` to list every component in the server's
239
+ current bundle. No design goal or component name is required. To also check a
240
+ consumer project, supply an explicit target:
241
+
242
+ ```json
243
+ { "projectRoot": "/absolute/path/to/consumer" }
244
+ ```
245
+
246
+ An optional `workflowId` associates the result with other tool calls. `entries`
247
+ are sorted by canonical `slug`, and `count` reports their total. Each entry has:
248
+
249
+ | Field | Source and meaning |
250
+ | --- | --- |
251
+ | `slug`, `title` | Canonical guide name and title. Pass the slug to `component_syntax_expert`. |
252
+ | `description` | First nonempty decision `useWhen` string, then `jobs`, or null. |
253
+ | `aliases` | Existing decision aliases, or an empty array. These describe the component; they do not extend exact syntax lookup. |
254
+ | `runtime` | Existing runtime ownership value, or null. |
255
+ | `docs` | Bundled guide's documentation link, or null. |
256
+
257
+ The result includes `contractVersion`, `sourceHash` and `guideSource: "bundled"`
258
+ to identify the shipped snapshot. It contains compact metadata, with no full
259
+ syntax, rules, runtime API sections or capability records. Retrieve guidance
260
+ through `component_syntax_expert`. Listing includes component guides only;
261
+ foundation guidance remains available through that tool's `foundations` selector.
262
+
263
+ Without `projectRoot`, listing reports `status: "available"` and
264
+ `contractCompatibility: "unknown"`. It does not inspect the working directory
265
+ or a CLI project-root default. `contractProvenance: "bundled-verified"` concerns
266
+ the packaged snapshot, and `uncheckedAreas` names target compatibility and
267
+ provenance as unperformed checks. With an explicit target, existing version and
268
+ provenance checks can return `status: "blocked"`. The complete reference entries
269
+ remain available with the same bundled version and hash.
270
+
271
+ `coverageStatus: "complete-bundled-catalogue"` describes delivery of all entries.
272
+ It does not establish consumer compatibility, browser behavior or accessibility
273
+ approval. Calls are read-only and execute no project scripts.
274
+
275
+ ### Search the catalogue
276
+
277
+ Supply `query` to search canonical slugs, titles, aliases and compact descriptions:
278
+
279
+ ```json
280
+ { "query": "navbar", "limit": 1 }
281
+ ```
282
+
283
+ This discovers `app-bar` with `matchType: "exact-alias"`. Pass the returned
284
+ canonical slug to `component_syntax_expert`; search does not expand that tool's
285
+ alias lookup. Search also accepts exact names such as `app-bar` and descriptive
286
+ queries such as `screen-level actions`.
287
+
288
+ `query` accepts at most 256 characters before trimming and rejects empty or
289
+ whitespace-only strings. `limit` must be an integer from 1 through 50 and defaults
290
+ to 10 for search. Without `query`, the tool still returns the entire catalogue;
291
+ a valid supplied limit has no effect on listing.
292
+
293
+ Names use the existing case-insensitive normalization: runs of characters other
294
+ than ASCII letters and digits become hyphens, with leading/trailing hyphens removed.
295
+ Search sorts exact slug/title matches first, exact aliases second, then heuristic
296
+ matches. Within each group, entries are sorted by canonical slug. A heuristic
297
+ match contains every normalized query token somewhere in the searchable fields,
298
+ including one- and two-character tokens. Tokens can match partial words or span
299
+ fields. These suggestions do not establish which component a design requires.
300
+ Queries that normalize to no tokens return no matches. Full guide bodies,
301
+ capability records and extra decision descriptions are not searched.
302
+
303
+ Search entries retain the listing metadata and add `matchType`, which is
304
+ `exact-name`, `exact-alias` or `heuristic`. Each component appears once with its
305
+ strongest match type. Search results also include:
306
+
307
+ | Field | Meaning |
308
+ | --- | --- |
309
+ | `query`, `limit` | Trimmed query and effective search limit. |
310
+ | `count`, `totalMatches` | Number delivered and total matches before limiting. |
311
+ | `omittedCount`, `truncated` | Matches omitted by the search result-count limit, separately from the byte budget. |
312
+ | `coverageStatus` | `complete-search-results` for all matches, or `partial-search-results` when the limit omitted matches. |
313
+
314
+ For example, `{"query":"no-catalogue-match-zzzz"}` returns `entries: []`,
315
+ zero counts, `truncated: false` and complete search coverage. If a query returns
316
+ more than its limit, increase `limit` up to 50 or narrow the query to retrieve
317
+ omitted entries. Search coverage concerns matching entries, not the whole
318
+ catalogue. Further byte omissions appear in `responseBudget`; `count` reflects
319
+ the records actually delivered and coverage becomes `partial-response-budget`
320
+ or `response-budget-error` when necessary.
321
+
322
+ Search retains the listing's bundled version/hash and optional-target evidence.
323
+ An omitted target leaves compatibility unknown; an incompatible explicit target
324
+ remains blocked while reference matches stay available. Empty results and
325
+ truncation do not change compatibility outcomes.
326
+
327
+ ## Versioned catalogue resource
328
+
329
+ Clients with resource support can discover and read the current bundled snapshot
330
+ over the same stdio connection. The resource is named `component_catalog` and
331
+ has MIME type `application/json`. Use the advertised URI:
332
+
333
+ ```js
334
+ const { resources } = await client.listResources();
335
+ const catalogue = resources.find((resource) => resource.name === 'component_catalog');
336
+ const result = await client.readResource({ uri: catalogue.uri });
337
+ const snapshot = JSON.parse(result.contents[0].text);
338
+ console.log(snapshot.contractVersion, snapshot.sourceHash, snapshot.entries);
339
+ ```
340
+
341
+ The URI format is
342
+ `expressivecss://catalogue/<framework-version>/<source-hash>`. The framework
343
+ version is a URI-encoded path segment and the complete hash comes from the
344
+ shipped contract. It identifies those contract sources; it is not a digest of
345
+ the serialized resource text. Only the current shipped bundle is available.
346
+ The URI's version and hash agree with `contractVersion` and `sourceHash` in JSON.
347
+ There is no unversioned `latest` alias, historical lookup or search selector.
348
+ Resource reads require the exact advertised URI.
349
+ Unknown versions/hashes, query/fragment selectors and unrelated URIs return
350
+ resource-not-found error `-32002`. Invalid request parameters fail through the
351
+ SDK's request validation. The installed SDK 1.31.0 reports request-schema
352
+ failures with protocol error `-32603`.
353
+
354
+ Successful reads return one text item with that URI and JSON MIME type. The
355
+ JSON has `schemaVersion: 1`, `entries`, `count`, `contractVersion`, `sourceHash`
356
+ and `guideSource: "bundled"`. Entries contain the same compact fields and slug
357
+ ordering as a complete unfiltered catalogue tool result. They contain no full
358
+ component guide or capability dump. Tool-only stage/workflow and search fields
359
+ are absent. Resource operations do not depend on tool skip flags.
360
+
361
+ The JSON retains catalogue evidence fields: `status`, `checksPerformed`,
362
+ `evidenceSources`, `uncheckedAreas`, `contractCompatibility`,
363
+ `contractProvenance`, `contractProvenanceDetails`, `coverageStatus` and
364
+ `blockedChecks`. Compatibility is always `unknown`; `bundled-verified`
365
+ provenance concerns the packaged snapshot. Reads inspect no consumer files,
366
+ ignore the working directory and CLI project-root default, and execute no
367
+ project scripts or components. Complete catalogue coverage does not establish
368
+ consumer compatibility, browser behavior or accessibility approval.
369
+
370
+ ### Resource-read budget and recovery
371
+
372
+ Successful resource reads share `EXPRESSIVECSS_MCP_MAX_RESPONSE_BYTES`, default
373
+ 65,536 UTF-8 bytes. Measure the entire final `resources/read` result with
374
+ `Buffer.byteLength(JSON.stringify(result), 'utf8')`. This includes the contents
375
+ array, URI, MIME type, escaped JSON text, metadata and any SDK-added result
376
+ fields. The outer JSON-RPC envelope and stdio framing are excluded. Resource
377
+ JSON includes `responseBudget` with the effective `maxBytes`,
378
+ `delivery: "complete"` and empty `omissions`/`recoveries` arrays.
379
+
380
+ Every successful read delivers every entry whole. If that cannot fit, the
381
+ server returns JSON-RPC error `-32001` without a successful resource result.
382
+ Error data has `uri`, `maxBytes`, `requiredBytes` and
383
+ `setting: "EXPRESSIVECSS_MCP_MAX_RESPONSE_BYTES"`. The required size includes
384
+ the retry budget field's own bytes. Set the operator setting to at least
385
+ `requiredBytes`, restart the server and read the same advertised URI to
386
+ retrieve the complete catalogue. For example, in a contributor checkout:
387
+
388
+ ```sh
389
+ # Replace 100000 with the requiredBytes from the error.
390
+ EXPRESSIVECSS_MCP_MAX_RESPONSE_BYTES=100000 node mcp/expressivecss/server.js
391
+ ```
392
+
393
+ In an MCP client configuration, update that server's environment and reconnect
394
+ instead. A narrower catalogue tool query remains an option when only one entry
395
+ is needed, but it does not recover the whole resource at the same small budget.
396
+ Protocol errors are outside the successful-result budget, including budget 1.
397
+ `resources/list`, `resources/templates/list` and `tools/list` are discovery
398
+ operations outside this content budget; resource discovery remains available
399
+ when a read cannot fit. Subscription support is not advertised.
400
+
401
+ ## Versioned component resources
402
+
403
+ Component guides are available as resources of the same bundled snapshot. Two
404
+ templates appear in `resources/templates/list`, both with MIME type
405
+ `application/json`:
406
+
407
+ | Template | URI |
408
+ | --- | --- |
409
+ | `component_guide` | `expressivecss://components/<framework-version>/<source-hash>/{slug}` |
410
+ | `component_guide_section` | `expressivecss://components/<framework-version>/<source-hash>/{slug}/{section}` |
411
+
412
+ The version and hash are fixed to the shipped contract, as in the catalogue
413
+ URI. `resources/list` lists one whole-guide URI per bundled component, sorted by
414
+ slug, after the catalogue. Section URIs are not listed. Build them from the
415
+ template with a canonical slug and one of `contract`, `syntax`, `rules`,
416
+ `options` or `methods`:
417
+
418
+ ```js
419
+ const { resourceTemplates } = await client.listResourceTemplates();
420
+ const section = resourceTemplates.find((template) => template.name === 'component_guide_section');
421
+ const uri = section.uriTemplate.replace('{slug}', 'date-picker').replace('{section}', 'options');
422
+ const options = JSON.parse((await client.readResource({ uri })).contents[0].text).options;
423
+ ```
424
+
425
+ Every read returns one text item with JSON containing `schemaVersion: 1`,
426
+ `slug`, `title`, `docs` (the documentation page, as in catalogue entries),
427
+ `repositorySource` (the page source in the repository), `contractVersion`,
428
+ `sourceHash` and `guideSource: "bundled"`. A whole-guide read adds all five
429
+ sections. A section read adds `section` and only that section's field:
430
+
431
+ - `contract` is the complete Contract text. The syntax tool shortens long
432
+ contracts to 900 characters; resources do not.
433
+ - `syntax` is `{ language, example }`, the same as detailed syntax tool output.
434
+ - `rules` is the complete ordered rule list returned by the syntax tool.
435
+ - `options` and `methods` are `{ status, markdown }`. A guide without that
436
+ section returns `status: "absent"` and `markdown: null`.
437
+
438
+ The JSON carries the same evidence fields as the catalogue resource.
439
+ Compatibility is always `unknown`, and `coverageStatus` is
440
+ `complete-bundled-guide` or `complete-bundled-guide-section`. Reads inspect no
441
+ consumer files, ignore the working directory, CLI project-root default and tool
442
+ skip flags, and execute no project scripts or components.
443
+
444
+ Reads accept only the exact URIs the templates describe. Catalogue aliases such
445
+ as `datepicker`, case variants, unknown slugs or sections, other versions or
446
+ hashes, extra or empty segments, trailing slashes, percent-encoded variants and
447
+ query or fragment selectors return `-32002`. Use `component_catalog` to resolve
448
+ an alias to its canonical slug, or [complete](#complete-resource-arguments) a
449
+ slug prefix.
450
+
451
+ ### Component read budget and recovery
452
+
453
+ Component reads use the [resource-read budget](#resource-read-budget-and-recovery)
454
+ and its measurement. A successful read always delivers every requested section
455
+ whole. If a read does not fit, the server returns `-32001` with no contents.
456
+ The error data has `uri`, `maxBytes`, `requiredBytes`, `setting`,
457
+ `recoveries` and `unrecoverableSections`:
458
+
459
+ - For a whole-guide URI, `recoveries` lists the section URIs whose complete
460
+ reads fit the current budget, in section order. Read those on the same
461
+ connection. `unrecoverableSections` names the sections that do not fit.
462
+ - For a section URI, `recoveries` is empty and `unrecoverableSections` names
463
+ that section. Its `requiredBytes` is the budget that section needs.
464
+
465
+ Restart with `EXPRESSIVECSS_MCP_MAX_RESPONSE_BYTES` of at least `requiredBytes`
466
+ to read a URI that cannot fit. The largest bundled guide fits the default
467
+ budget, so section recovery matters only under a smaller operator budget.
468
+
469
+ ### Complete resource arguments
470
+
471
+ The server advertises the `completions` capability. `completion/complete`
472
+ completes `slug` on both component templates and `section` on
473
+ `component_guide_section`. Pass the exact `uriTemplate` string from
474
+ `resources/templates/list` as `ref.uri`:
475
+
476
+ ```js
477
+ const { resourceTemplates } = await client.listResourceTemplates();
478
+ const guide = resourceTemplates.find((template) => template.name === 'component_guide');
479
+ await client.complete({ ref: { type: 'ref/resource', uri: guide.uriTemplate }, argument: { name: 'slug', value: 'ca' } });
480
+ // { completion: { values: ['cards', 'carousel'], total: 2, hasMore: false } }
481
+ ```
482
+
483
+ A value matches names that start with it, ignoring case. Slugs come back in
484
+ `resources/list` order, and an empty value returns all of them. Sections come
485
+ back in the order `contract`, `syntax`, `rules`, `options`, `methods`, whatever
486
+ slug `context.arguments` holds. Only canonical slugs match, so `datepicker`
487
+ returns no values while `date` returns `date-picker`. The SDK returns at most
488
+ 100 values, with `total` matches and `hasMore` set when more matched. Every
489
+ current result fits.
490
+
491
+ - A value with no matches returns `values: []`, `total: 0` and
492
+ `hasMore: false`.
493
+ - Other argument names, such as `version`, and the fixed catalogue URI return
494
+ `values: []` and `hasMore: false` without `total`.
495
+ - A `ref.uri` that is not one of the two current template strings, such as
496
+ another version or hash, returns `-32602`. So does a `ref/prompt` reference,
497
+ because the server has no prompts.
498
+
499
+ Completion uses the bundled catalogue loaded at startup. It reads no project
500
+ files and runs no commands, and it stays outside the
501
+ [content budget](#resource-read-budget-and-recovery) like resource listing.
502
+ Completion covers resource template arguments only. MCP does not complete tool
503
+ arguments, so `component_syntax_expert` and other tools still need canonical
504
+ names or aliases, which `component_catalog` lists.
505
+
32
506
  ## Run it locally
33
507
 
34
508
  The server supports Node `^22.22.2 || ^24.15.0 || >=26.0.0`, matching its `jsdom` runtime dependency.
@@ -59,14 +533,15 @@ npm test
59
533
  | `creative_director` | Suggests components from the generated decision catalogue, with uncertain fuzzy matches labelled as fallback |
60
534
  | `page_arcjitect` | Workflow stage returning page sections, landmarks, and a semantic skeleton |
61
535
  | `page_architect` | Conventional spelling for the same page architecture tool; component names must resolve exactly |
62
- | `component_syntax_expert` | Returns authoritative syntax/contract/rules for components |
536
+ | `component_syntax_expert` | Returns complete rules, selectable syntax/capability detail and requested documented Options and Methods for components |
537
+ | `component_catalog` | Lists or searches compact bundled component metadata with labelled matches, result limits, snapshot identity and optional target compatibility checks |
63
538
  | `quality_inspector` | Runs scoped static checks and optional commands (`npm run typecheck`, `npm run test`), then names every uninspected review area |
64
539
 
65
540
  Static findings are heuristic and require source or runtime confirmation before remediation. A clean static check is reported as `staticStatus: "heuristic_pass"`; any overall MCP `pass` applies only to `checksPerformed`. Neither proves visual hierarchy, responsive rendering, focus behavior, motion, contrast, screen-reader announcements, or component-rule conformance unless separate evidence covers those areas. Read `uncheckedAreas`, `blockedChecks`, `coverageStatus`, `contractCompatibility`, and `contractProvenance` before using a result in a finish review.
66
541
 
67
542
  `creative_director` and both page architect spellings resolve the target ExpressiveCSS version before reading current contract guidance. They return no recommendations or architecture when the version is mismatched or unresolved, when local contract provenance is missing, stale, invalid, or divergent from the bundled package contract, or when an architecture request contains an inexact component name. Fuzzy creative matches remain labelled `confidence: "fallback"`; page architecture never accepts them silently.
68
543
 
69
- For a framework source checkout, the server accepts only the generated contract's canonical source list. It resolves the real project and source paths, rejects symbolic links and non-regular files, and caps each source at 2 MiB and the set at 8 MiB. It recomputes provenance for every tool call in manifest order with the generator's SHA-256 input format, `source path + NUL + file content + NUL`. The verified local manifest must also match the bundled package's framework version and source hash because the MCP serves bundled guidance. Contract-dependent output is blocked when the source set is invalid, missing, oversized, stale, or divergent. Invalid source paths never produce a computed hash. Generated data shipped in this package reports `contractProvenance: "bundled-verified"` because package consumers do not receive the framework source files.
544
+ When checking a framework source target, the server accepts only the generated contract's canonical source list. It resolves the real project and source paths, rejects symbolic links and non-regular files, and caps each source at 2 MiB and the set at 8 MiB. It recomputes provenance for each target-project check in manifest order with the generator's SHA-256 input format, `source path + NUL + file content + NUL`. The verified local manifest must also match the bundled package's framework version and source hash because the MCP serves bundled guidance. Contract-dependent output is blocked when the source set is invalid, missing, oversized, stale, or divergent. Invalid source paths never produce a computed hash. Generated data shipped in this package reports `contractProvenance: "bundled-verified"` because package consumers do not receive the framework source files.
70
545
 
71
546
  Static inspection uses descriptor-level, no-follow bounded reads and rechecks file identity after each read. It caps files at 2 MiB each and 16 MiB per request by default, stops after 200 issues per file or 1,000 per request, and applies a five-second scan budget. Any unread, changed, over-budget, or partially scanned file appears under `filesUninspected`, which prevents a pass.
72
547
 
@@ -136,6 +611,7 @@ network limits, evidence handling, and bounded repair workflow.
136
611
 
137
612
  ## Environment variables
138
613
 
614
+ - `EXPRESSIVECSS_MCP_MAX_RESPONSE_BYTES`, default `65536`.
139
615
  - `EXPRESSIVECSS_MCP_MAX_COMPONENT_RESPONSE_CHARS`
140
616
  - `EXPRESSIVECSS_MCP_MAX_COMPONENT_SKIPS`
141
617
  - `EXPRESSIVECSS_MCP_QA_MAX_FILES`
@@ -152,6 +628,11 @@ network limits, evidence handling, and bounded repair workflow.
152
628
 
153
629
  Set any skip flag to `true` to disable that stage from doing work.
154
630
 
631
+ `EXPRESSIVECSS_MCP_MAX_COMPONENT_RESPONSE_CHARS` is retained for configuration
632
+ compatibility and the legacy `maxCharactersPerComponent` metadata. It no longer
633
+ clips syntax examples and does not bound tool results. Use the byte setting for
634
+ aggregate guidance limits. QA command-output limits remain separate.
635
+
155
636
  Command execution is denied by default. To let `quality_inspector` honor `runCommands: true`, the MCP operator must set `EXPRESSIVECSS_MCP_ALLOWED_COMMAND_ROOTS` when launching the server. Use platform path separators for multiple roots, or a JSON array of absolute roots:
156
637
 
157
638
  ```text
@@ -172,6 +653,7 @@ The real `projectRoot` must equal or be contained by one of those roots. A tool
172
653
  "command": "npx",
173
654
  "args": ["-y", "@expressivecss/mcp-server@latest"],
174
655
  "env": {
656
+ "EXPRESSIVECSS_MCP_MAX_RESPONSE_BYTES": "65536",
175
657
  "EXPRESSIVECSS_MCP_MAX_COMPONENT_RESPONSE_CHARS": "24000",
176
658
  "EXPRESSIVECSS_MCP_MAX_COMPONENT_SKIPS": "7",
177
659
  "EXPRESSIVECSS_MCP_QA_MAX_FILES": "300",