@webspire/mcp 0.5.0 → 0.6.0
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.
- package/README.md +61 -50
- package/data/registry.json +1 -1
- package/dist/index.js +6 -1
- package/dist/registration.js +86 -17
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
# @webspire/mcp
|
|
2
2
|
|
|
3
|
-
MCP server for [Webspire](https://webspire.de) — AI-native discovery of CSS snippets, UI patterns, and page templates.
|
|
3
|
+
MCP server for [Webspire](https://webspire.de) — AI-native discovery of CSS snippets, UI patterns, and page templates with a 3-layer design token system.
|
|
4
4
|
|
|
5
|
-
**49 CSS snippets** + **212 UI patterns** + **18 page templates** — all Tailwind v4, dark mode, accessible.
|
|
5
|
+
**49 CSS snippets** + **212 UI patterns** + **18 page templates** — all Tailwind v4, token-based, dark mode, accessible.
|
|
6
6
|
|
|
7
7
|
## Quick Start
|
|
8
8
|
|
|
9
9
|
### Claude Code / Claude Desktop
|
|
10
10
|
|
|
11
|
-
Add to your MCP settings (`~/.claude/settings.json` or Claude Desktop config):
|
|
12
|
-
|
|
13
11
|
```json
|
|
14
12
|
{
|
|
15
13
|
"mcpServers": {
|
|
@@ -21,71 +19,88 @@ Add to your MCP settings (`~/.claude/settings.json` or Claude Desktop config):
|
|
|
21
19
|
}
|
|
22
20
|
```
|
|
23
21
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
```json
|
|
27
|
-
{
|
|
28
|
-
"mcpServers": {
|
|
29
|
-
"webspire": {
|
|
30
|
-
"command": "npx",
|
|
31
|
-
"args": ["-y", "@webspire/mcp", "--registry-url", "https://your-domain.com/registry.json"]
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
## Available Tools
|
|
22
|
+
## Available Tools (12)
|
|
38
23
|
|
|
39
24
|
| Tool | Description |
|
|
40
25
|
|------|-------------|
|
|
41
26
|
| `list_categories` | List all snippet categories with counts |
|
|
42
27
|
| `search_snippets` | Search snippets by keyword, use case, or CSS technique |
|
|
43
28
|
| `get_snippet` | Get full CSS source, metadata, and usage example |
|
|
44
|
-
| `recommend_snippet` | Describe a UI problem, get best matching snippets
|
|
29
|
+
| `recommend_snippet` | Describe a UI problem, get best matching snippets |
|
|
45
30
|
| `list_pattern_families` | List all 55 pattern families with counts |
|
|
46
31
|
| `search_patterns` | Search 212 UI patterns by intent, family, or tier |
|
|
47
|
-
| `get_pattern` | Get full pattern HTML
|
|
32
|
+
| `get_pattern` | Get full pattern HTML with component token references |
|
|
33
|
+
| `list_templates` | List all page templates by category |
|
|
34
|
+
| `search_templates` | Search templates by keyword, category, or style |
|
|
35
|
+
| `get_template` | Get full standalone HTML for a page template |
|
|
36
|
+
| `setup_tokens` | Get token CSS files to write into your project (no CDN needed) |
|
|
37
|
+
| `recommend_token_mapping` | Analyze your project tokens and suggest --ws-* mapping |
|
|
38
|
+
|
|
39
|
+
## 3-Layer Token Architecture
|
|
40
|
+
|
|
41
|
+
Patterns use semantic CSS custom properties via a 3-layer system:
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
Host Tokens (your project) → WebSpire Alias Tokens → Component Tokens → Markup
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Setup via MCP
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
> setup_tokens()
|
|
51
|
+
// Returns webspire-tokens.css + webspire-components.css
|
|
52
|
+
// AI agent writes them into your project
|
|
53
|
+
|
|
54
|
+
> setup_tokens({ components: ["hero", "cta", "pricing"] })
|
|
55
|
+
// Only includes tokens for the families you use
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Pattern Markup
|
|
59
|
+
|
|
60
|
+
```html
|
|
61
|
+
<section class="ws-cta bg-[var(--ws-cta-bg)] py-20">
|
|
62
|
+
<h2 class="text-[var(--ws-cta-text)] text-3xl font-bold">Title</h2>
|
|
63
|
+
<a class="bg-[var(--ws-cta-action-bg)] text-[var(--ws-cta-action-text)]
|
|
64
|
+
hover:bg-[var(--ws-cta-action-bg-hover)] rounded-lg px-5 py-3">
|
|
65
|
+
Get started
|
|
66
|
+
</a>
|
|
67
|
+
</section>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Customize
|
|
71
|
+
|
|
72
|
+
```css
|
|
73
|
+
:root {
|
|
74
|
+
--ws-color-primary: #your-brand-color;
|
|
75
|
+
--ws-color-primary-hover: #your-brand-darker;
|
|
76
|
+
}
|
|
77
|
+
```
|
|
48
78
|
|
|
49
79
|
## Available Resources
|
|
50
80
|
|
|
51
81
|
| URI | Description |
|
|
52
82
|
|-----|-------------|
|
|
53
|
-
| `webspire://categories` |
|
|
54
|
-
| `webspire://category/{name}` | Snippets in a category
|
|
55
|
-
| `webspire://snippet/{id}` | Full snippet data including CSS
|
|
56
|
-
| `webspire://patterns` | All
|
|
57
|
-
| `webspire://pattern/{id}` | Full pattern data including HTML
|
|
83
|
+
| `webspire://categories` | Snippet categories with counts |
|
|
84
|
+
| `webspire://category/{name}` | Snippets in a category |
|
|
85
|
+
| `webspire://snippet/{id}` | Full snippet data including CSS |
|
|
86
|
+
| `webspire://patterns` | All patterns with brief metadata |
|
|
87
|
+
| `webspire://pattern/{id}` | Full pattern data including HTML |
|
|
88
|
+
| `webspire://templates` | All templates with brief metadata |
|
|
89
|
+
| `webspire://template/{id}` | Full template data including HTML |
|
|
58
90
|
|
|
59
91
|
## Content
|
|
60
92
|
|
|
61
93
|
### CSS Snippets (49)
|
|
62
94
|
|
|
63
|
-
Effects that Tailwind v4 can't do natively:
|
|
64
|
-
|
|
65
|
-
- **glass** (5) — Frosted, subtle, bold, colored, dark glassmorphism
|
|
66
|
-
- **animations** (7) — Fade, slide, scale, blur, stagger, pulse, infinite scroll
|
|
67
|
-
- **easing** (1) — Spring, bounce, snap easing tokens
|
|
68
|
-
- **scroll** (8) — Parallax, reveal, progress bar, snap, sticky header
|
|
69
|
-
- **decorative** (11) — Aurora, gradient mesh, neon glow, noise, orbs, shimmer
|
|
70
|
-
- **interactions** (11) — Hover lift, ripple, flip card, tilt, magnetic, focus ring
|
|
71
|
-
- **text** (6) — Fluid size, gradient text, typewriter, truncate, balance
|
|
95
|
+
Effects that Tailwind v4 can't do natively: glass, animations, easing, scroll, decorative, interactions, text.
|
|
72
96
|
|
|
73
97
|
### UI Patterns (212)
|
|
74
98
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
accordion, auth, avatar, badge, banner, bento, blog, breadcrumb, callout, cards, checkout, code-preview, comments, comparison, contact, cookie-consent, cta, dashboard, description-list, divider, empty-state, error, faq, features, file-tree, footer, forms, gallery, hero, kbd, link-card, logo-cloud, modal, navbar, newsletter, onboarding, pagination, popup, pricing, product-card, property-table, quote, related-articles, see-also, sidebar, social-proof, stats, steps, tabs, team, testimonials, and more.
|
|
99
|
+
55 families across Page Sections and Content Elements — all using `--ws-*` component tokens.
|
|
78
100
|
|
|
79
101
|
### Page Templates (18)
|
|
80
102
|
|
|
81
|
-
Complete
|
|
82
|
-
|
|
83
|
-
## Search Features
|
|
84
|
-
|
|
85
|
-
- **Synonym expansion**: "blur" also matches glass/frosted snippets
|
|
86
|
-
- **Stemming**: "animations" matches "animated", "animate"
|
|
87
|
-
- **Multi-field scoring**: Weighted matches across title, description, use cases, tags, classes, IDs
|
|
88
|
-
- **Filters**: Category, tags, dark mode support, responsive support, reduced motion
|
|
103
|
+
Complete standalone pages: SaaS, agency, portfolio, shop, company — with Tailwind CDN.
|
|
89
104
|
|
|
90
105
|
## Programmatic Usage
|
|
91
106
|
|
|
@@ -95,12 +110,8 @@ import { loadRegistry, searchSnippets } from '@webspire/mcp/registry';
|
|
|
95
110
|
const registry = await loadRegistry();
|
|
96
111
|
const results = searchSnippets(registry, {
|
|
97
112
|
query: 'glass card hover',
|
|
98
|
-
category: 'glass',
|
|
99
113
|
darkMode: true,
|
|
100
|
-
limit: 5,
|
|
101
114
|
});
|
|
102
115
|
```
|
|
103
116
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
MIT
|
|
117
|
+
Docs: https://webspire.de/tokens
|
package/data/registry.json
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import { dirname, resolve } from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
2
5
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
6
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
7
|
import { registerResources, registerTools } from './handlers.js';
|
|
8
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const pkg = JSON.parse(readFileSync(resolve(__dirname, '..', 'package.json'), 'utf-8'));
|
|
5
10
|
const args = process.argv.slice(2);
|
|
6
11
|
const urlIdx = args.indexOf('--registry-url');
|
|
7
12
|
const fileIdx = args.indexOf('--registry-file');
|
|
@@ -11,7 +16,7 @@ const registryOptions = {
|
|
|
11
16
|
};
|
|
12
17
|
const server = new McpServer({
|
|
13
18
|
name: 'webspire',
|
|
14
|
-
version:
|
|
19
|
+
version: pkg.version,
|
|
15
20
|
});
|
|
16
21
|
registerTools(server, registryOptions);
|
|
17
22
|
registerResources(server, registryOptions);
|
package/dist/registration.js
CHANGED
|
@@ -404,8 +404,14 @@ export function registerToolsWithProvider(server, getRegistry) {
|
|
|
404
404
|
});
|
|
405
405
|
server.tool('search_templates', 'Search Webspire page templates by keyword, category, or style.', {
|
|
406
406
|
query: z.string().describe('Search query, e.g. "saas landing", "portfolio dark", "shop"'),
|
|
407
|
-
category: z
|
|
408
|
-
|
|
407
|
+
category: z
|
|
408
|
+
.string()
|
|
409
|
+
.optional()
|
|
410
|
+
.describe('Filter by category, e.g. saas-landing, agency, shop'),
|
|
411
|
+
style: z
|
|
412
|
+
.string()
|
|
413
|
+
.optional()
|
|
414
|
+
.describe('Filter by style, e.g. modern, bold, minimal, corporate'),
|
|
409
415
|
}, async ({ query, category, style }) => {
|
|
410
416
|
const registry = await getRegistry();
|
|
411
417
|
let templates = registry.templates ?? [];
|
|
@@ -416,7 +422,15 @@ export function registerToolsWithProvider(server, getRegistry) {
|
|
|
416
422
|
const terms = query.toLowerCase().split(/\s+/).filter(Boolean);
|
|
417
423
|
const results = templates
|
|
418
424
|
.map((t) => {
|
|
419
|
-
const haystack = [
|
|
425
|
+
const haystack = [
|
|
426
|
+
t.title,
|
|
427
|
+
t.summary,
|
|
428
|
+
t.description ?? '',
|
|
429
|
+
t.category,
|
|
430
|
+
t.style,
|
|
431
|
+
...t.tags,
|
|
432
|
+
...t.sections,
|
|
433
|
+
]
|
|
420
434
|
.join(' ')
|
|
421
435
|
.toLowerCase();
|
|
422
436
|
const score = terms.reduce((acc, term) => acc + (haystack.includes(term) ? 1 : 0), 0);
|
|
@@ -469,22 +483,77 @@ export function registerToolsWithProvider(server, getRegistry) {
|
|
|
469
483
|
.optional()
|
|
470
484
|
.describe('CSS framework used in your project'),
|
|
471
485
|
}, async ({ project_tokens, framework }) => {
|
|
472
|
-
const lines = project_tokens
|
|
486
|
+
const lines = project_tokens
|
|
487
|
+
.split(/[;\n,]+/)
|
|
488
|
+
.map((s) => s.trim())
|
|
489
|
+
.filter(Boolean);
|
|
473
490
|
const mappings = [];
|
|
474
491
|
const TOKEN_HINTS = [
|
|
475
|
-
{
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
{
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
{
|
|
486
|
-
|
|
487
|
-
|
|
492
|
+
{
|
|
493
|
+
patterns: [/brand|primary|main|accent-color/i],
|
|
494
|
+
wsToken: '--ws-color-primary',
|
|
495
|
+
description: 'Primary/brand color',
|
|
496
|
+
},
|
|
497
|
+
{
|
|
498
|
+
patterns: [/brand.*hover|primary.*hover|primary.*dark/i],
|
|
499
|
+
wsToken: '--ws-color-primary-hover',
|
|
500
|
+
description: 'Primary hover state',
|
|
501
|
+
},
|
|
502
|
+
{
|
|
503
|
+
patterns: [/brand.*light|primary.*light|primary.*50|brand.*50/i],
|
|
504
|
+
wsToken: '--ws-color-primary-soft',
|
|
505
|
+
description: 'Primary soft background',
|
|
506
|
+
},
|
|
507
|
+
{
|
|
508
|
+
patterns: [/secondary|accent(?!-color)/i],
|
|
509
|
+
wsToken: '--ws-color-accent',
|
|
510
|
+
description: 'Secondary/accent color',
|
|
511
|
+
},
|
|
512
|
+
{
|
|
513
|
+
patterns: [/^bg$|background(?!.*secondary)|surface(?!.*alt)/i],
|
|
514
|
+
wsToken: '--ws-color-surface',
|
|
515
|
+
description: 'Page background',
|
|
516
|
+
},
|
|
517
|
+
{
|
|
518
|
+
patterns: [/bg.*secondary|bg.*subtle|bg.*muted|surface.*alt|bg.*light/i],
|
|
519
|
+
wsToken: '--ws-color-surface-alt',
|
|
520
|
+
description: 'Subtle background',
|
|
521
|
+
},
|
|
522
|
+
{
|
|
523
|
+
patterns: [/^text$|text.*primary|foreground(?!.*muted)/i],
|
|
524
|
+
wsToken: '--ws-color-text',
|
|
525
|
+
description: 'Primary text color',
|
|
526
|
+
},
|
|
527
|
+
{
|
|
528
|
+
patterns: [/text.*secondary|text.*soft|text.*muted|muted.*foreground/i],
|
|
529
|
+
wsToken: '--ws-color-text-muted',
|
|
530
|
+
description: 'Muted text color',
|
|
531
|
+
},
|
|
532
|
+
{
|
|
533
|
+
patterns: [/border(?!.*strong)|divider/i],
|
|
534
|
+
wsToken: '--ws-color-border',
|
|
535
|
+
description: 'Default border',
|
|
536
|
+
},
|
|
537
|
+
{
|
|
538
|
+
patterns: [/success|green|positive/i],
|
|
539
|
+
wsToken: '--ws-color-success',
|
|
540
|
+
description: 'Success color',
|
|
541
|
+
},
|
|
542
|
+
{
|
|
543
|
+
patterns: [/warning|amber|yellow|caution/i],
|
|
544
|
+
wsToken: '--ws-color-warning',
|
|
545
|
+
description: 'Warning color',
|
|
546
|
+
},
|
|
547
|
+
{
|
|
548
|
+
patterns: [/danger|error|red|destructive/i],
|
|
549
|
+
wsToken: '--ws-color-danger',
|
|
550
|
+
description: 'Danger/error color',
|
|
551
|
+
},
|
|
552
|
+
{
|
|
553
|
+
patterns: [/radius|rounded|corner/i],
|
|
554
|
+
wsToken: '--ws-radius-md',
|
|
555
|
+
description: 'Border radius',
|
|
556
|
+
},
|
|
488
557
|
];
|
|
489
558
|
for (const line of lines) {
|
|
490
559
|
const [rawName] = line.split(':').map((s) => s.trim());
|