@monoharada/wcf-mcp 0.1.0 → 0.1.2
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 +83 -10
- package/bin.mjs +108 -2
- package/core.mjs +1643 -0
- package/data/custom-elements.json +13055 -6859
- package/data/design-tokens.json +2422 -0
- package/data/guidelines-index.json +5914 -0
- package/data/install-registry.json +52 -0
- package/package.json +2 -1
- package/server.mjs +26 -624
- package/validator.mjs +174 -5
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# @
|
|
1
|
+
# @monoharada/wcf-mcp
|
|
2
2
|
|
|
3
3
|
web-components-factory デザインシステム用の MCP (Model Context Protocol) サーバー。
|
|
4
4
|
|
|
@@ -9,7 +9,7 @@ web-components-factory デザインシステム用の MCP (Model Context Protoco
|
|
|
9
9
|
### npx で起動(クローン不要)
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
npx @
|
|
12
|
+
npx @monoharada/wcf-mcp
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
### Claude Desktop で使う
|
|
@@ -21,7 +21,7 @@ npx @anthropic/wcf-mcp
|
|
|
21
21
|
"mcpServers": {
|
|
22
22
|
"wcf": {
|
|
23
23
|
"command": "npx",
|
|
24
|
-
"args": ["@
|
|
24
|
+
"args": ["@monoharada/wcf-mcp"]
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
}
|
|
@@ -30,17 +30,39 @@ npx @anthropic/wcf-mcp
|
|
|
30
30
|
### Claude Code で使う
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
|
-
claude mcp add wcf -- npx @
|
|
33
|
+
claude mcp add wcf -- npx @monoharada/wcf-mcp
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
### Cursor で使う
|
|
37
|
+
|
|
38
|
+
`.cursor/mcp.json` に追加:
|
|
39
|
+
|
|
40
|
+
```json
|
|
41
|
+
{
|
|
42
|
+
"mcpServers": {
|
|
43
|
+
"wcf": {
|
|
44
|
+
"command": "npx",
|
|
45
|
+
"args": ["@monoharada/wcf-mcp"]
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## 提供ツール(13個)
|
|
52
|
+
|
|
53
|
+
### ガードレール
|
|
54
|
+
|
|
55
|
+
| ツール | 説明 |
|
|
56
|
+
|--------|------|
|
|
57
|
+
| `get_design_system_overview` | 最初に呼ぶ前提情報(カテゴリ別コンポーネント数、利用可能パターン、推奨ワークフロー、IDE設定テンプレート)を返す |
|
|
37
58
|
|
|
38
59
|
### コンポーネント検索・API
|
|
39
60
|
|
|
40
61
|
| ツール | 説明 |
|
|
41
62
|
|--------|------|
|
|
42
|
-
| `list_components` |
|
|
43
|
-
| `
|
|
63
|
+
| `list_components` | カテゴリ/クエリ/limit/offset でコンポーネントを段階的に取得(互換維持のため limit 未指定時は全件) |
|
|
64
|
+
| `search_icons` | アイコン名をキーワード検索し、usage example を返す |
|
|
65
|
+
| `get_component_api` | tagName or className で属性・スロット・イベント・CSS Parts・CSS Custom Properties を取得(`relatedComponents` を含む) |
|
|
44
66
|
| `generate_usage_snippet` | コンポーネントの最小限 HTML スニペットを生成 |
|
|
45
67
|
| `get_install_recipe` | componentId・依存関係・define関数・インストールコマンドを取得 |
|
|
46
68
|
|
|
@@ -48,7 +70,7 @@ claude mcp add wcf -- npx @anthropic/wcf-mcp
|
|
|
48
70
|
|
|
49
71
|
| ツール | 説明 |
|
|
50
72
|
|--------|------|
|
|
51
|
-
| `validate_markup` | HTML
|
|
73
|
+
| `validate_markup` | HTML スニペットを検証し、未知要素(error)・未知属性(warning)・禁止属性/トークン誤用/`aria-live`・`role="alert"` の誤用(warning)を検出し、可能な場合は `suggestion` を返す |
|
|
52
74
|
|
|
53
75
|
### UI パターン
|
|
54
76
|
|
|
@@ -58,9 +80,58 @@ claude mcp add wcf -- npx @anthropic/wcf-mcp
|
|
|
58
80
|
| `get_pattern_recipe` | パターンの完全レシピ(必要コンポーネント・依存解決・HTML)を取得 |
|
|
59
81
|
| `generate_pattern_snippet` | パターンの HTML スニペットを生成 |
|
|
60
82
|
|
|
83
|
+
### トークン・ガイドライン検索
|
|
84
|
+
|
|
85
|
+
| ツール | 説明 |
|
|
86
|
+
|--------|------|
|
|
87
|
+
| `get_design_tokens` | デザイントークンを type/category/query で検索 |
|
|
88
|
+
| `get_accessibility_docs` | component/topic/wcagLevel で A11y チェックリストとガイドライン要点を検索(`topic=all` では両ソースを混在返却) |
|
|
89
|
+
| `search_guidelines` | ガイドライン(topic/query)をスコア付きで検索 |
|
|
90
|
+
|
|
91
|
+
## transport
|
|
92
|
+
|
|
93
|
+
標準は stdio です。HTTP transport も利用できます(localhost のみ)。
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
npx @monoharada/wcf-mcp --transport=http --port=3100
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
- bind: `127.0.0.1`
|
|
100
|
+
- endpoint: `http://127.0.0.1:3100/mcp`
|
|
101
|
+
|
|
102
|
+
## structuredContent rollback
|
|
103
|
+
|
|
104
|
+
`get_component_api` / `get_design_tokens` / `get_accessibility_docs` / `search_guidelines` は通常 `structuredContent` を返します。
|
|
105
|
+
|
|
106
|
+
- 100KB 制限を超える場合は自動的に `structuredContent` を省略し、`content` のみ返します
|
|
107
|
+
- 緊急切り戻し時は環境変数 `WCF_MCP_DISABLE_STRUCTURED_CONTENT=1` を設定してください
|
|
108
|
+
|
|
109
|
+
例:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
WCF_MCP_DISABLE_STRUCTURED_CONTENT=1 npx @monoharada/wcf-mcp
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Claude Desktop 設定例:
|
|
116
|
+
|
|
117
|
+
```json
|
|
118
|
+
{
|
|
119
|
+
"mcpServers": {
|
|
120
|
+
"wcf": {
|
|
121
|
+
"command": "npx",
|
|
122
|
+
"args": ["@monoharada/wcf-mcp"],
|
|
123
|
+
"env": {
|
|
124
|
+
"WCF_MCP_DISABLE_STRUCTURED_CONTENT": "1"
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
61
131
|
## prefix パラメータ
|
|
62
132
|
|
|
63
133
|
全ツールで `prefix` パラメータをサポート。デフォルトは `dads`(例: `dads-button`)。
|
|
134
|
+
`prefix` は最大64文字まで使用され、超過分は切り詰められます(例: 200文字指定 -> 先頭64文字を採用)。
|
|
64
135
|
|
|
65
136
|
カスタム prefix を指定すると、出力のタグ名が自動変換されます:
|
|
66
137
|
|
|
@@ -115,7 +186,6 @@ prefix: "myui" → dads-button → myui-button
|
|
|
115
186
|
"severity": "warning",
|
|
116
187
|
"code": "unknownAttribute",
|
|
117
188
|
"message": "Unknown attribute on <dads-button>: foo",
|
|
118
|
-
"tagName": "dads-button",
|
|
119
189
|
"attrName": "foo"
|
|
120
190
|
}
|
|
121
191
|
]
|
|
@@ -148,13 +218,16 @@ npm run mcp:check # データが最新かチェック(CI用)
|
|
|
148
218
|
```
|
|
149
219
|
packages/mcp-server/
|
|
150
220
|
├── bin.mjs # エントリポイント (#!/usr/bin/env node)
|
|
221
|
+
├── core.mjs # ツール定義・共通ロジック
|
|
151
222
|
├── server.mjs # MCP サーバー本体
|
|
152
223
|
├── validator.mjs # HTML バリデーター
|
|
153
224
|
├── package.json # npm パッケージ定義
|
|
154
225
|
└── data/ # バンドルデータ (npm run mcp:build で生成)
|
|
155
226
|
├── custom-elements.json
|
|
156
227
|
├── install-registry.json
|
|
157
|
-
|
|
228
|
+
├── pattern-registry.json
|
|
229
|
+
├── design-tokens.json
|
|
230
|
+
└── guidelines-index.json
|
|
158
231
|
```
|
|
159
232
|
|
|
160
233
|
## 要件
|
package/bin.mjs
CHANGED
|
@@ -1,7 +1,113 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* bin.mjs — CLI entry-point for the wcf-mcp server.
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* wcf-mcp # stdio (default)
|
|
7
|
+
* wcf-mcp --transport=http # HTTP on 127.0.0.1:3100
|
|
8
|
+
* wcf-mcp --transport=http --port=4000
|
|
9
|
+
*/
|
|
3
10
|
|
|
4
|
-
|
|
11
|
+
import { createServer } from './server.mjs';
|
|
12
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
13
|
+
|
|
14
|
+
const USAGE = [
|
|
15
|
+
'Usage:',
|
|
16
|
+
' wcf-mcp',
|
|
17
|
+
' wcf-mcp --transport=stdio',
|
|
18
|
+
' wcf-mcp --transport=http [--port=3100]',
|
|
19
|
+
' wcf-mcp --help',
|
|
20
|
+
].join('\n');
|
|
21
|
+
|
|
22
|
+
function parseArgs(argv) {
|
|
23
|
+
let transport = 'stdio';
|
|
24
|
+
let port = 3100;
|
|
25
|
+
|
|
26
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
27
|
+
const arg = argv[index];
|
|
28
|
+
if (arg === '--help' || arg === '-h') {
|
|
29
|
+
return { help: true, transport, port };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (arg === '--transport') {
|
|
33
|
+
const value = argv[index + 1];
|
|
34
|
+
if (!value || value.startsWith('--')) {
|
|
35
|
+
throw new Error('--transport requires a value (stdio|http)');
|
|
36
|
+
}
|
|
37
|
+
transport = value;
|
|
38
|
+
index += 1;
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (arg.startsWith('--transport=')) {
|
|
43
|
+
transport = arg.slice('--transport='.length);
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (arg === '--port') {
|
|
48
|
+
const value = argv[index + 1];
|
|
49
|
+
if (!value || value.startsWith('--')) {
|
|
50
|
+
throw new Error('--port requires a number between 1 and 65535');
|
|
51
|
+
}
|
|
52
|
+
port = Number(value);
|
|
53
|
+
index += 1;
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (arg.startsWith('--port=')) {
|
|
58
|
+
port = Number(arg.slice('--port='.length));
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
throw new Error(`Unknown argument: ${arg}`);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (transport !== 'stdio' && transport !== 'http') {
|
|
66
|
+
throw new Error(`Invalid transport: ${transport} (expected: stdio or http)`);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
|
70
|
+
throw new Error(`Invalid port: ${String(port)} (expected: integer 1-65535)`);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return { help: false, transport, port };
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async function main() {
|
|
77
|
+
let parsed;
|
|
78
|
+
try {
|
|
79
|
+
parsed = parseArgs(process.argv.slice(2));
|
|
80
|
+
} catch (error) {
|
|
81
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
82
|
+
console.error('');
|
|
83
|
+
console.error(USAGE);
|
|
84
|
+
process.exit(1);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (parsed.help) {
|
|
88
|
+
console.log(USAGE);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const { server } = await createServer();
|
|
93
|
+
|
|
94
|
+
if (parsed.transport === 'http') {
|
|
95
|
+
const { StreamableHTTPServerTransport } = await import(
|
|
96
|
+
'@modelcontextprotocol/sdk/server/streamableHttp.js'
|
|
97
|
+
);
|
|
98
|
+
const { createServer: createHttpServer } = await import('node:http');
|
|
99
|
+
const httpTransport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined });
|
|
100
|
+
await server.connect(httpTransport);
|
|
101
|
+
const httpServer = createHttpServer((req, res) => httpTransport.handleRequest(req, res));
|
|
102
|
+
httpServer.listen(parsed.port, '127.0.0.1', () => {
|
|
103
|
+
console.error(`MCP HTTP server listening on http://127.0.0.1:${parsed.port}/mcp`);
|
|
104
|
+
});
|
|
105
|
+
} else {
|
|
106
|
+
await server.connect(new StdioServerTransport());
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
main().catch((err) => {
|
|
5
111
|
console.error(err);
|
|
6
112
|
process.exit(1);
|
|
7
113
|
});
|