@cobwds/mcp-server 1.19.3

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.
Files changed (65) hide show
  1. package/README.md +235 -0
  2. package/data/cem/custom-elements.json +15923 -0
  3. package/data/guides/.gitkeep +0 -0
  4. package/data/guides/fonts.md +56 -0
  5. package/data/guides/form-validation.md +169 -0
  6. package/data/guides/frameworks/angular.md +71 -0
  7. package/data/guides/frameworks/dotnet.md +42 -0
  8. package/data/guides/frameworks/drupal.md +39 -0
  9. package/data/guides/frameworks/react.md +115 -0
  10. package/data/guides/frameworks/vanilla.md +45 -0
  11. package/data/guides/installation.md +73 -0
  12. package/data/guides/page-structure.md +161 -0
  13. package/data/guides/styles.md +48 -0
  14. package/data/guides/themes.md +61 -0
  15. package/data/tokens/tokens.css +479 -0
  16. package/data/tokens/tokens.json +1553 -0
  17. package/dist/index.d.ts +9 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +16 -0
  20. package/dist/lib/cem-parser.d.ts +102 -0
  21. package/dist/lib/cem-parser.d.ts.map +1 -0
  22. package/dist/lib/cem-parser.js +92 -0
  23. package/dist/lib/search.d.ts +20 -0
  24. package/dist/lib/search.d.ts.map +1 -0
  25. package/dist/lib/search.js +87 -0
  26. package/dist/lib/token-parser.d.ts +128 -0
  27. package/dist/lib/token-parser.d.ts.map +1 -0
  28. package/dist/lib/token-parser.js +431 -0
  29. package/dist/prompts/cobwds-mode.d.ts +8 -0
  30. package/dist/prompts/cobwds-mode.d.ts.map +1 -0
  31. package/dist/prompts/cobwds-mode.js +60 -0
  32. package/dist/resources/components.d.ts +12 -0
  33. package/dist/resources/components.d.ts.map +1 -0
  34. package/dist/resources/components.js +62 -0
  35. package/dist/resources/guides.d.ts +11 -0
  36. package/dist/resources/guides.d.ts.map +1 -0
  37. package/dist/resources/guides.js +76 -0
  38. package/dist/resources/index.d.ts +8 -0
  39. package/dist/resources/index.d.ts.map +1 -0
  40. package/dist/resources/index.js +13 -0
  41. package/dist/resources/tokens.d.ts +17 -0
  42. package/dist/resources/tokens.d.ts.map +1 -0
  43. package/dist/resources/tokens.js +312 -0
  44. package/dist/server.d.ts +11 -0
  45. package/dist/server.d.ts.map +1 -0
  46. package/dist/server.js +30 -0
  47. package/dist/tools/component-tools.d.ts +12 -0
  48. package/dist/tools/component-tools.d.ts.map +1 -0
  49. package/dist/tools/component-tools.js +95 -0
  50. package/dist/tools/guide-tools.d.ts +9 -0
  51. package/dist/tools/guide-tools.d.ts.map +1 -0
  52. package/dist/tools/guide-tools.js +80 -0
  53. package/dist/tools/index.d.ts +8 -0
  54. package/dist/tools/index.d.ts.map +1 -0
  55. package/dist/tools/index.js +17 -0
  56. package/dist/tools/token-tools.d.ts +13 -0
  57. package/dist/tools/token-tools.d.ts.map +1 -0
  58. package/dist/tools/token-tools.js +207 -0
  59. package/dist/tools/utility-tools.d.ts +8 -0
  60. package/dist/tools/utility-tools.d.ts.map +1 -0
  61. package/dist/tools/utility-tools.js +293 -0
  62. package/dist/tools/validation-tools.d.ts +11 -0
  63. package/dist/tools/validation-tools.d.ts.map +1 -0
  64. package/dist/tools/validation-tools.js +60 -0
  65. package/package.json +54 -0
@@ -0,0 +1,431 @@
1
+ /**
2
+ * Design Token Parser
3
+ *
4
+ * Reads and parses COBWDS design tokens with a CSS-centric approach.
5
+ * Returns data aligned with tokens.css output (not JSON internals).
6
+ *
7
+ * Key transformations:
8
+ * - Token paths are converted to CSS variable names
9
+ * - Alias references become var() expressions
10
+ * - Layer prefixes (primitive, applied) are stripped
11
+ */
12
+ import { readFileSync, existsSync } from "node:fs";
13
+ import { resolve, dirname } from "node:path";
14
+ import { fileURLToPath } from "node:url";
15
+ // ESM path resolution
16
+ const __filename = fileURLToPath(import.meta.url);
17
+ const __dirname = dirname(__filename);
18
+ // ============================================================================
19
+ // Token Data Cache
20
+ // ============================================================================
21
+ let cachedCSSTokens = null;
22
+ let cachedTokenGraph = null;
23
+ let cachedRawTokens = null;
24
+ // ============================================================================
25
+ // Path Resolution
26
+ // ============================================================================
27
+ /**
28
+ * Get the path to tokens.json file
29
+ * Uses ESM-compatible path resolution with fallbacks for different contexts
30
+ */
31
+ export function getTokensPath() {
32
+ const possiblePaths = [
33
+ // Bundled data — works in standalone installs (most reliable)
34
+ resolve(__dirname, "../../data/tokens/tokens.json"),
35
+ // From lib/ directory (normal execution)
36
+ resolve(__dirname, "../../../../tokens/src/tokens.json"),
37
+ // From mcp-server package root
38
+ resolve(__dirname, "../../../tokens/src/tokens.json"),
39
+ // From monorepo root
40
+ resolve(__dirname, "../../../../../packages/tokens/src/tokens.json"),
41
+ // Direct path from monorepo root
42
+ resolve(process.cwd(), "packages/tokens/src/tokens.json"),
43
+ // From mcp-server package
44
+ resolve(process.cwd(), "../tokens/src/tokens.json"),
45
+ ];
46
+ for (const path of possiblePaths) {
47
+ if (existsSync(path)) {
48
+ return path;
49
+ }
50
+ }
51
+ return null;
52
+ }
53
+ /**
54
+ * Get the path to tokens.css file
55
+ */
56
+ export function getTokensCSSPath() {
57
+ const possiblePaths = [
58
+ // Bundled data — works in standalone installs (most reliable)
59
+ resolve(__dirname, "../../data/tokens/tokens.css"),
60
+ resolve(__dirname, "../../../../tokens/dist/tokens.css"),
61
+ resolve(__dirname, "../../../tokens/dist/tokens.css"),
62
+ resolve(__dirname, "../../../../../packages/tokens/dist/tokens.css"),
63
+ resolve(process.cwd(), "packages/tokens/dist/tokens.css"),
64
+ resolve(process.cwd(), "../tokens/dist/tokens.css"),
65
+ ];
66
+ for (const path of possiblePaths) {
67
+ if (existsSync(path)) {
68
+ return path;
69
+ }
70
+ }
71
+ return null;
72
+ }
73
+ // ============================================================================
74
+ // Constants
75
+ // ============================================================================
76
+ const LAYER_PREFIXES = ["primitive", "applied", "appearance", "theme"];
77
+ // ============================================================================
78
+ // CSS Variable Transformation
79
+ // ============================================================================
80
+ /**
81
+ * Transform a JSON token path to CSS variable name
82
+ *
83
+ * Examples:
84
+ * - "primitive.color.neutral.900" → "--cob-color-neutral-900"
85
+ * - "applied.color.text.default" → "--cob-color-text"
86
+ * - "color.theme.default" → "--cob-color-theme"
87
+ * - "font.size.md" → "--cob-font-size-md"
88
+ */
89
+ export function toCSSVariable(jsonPath) {
90
+ let name = "--cob-" +
91
+ jsonPath
92
+ // Strip layer prefixes
93
+ .replace(new RegExp(`^(${LAYER_PREFIXES.join("|")})\\.`), "")
94
+ // Dots to hyphens
95
+ .replace(/\./g, "-");
96
+ // Strip trailing -default suffix
97
+ name = name.replace(/-default$/, "");
98
+ return name;
99
+ }
100
+ /**
101
+ * Convert an alias reference to CSS var() syntax
102
+ *
103
+ * Examples:
104
+ * - "{primitive.color.neutral.900}" → "var(--cob-color-neutral-900)"
105
+ * - "{font.size.md}" → "var(--cob-font-size-md)"
106
+ */
107
+ export function aliasToVarRef(aliasValue) {
108
+ // Extract the path from {path.to.token}
109
+ const match = aliasValue.match(/^\{(.+)\}$/);
110
+ if (!match) {
111
+ return { cssValue: aliasValue, referencesVariable: "" };
112
+ }
113
+ const referencesVariable = toCSSVariable(match[1]);
114
+ const cssValue = `var(${referencesVariable})`;
115
+ return { cssValue, referencesVariable };
116
+ }
117
+ /**
118
+ * Determine the category from a JSON path
119
+ */
120
+ function getCategoryFromPath(jsonPath) {
121
+ const parts = jsonPath.split(".");
122
+ // Skip layer prefix if present
123
+ const startIndex = LAYER_PREFIXES.includes(parts[0]) ? 1 : 0;
124
+ return parts[startIndex] || "unknown";
125
+ }
126
+ /**
127
+ * Determine the layer from a JSON path
128
+ *
129
+ * Layers:
130
+ * - primitive: Raw values (colors, sizes, fonts, spacing, etc.)
131
+ * - applied: Semantic tokens that reference primitives (includes color.theme.* defaults)
132
+ * - theme: Agency theme overrides
133
+ * - appearance: Light/dark mode variations
134
+ */
135
+ function getLayerFromPath(jsonPath) {
136
+ const parts = jsonPath.split(".");
137
+ // Check for explicit layer prefixes
138
+ if (LAYER_PREFIXES.includes(parts[0])) {
139
+ return parts[0];
140
+ }
141
+ // color.theme.* tokens are applied semantic tokens (agency themes override these)
142
+ if (parts[0] === "color" && parts[1] === "theme") {
143
+ return "applied";
144
+ }
145
+ // Non-prefixed categories (space, size, font, radius, etc.) contain raw values
146
+ // so they are classified as "primitive"
147
+ return "primitive";
148
+ }
149
+ // ============================================================================
150
+ // Token Parsing
151
+ // ============================================================================
152
+ /**
153
+ * Load raw token data from tokens.json
154
+ */
155
+ function loadRawTokens() {
156
+ if (cachedRawTokens) {
157
+ return cachedRawTokens;
158
+ }
159
+ const tokensPath = getTokensPath();
160
+ if (!tokensPath) {
161
+ console.error("Warning: No tokens file found");
162
+ return null;
163
+ }
164
+ try {
165
+ const content = readFileSync(tokensPath, "utf-8");
166
+ cachedRawTokens = JSON.parse(content);
167
+ return cachedRawTokens;
168
+ }
169
+ catch (error) {
170
+ console.error("Warning: Could not parse tokens file:", error);
171
+ return null;
172
+ }
173
+ }
174
+ /**
175
+ * Parse tokens recursively into CSS-centric format
176
+ */
177
+ function parseCSSTokens(obj, prefix = "", resolvedValues = new Map()) {
178
+ const tokens = [];
179
+ for (const [key, value] of Object.entries(obj)) {
180
+ if (key.startsWith("$"))
181
+ continue; // Skip meta properties
182
+ const jsonPath = prefix ? `${prefix}.${key}` : key;
183
+ if (typeof value === "object" &&
184
+ value !== null &&
185
+ "$value" in value) {
186
+ // This is a token
187
+ const tokenObj = value;
188
+ const rawValue = tokenObj.$value;
189
+ const description = tokenObj.$description;
190
+ const cssVariable = toCSSVariable(jsonPath);
191
+ const category = getCategoryFromPath(jsonPath);
192
+ const layer = getLayerFromPath(jsonPath);
193
+ let cssValue;
194
+ let referencesVariable;
195
+ let resolvedValue;
196
+ // Handle different value types
197
+ if (typeof rawValue === "string" && rawValue.startsWith("{")) {
198
+ // Alias reference
199
+ const aliasResult = aliasToVarRef(rawValue);
200
+ cssValue = aliasResult.cssValue;
201
+ referencesVariable = aliasResult.referencesVariable;
202
+ // Try to resolve the value
203
+ resolvedValue = resolvedValues.get(referencesVariable);
204
+ }
205
+ else if (Array.isArray(rawValue)) {
206
+ // Complex value (like shadows) - format as string
207
+ cssValue = JSON.stringify(rawValue);
208
+ resolvedValue = cssValue;
209
+ }
210
+ else if (typeof rawValue === "object" && rawValue !== null) {
211
+ // Object value (like single shadow)
212
+ cssValue = JSON.stringify(rawValue);
213
+ resolvedValue = cssValue;
214
+ }
215
+ else {
216
+ // Direct value
217
+ cssValue = String(rawValue);
218
+ resolvedValue = cssValue;
219
+ }
220
+ // Store resolved value for other tokens to reference
221
+ if (resolvedValue) {
222
+ resolvedValues.set(cssVariable, resolvedValue);
223
+ }
224
+ tokens.push({
225
+ cssVariable,
226
+ cssValue,
227
+ referencesVariable,
228
+ resolvedValue,
229
+ description,
230
+ category,
231
+ layer,
232
+ jsonPath,
233
+ });
234
+ }
235
+ else if (typeof value === "object" && value !== null) {
236
+ // Recurse into nested group
237
+ tokens.push(...parseCSSTokens(value, jsonPath, resolvedValues));
238
+ }
239
+ }
240
+ return tokens;
241
+ }
242
+ /**
243
+ * Resolve all alias values to their final resolved values
244
+ */
245
+ function resolveAllValues(tokens) {
246
+ const byVariable = new Map();
247
+ for (const token of tokens) {
248
+ byVariable.set(token.cssVariable, token);
249
+ }
250
+ // Iterate to resolve nested aliases (max 10 levels to prevent infinite loops)
251
+ for (let i = 0; i < 10; i++) {
252
+ let changed = false;
253
+ for (const token of tokens) {
254
+ if (token.referencesVariable && !token.resolvedValue) {
255
+ const referenced = byVariable.get(token.referencesVariable);
256
+ if (referenced?.resolvedValue) {
257
+ token.resolvedValue = referenced.resolvedValue;
258
+ changed = true;
259
+ }
260
+ }
261
+ }
262
+ if (!changed)
263
+ break;
264
+ }
265
+ }
266
+ // ============================================================================
267
+ // Token Graph
268
+ // ============================================================================
269
+ /**
270
+ * Build a dependency graph of tokens
271
+ * Shows which tokens reference which, and which tokens are used by which
272
+ */
273
+ export function buildTokenGraph() {
274
+ if (cachedTokenGraph) {
275
+ return cachedTokenGraph;
276
+ }
277
+ const tokens = getCSSTokens();
278
+ const graph = new Map();
279
+ // Initialize all nodes
280
+ for (const token of tokens) {
281
+ graph.set(token.cssVariable, {
282
+ cssVariable: token.cssVariable,
283
+ referencesVariable: token.referencesVariable,
284
+ usedBy: [],
285
+ });
286
+ }
287
+ // Build usedBy relationships
288
+ for (const token of tokens) {
289
+ if (token.referencesVariable) {
290
+ const referenced = graph.get(token.referencesVariable);
291
+ if (referenced) {
292
+ referenced.usedBy.push(token.cssVariable);
293
+ }
294
+ }
295
+ }
296
+ cachedTokenGraph = graph;
297
+ return graph;
298
+ }
299
+ // ============================================================================
300
+ // Public API - CSS-Centric
301
+ // ============================================================================
302
+ /**
303
+ * Get all tokens in CSS-centric format
304
+ */
305
+ export function getCSSTokens() {
306
+ if (cachedCSSTokens) {
307
+ return cachedCSSTokens;
308
+ }
309
+ const rawTokens = loadRawTokens();
310
+ if (!rawTokens) {
311
+ cachedCSSTokens = [];
312
+ return cachedCSSTokens;
313
+ }
314
+ cachedCSSTokens = parseCSSTokens(rawTokens);
315
+ resolveAllValues(cachedCSSTokens);
316
+ return cachedCSSTokens;
317
+ }
318
+ /**
319
+ * Get CSS tokens filtered by category
320
+ */
321
+ export function getCSSTokensByCategory(category) {
322
+ const tokens = getCSSTokens();
323
+ return tokens.filter((t) => t.category.toLowerCase() === category.toLowerCase());
324
+ }
325
+ /**
326
+ * Get a single token by CSS variable name
327
+ */
328
+ export function getCSSTokenByVariable(variableName) {
329
+ const tokens = getCSSTokens();
330
+ // Normalize: accept with or without -- prefix
331
+ const normalized = variableName.startsWith("--")
332
+ ? variableName
333
+ : `--cob-${variableName}`;
334
+ return tokens.find((t) => t.cssVariable === normalized);
335
+ }
336
+ /**
337
+ * Get all unique categories
338
+ */
339
+ export function getCSSTokenCategories() {
340
+ const tokens = getCSSTokens();
341
+ const counts = new Map();
342
+ for (const token of tokens) {
343
+ counts.set(token.category, (counts.get(token.category) || 0) + 1);
344
+ }
345
+ return Array.from(counts.entries())
346
+ .map(([category, count]) => ({ category, count }))
347
+ .sort((a, b) => a.category.localeCompare(b.category));
348
+ }
349
+ /**
350
+ * Get raw tokens.css content
351
+ */
352
+ export function getTokensCSS() {
353
+ const cssPath = getTokensCSSPath();
354
+ if (!cssPath) {
355
+ return null;
356
+ }
357
+ try {
358
+ return readFileSync(cssPath, "utf-8");
359
+ }
360
+ catch {
361
+ return null;
362
+ }
363
+ }
364
+ /**
365
+ * Get recommended tokens for everyday use.
366
+ *
367
+ * Excludes color primitive tokens (the ~150 palette ramps like neutral-*, red-*,
368
+ * blue-*) which are low-level raw values. For font tokens, applied aliases
369
+ * (body-*, h*, ui-*) are sorted before primitives so the most useful tokens
370
+ * appear first.
371
+ */
372
+ export function getRecommendedTokens() {
373
+ const tokens = getCSSTokens();
374
+ const filtered = tokens.filter((t) => !(t.category === "color" && t.layer === "primitive"));
375
+ // For font tokens, sort applied before primitive so named aliases surface first
376
+ filtered.sort((a, b) => {
377
+ if (a.category === "font" && b.category === "font") {
378
+ if (a.layer === "applied" && b.layer !== "applied")
379
+ return -1;
380
+ if (a.layer !== "applied" && b.layer === "applied")
381
+ return 1;
382
+ }
383
+ return 0;
384
+ });
385
+ return filtered;
386
+ }
387
+ /**
388
+ * Get only primitive (raw value) tokens across all categories.
389
+ */
390
+ export function getPrimitiveTokens() {
391
+ const tokens = getCSSTokens();
392
+ return tokens.filter((t) => t.layer === "primitive");
393
+ }
394
+ /**
395
+ * Get alternative tokens in the same category that share the same name prefix.
396
+ *
397
+ * First looks for child variants (tokens starting with this token's name + "-"):
398
+ * --cob-color-text → finds --cob-color-text-weak, --cob-color-text-reverse, etc.
399
+ *
400
+ * If no children exist, looks for siblings (tokens sharing the same parent prefix):
401
+ * --cob-color-text-weak → parent: --cob-color-text → finds text, text-weaker, etc.
402
+ *
403
+ * Returns an array of cssVariable strings (empty if none found).
404
+ */
405
+ export function getAlternativeTokens(token) {
406
+ const varName = token.cssVariable;
407
+ const tokens = getCSSTokens();
408
+ // Look for child variants: tokens starting with this token's name + "-"
409
+ const children = tokens.filter((t) => t.category === token.category && t.cssVariable.startsWith(varName + "-"));
410
+ if (children.length > 0) {
411
+ return children.map((t) => t.cssVariable);
412
+ }
413
+ // No children — look for siblings sharing the same parent prefix
414
+ const lastDash = varName.lastIndexOf("-");
415
+ if (lastDash <= 5)
416
+ return []; // "--cob-" is 6 chars minimum
417
+ const parent = varName.slice(0, lastDash);
418
+ return tokens
419
+ .filter((t) => t.category === token.category &&
420
+ t.cssVariable !== varName &&
421
+ (t.cssVariable === parent || t.cssVariable.startsWith(parent + "-")))
422
+ .map((t) => t.cssVariable);
423
+ }
424
+ /**
425
+ * Clear all cached tokens (useful for testing)
426
+ */
427
+ export function clearTokenCache() {
428
+ cachedCSSTokens = null;
429
+ cachedTokenGraph = null;
430
+ cachedRawTokens = null;
431
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * COBWDS Mode Prompt
3
+ *
4
+ * Activates COBWDS-aware coding assistance.
5
+ */
6
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
7
+ export declare function registerPrompts(server: McpServer): void;
8
+ //# sourceMappingURL=cobwds-mode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cobwds-mode.d.ts","sourceRoot":"","sources":["../../src/prompts/cobwds-mode.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA2DvD"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * COBWDS Mode Prompt
3
+ *
4
+ * Activates COBWDS-aware coding assistance.
5
+ */
6
+ export function registerPrompts(server) {
7
+ server.prompt("cobwds_mode", "Activates COBWDS-aware coding assistance with knowledge of components, tokens, and best practices", {}, async () => {
8
+ return {
9
+ messages: [
10
+ {
11
+ role: "user",
12
+ content: {
13
+ type: "text",
14
+ text: `You are now in COBWDS (City of Boston Web Design System) mode. You have access to comprehensive knowledge about COBWDS web components and design tokens.
15
+
16
+ ## Your Capabilities
17
+
18
+ 1. **Component Knowledge**: You can list, search, and provide detailed documentation for all COBWDS web components using the available tools.
19
+
20
+ 2. **Design Tokens**: You can access and explain COBWDS design tokens for colors, spacing, typography, and more.
21
+
22
+ 3. **Code Generation**: When generating code that uses UI components, prefer COBWDS components over generic HTML or other libraries.
23
+
24
+ 4. **Validation**: You can validate component usage to ensure correct attribute and property usage.
25
+
26
+ 5. **Framework Integration**: You can provide setup guides for various frameworks (React, Angular, .NET, Drupal, Vanilla JS).
27
+
28
+ ## Best Practices
29
+
30
+ - Always use semantic COBWDS components (e.g., \`<cob-button>\` instead of \`<button>\`)
31
+ - Use COBWDS design tokens via CSS custom properties for consistent styling
32
+ - Follow accessibility guidelines built into COBWDS components
33
+ - Reference the official documentation at https://cityofboston.github.io/nywds-poc/
34
+
35
+ ## Available Tools
36
+
37
+ ### Components
38
+ - \`find_components\`: Search for components or list all (omit query to list all)
39
+ - \`get_component\`: Get detailed docs for a specific component
40
+ - \`validate_component_api\`: Validate component attribute/property usage
41
+
42
+ ### Design Tokens
43
+ - \`get_tokens\`: Get tokens, categories, or themes (use output parameter)
44
+ - \`find_tokens\`: Search for tokens by name, value, or description
45
+ - \`get_token_info\`: Get details about a specific token with optional context validation
46
+ - \`get_token_graph\`: Explore token dependencies
47
+
48
+ ### Styles & Utilities
49
+ - \`get_utility_classes\`: Grid, flexbox, spacing, and other utility classes
50
+
51
+ ### Guides
52
+ - \`get_guide\`: Get guides for installation, forms, styles, fonts, page structure, or framework setup
53
+
54
+ When helping with UI development for the City of Boston projects, prioritize COBWDS components and patterns.`,
55
+ },
56
+ },
57
+ ],
58
+ };
59
+ });
60
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Component Resources
3
+ *
4
+ * MCP resources for COBWDS component documentation.
5
+ *
6
+ * P0 Resources:
7
+ * - cobwds://components - Component overview list
8
+ * - cobwds://component/{tag} - Individual component docs
9
+ */
10
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
11
+ export declare function registerComponentResources(server: McpServer): void;
12
+ //# sourceMappingURL=components.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../src/resources/components.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAiElE"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Component Resources
3
+ *
4
+ * MCP resources for COBWDS component documentation.
5
+ *
6
+ * P0 Resources:
7
+ * - cobwds://components - Component overview list
8
+ * - cobwds://component/{tag} - Individual component docs
9
+ */
10
+ import { getAllComponents, getComponent } from "../lib/cem-parser.js";
11
+ export function registerComponentResources(server) {
12
+ // cobwds://components - Component overview list
13
+ server.resource("components", "cobwds://components", {
14
+ description: "List of all COBWDS web components with summaries",
15
+ mimeType: "application/json",
16
+ }, async () => {
17
+ const components = getAllComponents();
18
+ const list = components.map((c) => ({
19
+ tagName: c.tagName,
20
+ name: c.name,
21
+ summary: c.summary || c.description?.split("\n")[0] || "No description",
22
+ }));
23
+ return {
24
+ contents: [
25
+ {
26
+ uri: "cobwds://components",
27
+ mimeType: "application/json",
28
+ text: JSON.stringify(list, null, 2),
29
+ },
30
+ ],
31
+ };
32
+ });
33
+ // cobwds://component/{tag} - Individual component docs
34
+ server.resource("component", "cobwds://component/{tag}", {
35
+ description: "Full documentation for a specific COBWDS component",
36
+ mimeType: "application/json",
37
+ }, async (uri) => {
38
+ // Extract tag from URI: cobwds://component/cob-button -> cob-button
39
+ const tag = uri.pathname.split("/").pop() || "";
40
+ const component = getComponent(tag);
41
+ if (!component) {
42
+ return {
43
+ contents: [
44
+ {
45
+ uri: uri.href,
46
+ mimeType: "text/plain",
47
+ text: `Component "${tag}" not found`,
48
+ },
49
+ ],
50
+ };
51
+ }
52
+ return {
53
+ contents: [
54
+ {
55
+ uri: uri.href,
56
+ mimeType: "application/json",
57
+ text: JSON.stringify(component, null, 2),
58
+ },
59
+ ],
60
+ };
61
+ });
62
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Guide Resources
3
+ *
4
+ * MCP resources for COBWDS installation and usage guides.
5
+ *
6
+ * P0 Resources:
7
+ * - cobwds://installation - Installation guide
8
+ */
9
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
10
+ export declare function registerGuideResources(server: McpServer): void;
11
+ //# sourceMappingURL=guides.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guides.d.ts","sourceRoot":"","sources":["../../src/resources/guides.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAyE9D"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Guide Resources
3
+ *
4
+ * MCP resources for COBWDS installation and usage guides.
5
+ *
6
+ * P0 Resources:
7
+ * - cobwds://installation - Installation guide
8
+ */
9
+ export function registerGuideResources(server) {
10
+ // cobwds://installation - Installation guide
11
+ server.resource("installation", "cobwds://installation", {
12
+ description: "COBWDS installation and setup guide",
13
+ mimeType: "text/markdown",
14
+ }, async () => {
15
+ const guide = `# COBWDS Installation Guide
16
+
17
+ ## 1. Install packages
18
+
19
+ \`\`\`bash
20
+ npm install @cobwds/components @cobwds/styles
21
+ \`\`\`
22
+
23
+ ## 2. Load styles
24
+
25
+ COBWDS components require CSS variables to render correctly. Choose the right stylesheet:
26
+
27
+ **New project** — includes a CSS reset, typography, and utility/layout classes:
28
+ \`\`\`css
29
+ @import '@cobwds/styles/full';
30
+ \`\`\`
31
+
32
+ **Existing project** — loads only the CSS variables that style the components:
33
+ \`\`\`css
34
+ @import '@cobwds/styles';
35
+ \`\`\`
36
+
37
+ ## 3. Import and use components
38
+
39
+ \`\`\`javascript
40
+ import '@cobwds/cob-button';
41
+ import '@cobwds/cob-alert';
42
+ \`\`\`
43
+
44
+ Or import all components:
45
+
46
+ \`\`\`javascript
47
+ import '@cobwds/components';
48
+ \`\`\`
49
+
50
+ Then use them in HTML:
51
+
52
+ \`\`\`html
53
+ <cob-button label="Submit" variant="filled"></cob-button>
54
+ <cob-alert type="info">This is an informational message.</cob-alert>
55
+ \`\`\`
56
+
57
+ ## Framework Integration
58
+
59
+ For framework-specific setup, use the \`get_guide\` tool with \`topic: "framework"\` and a \`framework\` parameter (angular, react, dotnet, drupal, or vanilla).
60
+
61
+ ## Resources
62
+
63
+ - Documentation: https://cityofboston.github.io/nywds-poc/
64
+ - GitHub: https://github.com/CityOfBoston/nywds-poc
65
+ `;
66
+ return {
67
+ contents: [
68
+ {
69
+ uri: "cobwds://installation",
70
+ mimeType: "text/markdown",
71
+ text: guide,
72
+ },
73
+ ],
74
+ };
75
+ });
76
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * MCP Resources Registration
3
+ *
4
+ * Registers all COBWDS resources with the MCP server.
5
+ */
6
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
7
+ export declare function registerResources(server: McpServer): void;
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKzE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAIzD"}