alus-ui-mcp 0.1.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 +58 -0
- package/dist/index.js +1221 -0
- package/package.json +71 -0
package/README.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# alus-ui-mcp
|
|
2
|
+
|
|
3
|
+
> MCP stdio server for the [alus-ui](https://www.npmjs.com/package/alus-ui) Svelte 5 component library.
|
|
4
|
+
|
|
5
|
+
Gives LLMs (Claude, Cursor, etc.) direct access to alus-ui component source, demos, exports, and utilities via the [Model Context Protocol](https://modelcontextprotocol.io).
|
|
6
|
+
|
|
7
|
+
## Usage
|
|
8
|
+
|
|
9
|
+
### npx (no install)
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npx alus-ui-mcp
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### Claude Code
|
|
16
|
+
|
|
17
|
+
Add to `.mcp.json` at your project root:
|
|
18
|
+
|
|
19
|
+
```json
|
|
20
|
+
{
|
|
21
|
+
"mcpServers": {
|
|
22
|
+
"alus-ui": {
|
|
23
|
+
"type": "stdio",
|
|
24
|
+
"command": "npx",
|
|
25
|
+
"args": ["alus-ui-mcp"]
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Remote HTTP
|
|
32
|
+
|
|
33
|
+
The production Cloudflare deployment exposes `/mcp`. Point your client to:
|
|
34
|
+
|
|
35
|
+
```json
|
|
36
|
+
{
|
|
37
|
+
"mcpServers": {
|
|
38
|
+
"alus-ui": {
|
|
39
|
+
"url": "https://alus.lkmn.link/mcp"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Tools
|
|
46
|
+
|
|
47
|
+
| Tool | Description |
|
|
48
|
+
|---|---|
|
|
49
|
+
| `alus_list_components` | Browse all 150+ components by category |
|
|
50
|
+
| `alus_get_component` | Read full `.svelte` + `index.ts` source |
|
|
51
|
+
| `alus_search_components` | Full-text search across all source files |
|
|
52
|
+
| `alus_get_component_demo` | Read showcase demo page |
|
|
53
|
+
| `alus_list_exports` | Show full public API (`components/index.ts`) |
|
|
54
|
+
| `alus_get_utils` | Read a11y/form utility module source |
|
|
55
|
+
|
|
56
|
+
## License
|
|
57
|
+
|
|
58
|
+
MIT — part of the [alus](https://github.com/Hanivan/alus) monorepo.
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,1221 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __export = (target, all) => {
|
|
4
|
+
for (var name in all)
|
|
5
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
// ../../node_modules/.pnpm/@tmcp+adapter-valibot@0.1.6_tmcp@1.19.4_typescript@5.9.3__valibot@1.4.1_typescript@5.9.3_/node_modules/@tmcp/adapter-valibot/src/index.js
|
|
9
|
+
import { JsonSchemaAdapter } from "tmcp/adapter";
|
|
10
|
+
|
|
11
|
+
// ../../node_modules/.pnpm/@valibot+to-json-schema@1.7.0_valibot@1.4.1_typescript@5.9.3_/node_modules/@valibot/to-json-schema/dist/index.mjs
|
|
12
|
+
function addError(errors, message) {
|
|
13
|
+
if (errors) {
|
|
14
|
+
errors.push(message);
|
|
15
|
+
return errors;
|
|
16
|
+
}
|
|
17
|
+
return [message];
|
|
18
|
+
}
|
|
19
|
+
var ESCAPE_REGEX = /[.*+?^${}()|[\]\\]/g;
|
|
20
|
+
function escapeRegExp(string2) {
|
|
21
|
+
return string2.replace(ESCAPE_REGEX, "\\$&");
|
|
22
|
+
}
|
|
23
|
+
function handleError(message, config) {
|
|
24
|
+
switch (config?.errorMode) {
|
|
25
|
+
case "ignore":
|
|
26
|
+
break;
|
|
27
|
+
case "warn":
|
|
28
|
+
console.warn(message);
|
|
29
|
+
break;
|
|
30
|
+
default:
|
|
31
|
+
throw new Error(message);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function isJsonConstValue(value) {
|
|
35
|
+
return typeof value === "boolean" || typeof value === "number" && Number.isFinite(value) || typeof value === "string";
|
|
36
|
+
}
|
|
37
|
+
function isJsonEnumValues(values) {
|
|
38
|
+
return values.every(isJsonConstValue);
|
|
39
|
+
}
|
|
40
|
+
function convertAction(jsonSchema, valibotAction, config) {
|
|
41
|
+
if (config?.ignoreActions?.includes(valibotAction.type)) return jsonSchema;
|
|
42
|
+
let errors;
|
|
43
|
+
switch (valibotAction.type) {
|
|
44
|
+
case "base64":
|
|
45
|
+
jsonSchema.contentEncoding = "base64";
|
|
46
|
+
break;
|
|
47
|
+
case "bic":
|
|
48
|
+
case "cuid2":
|
|
49
|
+
case "decimal":
|
|
50
|
+
case "digits":
|
|
51
|
+
case "domain":
|
|
52
|
+
case "emoji":
|
|
53
|
+
case "hash":
|
|
54
|
+
case "hexadecimal":
|
|
55
|
+
case "hex_color":
|
|
56
|
+
case "isrc":
|
|
57
|
+
case "iso_time_second":
|
|
58
|
+
case "iso_week":
|
|
59
|
+
case "mac":
|
|
60
|
+
case "mac48":
|
|
61
|
+
case "mac64":
|
|
62
|
+
case "nanoid":
|
|
63
|
+
case "octal":
|
|
64
|
+
case "slug":
|
|
65
|
+
case "ulid":
|
|
66
|
+
if (jsonSchema.pattern) errors = addError(errors, `The "${valibotAction.type}" action is not supported in combination with another regex action.`);
|
|
67
|
+
else jsonSchema.pattern = valibotAction.requirement.source;
|
|
68
|
+
break;
|
|
69
|
+
case "description":
|
|
70
|
+
jsonSchema.description = valibotAction.description;
|
|
71
|
+
break;
|
|
72
|
+
case "email":
|
|
73
|
+
case "rfc_email":
|
|
74
|
+
jsonSchema.format = "email";
|
|
75
|
+
break;
|
|
76
|
+
case "ends_with":
|
|
77
|
+
if (jsonSchema.pattern) errors = addError(errors, `The "${valibotAction.type}" action is not supported in combination with another regex action.`);
|
|
78
|
+
else jsonSchema.pattern = `${escapeRegExp(valibotAction.requirement)}$`;
|
|
79
|
+
break;
|
|
80
|
+
case "empty":
|
|
81
|
+
if (jsonSchema.type === "array") jsonSchema.maxItems = 0;
|
|
82
|
+
else {
|
|
83
|
+
if (jsonSchema.type !== "string") errors = addError(errors, `The "${valibotAction.type}" action is not supported on type "${jsonSchema.type}".`);
|
|
84
|
+
jsonSchema.maxLength = 0;
|
|
85
|
+
}
|
|
86
|
+
break;
|
|
87
|
+
case "entries":
|
|
88
|
+
jsonSchema.minProperties = valibotAction.requirement;
|
|
89
|
+
jsonSchema.maxProperties = valibotAction.requirement;
|
|
90
|
+
break;
|
|
91
|
+
case "examples":
|
|
92
|
+
if (Array.isArray(jsonSchema.examples)) jsonSchema.examples = [...jsonSchema.examples, ...valibotAction.examples];
|
|
93
|
+
else jsonSchema.examples = valibotAction.examples;
|
|
94
|
+
break;
|
|
95
|
+
case "gt_value":
|
|
96
|
+
if (jsonSchema.type !== "number" && jsonSchema.type !== "integer") errors = addError(errors, `The "gt_value" action is not supported on type "${jsonSchema.type}".`);
|
|
97
|
+
if (config?.target === "openapi-3.0") {
|
|
98
|
+
errors = addError(errors, 'The "gt_value" action is not supported for OpenAPI 3.0.');
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
jsonSchema.exclusiveMinimum = valibotAction.requirement;
|
|
102
|
+
break;
|
|
103
|
+
case "includes":
|
|
104
|
+
if (jsonSchema.pattern) errors = addError(errors, `The "${valibotAction.type}" action is not supported in combination with another regex action.`);
|
|
105
|
+
else jsonSchema.pattern = escapeRegExp(valibotAction.requirement);
|
|
106
|
+
break;
|
|
107
|
+
case "integer":
|
|
108
|
+
jsonSchema.type = "integer";
|
|
109
|
+
break;
|
|
110
|
+
case "ipv4":
|
|
111
|
+
jsonSchema.format = "ipv4";
|
|
112
|
+
break;
|
|
113
|
+
case "ipv6":
|
|
114
|
+
jsonSchema.format = "ipv6";
|
|
115
|
+
break;
|
|
116
|
+
case "iso_date":
|
|
117
|
+
jsonSchema.format = "date";
|
|
118
|
+
break;
|
|
119
|
+
case "iso_date_time":
|
|
120
|
+
case "iso_timestamp":
|
|
121
|
+
jsonSchema.format = "date-time";
|
|
122
|
+
break;
|
|
123
|
+
case "iso_time":
|
|
124
|
+
jsonSchema.format = "time";
|
|
125
|
+
break;
|
|
126
|
+
case "jws_compact":
|
|
127
|
+
if (jsonSchema.pattern) errors = addError(errors, `The "${valibotAction.type}" action is not supported in combination with another regex action.`);
|
|
128
|
+
else jsonSchema.pattern = valibotAction.requirement.source;
|
|
129
|
+
break;
|
|
130
|
+
case "length":
|
|
131
|
+
if (jsonSchema.type === "array") {
|
|
132
|
+
jsonSchema.minItems = valibotAction.requirement;
|
|
133
|
+
jsonSchema.maxItems = valibotAction.requirement;
|
|
134
|
+
} else {
|
|
135
|
+
if (jsonSchema.type !== "string") errors = addError(errors, `The "${valibotAction.type}" action is not supported on type "${jsonSchema.type}".`);
|
|
136
|
+
jsonSchema.minLength = valibotAction.requirement;
|
|
137
|
+
jsonSchema.maxLength = valibotAction.requirement;
|
|
138
|
+
}
|
|
139
|
+
break;
|
|
140
|
+
case "lt_value":
|
|
141
|
+
if (jsonSchema.type !== "number" && jsonSchema.type !== "integer") errors = addError(errors, `The "lt_value" action is not supported on type "${jsonSchema.type}".`);
|
|
142
|
+
if (config?.target === "openapi-3.0") {
|
|
143
|
+
errors = addError(errors, 'The "lt_value" action is not supported for OpenAPI 3.0.');
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
jsonSchema.exclusiveMaximum = valibotAction.requirement;
|
|
147
|
+
break;
|
|
148
|
+
case "max_entries":
|
|
149
|
+
jsonSchema.maxProperties = valibotAction.requirement;
|
|
150
|
+
break;
|
|
151
|
+
case "max_length":
|
|
152
|
+
if (jsonSchema.type === "array") jsonSchema.maxItems = valibotAction.requirement;
|
|
153
|
+
else {
|
|
154
|
+
if (jsonSchema.type !== "string") errors = addError(errors, `The "${valibotAction.type}" action is not supported on type "${jsonSchema.type}".`);
|
|
155
|
+
jsonSchema.maxLength = valibotAction.requirement;
|
|
156
|
+
}
|
|
157
|
+
break;
|
|
158
|
+
case "max_value":
|
|
159
|
+
if (jsonSchema.type !== "number" && jsonSchema.type !== "integer") errors = addError(errors, `The "max_value" action is not supported on type "${jsonSchema.type}".`);
|
|
160
|
+
jsonSchema.maximum = valibotAction.requirement;
|
|
161
|
+
break;
|
|
162
|
+
case "metadata":
|
|
163
|
+
if (typeof valibotAction.metadata.title === "string") jsonSchema.title = valibotAction.metadata.title;
|
|
164
|
+
if (typeof valibotAction.metadata.description === "string") jsonSchema.description = valibotAction.metadata.description;
|
|
165
|
+
if (Array.isArray(valibotAction.metadata.examples)) if (Array.isArray(jsonSchema.examples)) jsonSchema.examples = [...jsonSchema.examples, ...valibotAction.metadata.examples];
|
|
166
|
+
else jsonSchema.examples = valibotAction.metadata.examples;
|
|
167
|
+
break;
|
|
168
|
+
case "min_entries":
|
|
169
|
+
jsonSchema.minProperties = valibotAction.requirement;
|
|
170
|
+
break;
|
|
171
|
+
case "min_length":
|
|
172
|
+
if (jsonSchema.type === "array") jsonSchema.minItems = valibotAction.requirement;
|
|
173
|
+
else {
|
|
174
|
+
if (jsonSchema.type !== "string") errors = addError(errors, `The "${valibotAction.type}" action is not supported on type "${jsonSchema.type}".`);
|
|
175
|
+
jsonSchema.minLength = valibotAction.requirement;
|
|
176
|
+
}
|
|
177
|
+
break;
|
|
178
|
+
case "min_value":
|
|
179
|
+
if (jsonSchema.type !== "number" && jsonSchema.type !== "integer") errors = addError(errors, `The "min_value" action is not supported on type "${jsonSchema.type}".`);
|
|
180
|
+
jsonSchema.minimum = valibotAction.requirement;
|
|
181
|
+
break;
|
|
182
|
+
case "multiple_of":
|
|
183
|
+
jsonSchema.multipleOf = valibotAction.requirement;
|
|
184
|
+
break;
|
|
185
|
+
case "non_empty":
|
|
186
|
+
if (jsonSchema.type === "array") jsonSchema.minItems = 1;
|
|
187
|
+
else {
|
|
188
|
+
if (jsonSchema.type !== "string") errors = addError(errors, `The "${valibotAction.type}" action is not supported on type "${jsonSchema.type}".`);
|
|
189
|
+
jsonSchema.minLength = 1;
|
|
190
|
+
}
|
|
191
|
+
break;
|
|
192
|
+
case "not_value":
|
|
193
|
+
if (!isJsonConstValue(valibotAction.requirement)) {
|
|
194
|
+
errors = addError(errors, 'The requirement of the "not_value" action is not JSON compatible.');
|
|
195
|
+
break;
|
|
196
|
+
}
|
|
197
|
+
if (config?.target === "openapi-3.0") jsonSchema.not = { enum: [valibotAction.requirement] };
|
|
198
|
+
else jsonSchema.not = { const: valibotAction.requirement };
|
|
199
|
+
break;
|
|
200
|
+
case "not_values":
|
|
201
|
+
if (!isJsonEnumValues(valibotAction.requirement)) {
|
|
202
|
+
errors = addError(errors, 'A requirement of the "not_values" action is not JSON compatible.');
|
|
203
|
+
break;
|
|
204
|
+
}
|
|
205
|
+
jsonSchema.not = { enum: valibotAction.requirement };
|
|
206
|
+
break;
|
|
207
|
+
case "regex":
|
|
208
|
+
if (valibotAction.requirement.flags) errors = addError(errors, "RegExp flags are not supported by JSON Schema.");
|
|
209
|
+
if (jsonSchema.pattern) errors = addError(errors, `The "${valibotAction.type}" action is not supported in combination with another regex action.`);
|
|
210
|
+
else jsonSchema.pattern = valibotAction.requirement.source;
|
|
211
|
+
break;
|
|
212
|
+
case "safe_integer":
|
|
213
|
+
jsonSchema.type = "integer";
|
|
214
|
+
if (typeof jsonSchema.minimum !== "number" || jsonSchema.minimum < Number.MIN_SAFE_INTEGER) jsonSchema.minimum = Number.MIN_SAFE_INTEGER;
|
|
215
|
+
if (typeof jsonSchema.maximum !== "number" || jsonSchema.maximum > Number.MAX_SAFE_INTEGER) jsonSchema.maximum = Number.MAX_SAFE_INTEGER;
|
|
216
|
+
break;
|
|
217
|
+
case "starts_with":
|
|
218
|
+
if (jsonSchema.pattern) errors = addError(errors, `The "${valibotAction.type}" action is not supported in combination with another regex action.`);
|
|
219
|
+
else jsonSchema.pattern = `^${escapeRegExp(valibotAction.requirement)}`;
|
|
220
|
+
break;
|
|
221
|
+
case "title":
|
|
222
|
+
jsonSchema.title = valibotAction.title;
|
|
223
|
+
break;
|
|
224
|
+
case "url":
|
|
225
|
+
jsonSchema.format = "uri";
|
|
226
|
+
break;
|
|
227
|
+
case "uuid":
|
|
228
|
+
jsonSchema.format = "uuid";
|
|
229
|
+
break;
|
|
230
|
+
case "value":
|
|
231
|
+
if (!isJsonConstValue(valibotAction.requirement)) {
|
|
232
|
+
errors = addError(errors, 'The requirement of the "value" action is not JSON compatible.');
|
|
233
|
+
break;
|
|
234
|
+
}
|
|
235
|
+
if (config?.target === "openapi-3.0") jsonSchema.enum = [valibotAction.requirement];
|
|
236
|
+
else jsonSchema.const = valibotAction.requirement;
|
|
237
|
+
break;
|
|
238
|
+
case "values":
|
|
239
|
+
if (!isJsonEnumValues(valibotAction.requirement)) {
|
|
240
|
+
errors = addError(errors, 'A requirement of the "values" action is not JSON compatible.');
|
|
241
|
+
break;
|
|
242
|
+
}
|
|
243
|
+
jsonSchema.enum = valibotAction.requirement;
|
|
244
|
+
break;
|
|
245
|
+
default:
|
|
246
|
+
errors = addError(errors, `The "${valibotAction.type}" action cannot be converted to JSON Schema.`);
|
|
247
|
+
}
|
|
248
|
+
if (config?.overrideAction) {
|
|
249
|
+
const actionOverride = config.overrideAction({
|
|
250
|
+
valibotAction,
|
|
251
|
+
jsonSchema,
|
|
252
|
+
errors
|
|
253
|
+
});
|
|
254
|
+
if (actionOverride) return { ...actionOverride };
|
|
255
|
+
}
|
|
256
|
+
if (errors) for (const message of errors) handleError(message, config);
|
|
257
|
+
return jsonSchema;
|
|
258
|
+
}
|
|
259
|
+
function flattenPipe(pipe2) {
|
|
260
|
+
return pipe2.flatMap((item) => "pipe" in item ? flattenPipe(item.pipe) : item);
|
|
261
|
+
}
|
|
262
|
+
var refCount = 0;
|
|
263
|
+
function convertSchema(jsonSchema, valibotSchema, config, context, skipRef = false) {
|
|
264
|
+
if (!skipRef) {
|
|
265
|
+
const referenceId = context.referenceMap.get(valibotSchema);
|
|
266
|
+
if (referenceId) {
|
|
267
|
+
jsonSchema.$ref = `#/$defs/${referenceId}`;
|
|
268
|
+
if (config?.overrideRef) {
|
|
269
|
+
const refOverride = config.overrideRef({
|
|
270
|
+
...context,
|
|
271
|
+
referenceId,
|
|
272
|
+
valibotSchema,
|
|
273
|
+
jsonSchema
|
|
274
|
+
});
|
|
275
|
+
if (refOverride) jsonSchema.$ref = refOverride;
|
|
276
|
+
}
|
|
277
|
+
return jsonSchema;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
if ("pipe" in valibotSchema) {
|
|
281
|
+
const flatPipe = flattenPipe(valibotSchema.pipe);
|
|
282
|
+
let startIndex = 0;
|
|
283
|
+
let stopIndex = flatPipe.length - 1;
|
|
284
|
+
if (config?.typeMode === "input") {
|
|
285
|
+
const inputStopIndex = flatPipe.slice(1).findIndex((item) => item.kind === "schema" || item.kind === "transformation" && (item.type === "find_item" || item.type === "parse_json" || item.type === "raw_transform" || item.type === "reduce_items" || item.type === "stringify_json" || item.type === "to_bigint" || item.type === "to_boolean" || item.type === "to_date" || item.type === "to_number" || item.type === "to_string" || item.type === "transform"));
|
|
286
|
+
if (inputStopIndex !== -1) stopIndex = inputStopIndex;
|
|
287
|
+
} else if (config?.typeMode === "output") {
|
|
288
|
+
const outputStartIndex = flatPipe.findLastIndex((item) => item.kind === "schema");
|
|
289
|
+
if (outputStartIndex !== -1) startIndex = outputStartIndex;
|
|
290
|
+
}
|
|
291
|
+
for (let index = startIndex; index <= stopIndex; index++) {
|
|
292
|
+
const valibotPipeItem = flatPipe[index];
|
|
293
|
+
if (valibotPipeItem.kind === "schema") {
|
|
294
|
+
if (index > startIndex) handleError('Set the "typeMode" config to "input" or "output" to convert pipelines with multiple schemas.', config);
|
|
295
|
+
jsonSchema = convertSchema(jsonSchema, valibotPipeItem, config, context, true);
|
|
296
|
+
} else jsonSchema = convertAction(jsonSchema, valibotPipeItem, config);
|
|
297
|
+
}
|
|
298
|
+
return jsonSchema;
|
|
299
|
+
}
|
|
300
|
+
let errors;
|
|
301
|
+
switch (valibotSchema.type) {
|
|
302
|
+
case "boolean":
|
|
303
|
+
jsonSchema.type = "boolean";
|
|
304
|
+
break;
|
|
305
|
+
case "null":
|
|
306
|
+
if (config?.target === "openapi-3.0") jsonSchema.enum = [null];
|
|
307
|
+
else jsonSchema.type = "null";
|
|
308
|
+
break;
|
|
309
|
+
case "number":
|
|
310
|
+
jsonSchema.type = "number";
|
|
311
|
+
break;
|
|
312
|
+
case "string":
|
|
313
|
+
jsonSchema.type = "string";
|
|
314
|
+
break;
|
|
315
|
+
case "array":
|
|
316
|
+
jsonSchema.type = "array";
|
|
317
|
+
jsonSchema.items = convertSchema({}, valibotSchema.item, config, context);
|
|
318
|
+
break;
|
|
319
|
+
case "tuple":
|
|
320
|
+
case "tuple_with_rest":
|
|
321
|
+
case "loose_tuple":
|
|
322
|
+
case "strict_tuple":
|
|
323
|
+
jsonSchema.type = "array";
|
|
324
|
+
if (config?.target === "openapi-3.0") {
|
|
325
|
+
jsonSchema.items = { anyOf: [] };
|
|
326
|
+
jsonSchema.minItems = valibotSchema.items.length;
|
|
327
|
+
for (const item of valibotSchema.items) jsonSchema.items.anyOf.push(convertSchema({}, item, config, context));
|
|
328
|
+
if (valibotSchema.type === "tuple_with_rest") jsonSchema.items.anyOf.push(convertSchema({}, valibotSchema.rest, config, context));
|
|
329
|
+
else if (valibotSchema.type === "strict_tuple" || valibotSchema.type === "tuple") jsonSchema.maxItems = valibotSchema.items.length;
|
|
330
|
+
} else if (config?.target === "draft-2020-12") {
|
|
331
|
+
jsonSchema.prefixItems = [];
|
|
332
|
+
jsonSchema.minItems = valibotSchema.items.length;
|
|
333
|
+
for (const item of valibotSchema.items) jsonSchema.prefixItems.push(convertSchema({}, item, config, context));
|
|
334
|
+
if (valibotSchema.type === "tuple_with_rest") jsonSchema.items = convertSchema({}, valibotSchema.rest, config, context);
|
|
335
|
+
else if (valibotSchema.type === "strict_tuple") jsonSchema.items = false;
|
|
336
|
+
} else {
|
|
337
|
+
jsonSchema.items = [];
|
|
338
|
+
jsonSchema.minItems = valibotSchema.items.length;
|
|
339
|
+
for (const item of valibotSchema.items) jsonSchema.items.push(convertSchema({}, item, config, context));
|
|
340
|
+
if (valibotSchema.type === "tuple_with_rest") jsonSchema.additionalItems = convertSchema({}, valibotSchema.rest, config, context);
|
|
341
|
+
else if (valibotSchema.type === "strict_tuple") jsonSchema.additionalItems = false;
|
|
342
|
+
}
|
|
343
|
+
break;
|
|
344
|
+
case "object":
|
|
345
|
+
case "object_with_rest":
|
|
346
|
+
case "loose_object":
|
|
347
|
+
case "strict_object":
|
|
348
|
+
jsonSchema.type = "object";
|
|
349
|
+
jsonSchema.properties = {};
|
|
350
|
+
jsonSchema.required = [];
|
|
351
|
+
for (const key in valibotSchema.entries) {
|
|
352
|
+
const entry = valibotSchema.entries[key];
|
|
353
|
+
jsonSchema.properties[key] = convertSchema({}, entry, config, context);
|
|
354
|
+
if (entry.type !== "exact_optional" && entry.type !== "nullish" && entry.type !== "optional") jsonSchema.required.push(key);
|
|
355
|
+
}
|
|
356
|
+
if (valibotSchema.type === "object_with_rest") jsonSchema.additionalProperties = convertSchema({}, valibotSchema.rest, config, context);
|
|
357
|
+
else if (valibotSchema.type === "strict_object") jsonSchema.additionalProperties = false;
|
|
358
|
+
break;
|
|
359
|
+
case "record":
|
|
360
|
+
if (config?.target === "openapi-3.0" && "pipe" in valibotSchema.key) errors = addError(errors, 'The "record" schema with a schema for the key that contains a "pipe" cannot be converted to JSON Schema.');
|
|
361
|
+
if (valibotSchema.key.type !== "string") errors = addError(errors, `The "record" schema with the "${valibotSchema.key.type}" schema for the key cannot be converted to JSON Schema.`);
|
|
362
|
+
jsonSchema.type = "object";
|
|
363
|
+
if (config?.target !== "openapi-3.0") jsonSchema.propertyNames = convertSchema({}, valibotSchema.key, config, context);
|
|
364
|
+
jsonSchema.additionalProperties = convertSchema({}, valibotSchema.value, config, context);
|
|
365
|
+
break;
|
|
366
|
+
case "any":
|
|
367
|
+
case "unknown":
|
|
368
|
+
break;
|
|
369
|
+
case "never":
|
|
370
|
+
jsonSchema.not = {};
|
|
371
|
+
break;
|
|
372
|
+
case "nullable":
|
|
373
|
+
case "nullish":
|
|
374
|
+
if (config?.target === "openapi-3.0") {
|
|
375
|
+
const innerSchema = convertSchema({}, valibotSchema.wrapped, config, context);
|
|
376
|
+
Object.assign(jsonSchema, innerSchema);
|
|
377
|
+
jsonSchema.nullable = true;
|
|
378
|
+
} else jsonSchema.anyOf = [convertSchema({}, valibotSchema.wrapped, config, context), { type: "null" }];
|
|
379
|
+
if (valibotSchema.default !== void 0) jsonSchema.default = typeof valibotSchema.default === "function" ? valibotSchema.default() : valibotSchema.default;
|
|
380
|
+
break;
|
|
381
|
+
case "exact_optional":
|
|
382
|
+
case "optional":
|
|
383
|
+
case "undefinedable":
|
|
384
|
+
jsonSchema = convertSchema(jsonSchema, valibotSchema.wrapped, config, context);
|
|
385
|
+
if (valibotSchema.default !== void 0) jsonSchema.default = typeof valibotSchema.default === "function" ? valibotSchema.default() : valibotSchema.default;
|
|
386
|
+
break;
|
|
387
|
+
case "literal":
|
|
388
|
+
if (typeof valibotSchema.literal !== "boolean" && typeof valibotSchema.literal !== "number" && typeof valibotSchema.literal !== "string") errors = addError(errors, 'The value of the "literal" schema is not JSON compatible.');
|
|
389
|
+
if (config?.target === "openapi-3.0") jsonSchema.enum = [valibotSchema.literal];
|
|
390
|
+
else jsonSchema.const = valibotSchema.literal;
|
|
391
|
+
break;
|
|
392
|
+
case "enum":
|
|
393
|
+
jsonSchema.enum = valibotSchema.options;
|
|
394
|
+
if (valibotSchema.options.every((option) => typeof option === "string")) jsonSchema.type = "string";
|
|
395
|
+
else if (valibotSchema.options.every((option) => typeof option === "number")) jsonSchema.type = "number";
|
|
396
|
+
else if (config?.target !== "openapi-3.0") jsonSchema.type = ["string", "number"];
|
|
397
|
+
break;
|
|
398
|
+
case "picklist": {
|
|
399
|
+
const hasInvalidOption = valibotSchema.options.some((option) => typeof option !== "number" && typeof option !== "string");
|
|
400
|
+
if (hasInvalidOption) errors = addError(errors, 'An option of the "picklist" schema is not JSON compatible.');
|
|
401
|
+
jsonSchema.enum = valibotSchema.options;
|
|
402
|
+
if (valibotSchema.options.every((option) => typeof option === "string")) jsonSchema.type = "string";
|
|
403
|
+
else if (valibotSchema.options.every((option) => typeof option === "number")) jsonSchema.type = "number";
|
|
404
|
+
else if (!hasInvalidOption && config?.target !== "openapi-3.0") jsonSchema.type = ["string", "number"];
|
|
405
|
+
break;
|
|
406
|
+
}
|
|
407
|
+
case "union":
|
|
408
|
+
jsonSchema.anyOf = valibotSchema.options.map((option) => convertSchema({}, option, config, context));
|
|
409
|
+
break;
|
|
410
|
+
case "variant":
|
|
411
|
+
jsonSchema.oneOf = valibotSchema.options.map((option) => convertSchema({}, option, config, context));
|
|
412
|
+
break;
|
|
413
|
+
case "intersect":
|
|
414
|
+
jsonSchema.allOf = valibotSchema.options.map((option) => convertSchema({}, option, config, context));
|
|
415
|
+
break;
|
|
416
|
+
case "lazy": {
|
|
417
|
+
let wrappedValibotSchema = context.getterMap.get(valibotSchema.getter);
|
|
418
|
+
if (!wrappedValibotSchema) {
|
|
419
|
+
wrappedValibotSchema = valibotSchema.getter(void 0);
|
|
420
|
+
context.getterMap.set(valibotSchema.getter, wrappedValibotSchema);
|
|
421
|
+
}
|
|
422
|
+
let referenceId = context.referenceMap.get(wrappedValibotSchema);
|
|
423
|
+
if (!referenceId) {
|
|
424
|
+
referenceId = `${refCount++}`;
|
|
425
|
+
context.referenceMap.set(wrappedValibotSchema, referenceId);
|
|
426
|
+
context.definitions[referenceId] = convertSchema({}, wrappedValibotSchema, config, context, true);
|
|
427
|
+
}
|
|
428
|
+
jsonSchema.$ref = `#/$defs/${referenceId}`;
|
|
429
|
+
if (config?.overrideRef) {
|
|
430
|
+
const refOverride = config.overrideRef({
|
|
431
|
+
...context,
|
|
432
|
+
referenceId,
|
|
433
|
+
valibotSchema: wrappedValibotSchema,
|
|
434
|
+
jsonSchema
|
|
435
|
+
});
|
|
436
|
+
if (refOverride) jsonSchema.$ref = refOverride;
|
|
437
|
+
}
|
|
438
|
+
break;
|
|
439
|
+
}
|
|
440
|
+
default:
|
|
441
|
+
errors = addError(errors, `The "${valibotSchema.type}" schema cannot be converted to JSON Schema.`);
|
|
442
|
+
}
|
|
443
|
+
if (config?.overrideSchema) {
|
|
444
|
+
const schemaOverride = config.overrideSchema({
|
|
445
|
+
...context,
|
|
446
|
+
referenceId: context.referenceMap.get(valibotSchema),
|
|
447
|
+
valibotSchema,
|
|
448
|
+
jsonSchema,
|
|
449
|
+
errors
|
|
450
|
+
});
|
|
451
|
+
if (schemaOverride) return { ...schemaOverride };
|
|
452
|
+
}
|
|
453
|
+
if (errors) for (const message of errors) handleError(message, config);
|
|
454
|
+
return jsonSchema;
|
|
455
|
+
}
|
|
456
|
+
var store;
|
|
457
|
+
function getGlobalDefs() {
|
|
458
|
+
return store;
|
|
459
|
+
}
|
|
460
|
+
function toJsonSchema(schema6, config) {
|
|
461
|
+
const context = {
|
|
462
|
+
definitions: {},
|
|
463
|
+
referenceMap: /* @__PURE__ */ new Map(),
|
|
464
|
+
getterMap: /* @__PURE__ */ new Map()
|
|
465
|
+
};
|
|
466
|
+
const definitions = config?.definitions ?? getGlobalDefs();
|
|
467
|
+
if (definitions) {
|
|
468
|
+
for (const key in definitions) context.referenceMap.set(definitions[key], key);
|
|
469
|
+
for (const key in definitions) context.definitions[key] = convertSchema({}, definitions[key], config, context, true);
|
|
470
|
+
}
|
|
471
|
+
const jsonSchema = convertSchema({}, schema6, config, context);
|
|
472
|
+
const target = config?.target ?? "draft-07";
|
|
473
|
+
if (target === "draft-2020-12") jsonSchema.$schema = "https://json-schema.org/draft/2020-12/schema";
|
|
474
|
+
else if (target === "draft-07") jsonSchema.$schema = "http://json-schema.org/draft-07/schema#";
|
|
475
|
+
if (context.referenceMap.size) jsonSchema.$defs = context.definitions;
|
|
476
|
+
return jsonSchema;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
// ../../node_modules/.pnpm/@tmcp+adapter-valibot@0.1.6_tmcp@1.19.4_typescript@5.9.3__valibot@1.4.1_typescript@5.9.3_/node_modules/@tmcp/adapter-valibot/src/index.js
|
|
480
|
+
function add_type_to_enums(json_schema) {
|
|
481
|
+
for (let key in json_schema) {
|
|
482
|
+
const property = json_schema[
|
|
483
|
+
/** @type {keyof json_schema} */
|
|
484
|
+
key
|
|
485
|
+
];
|
|
486
|
+
if (property != null && typeof property === "object" && !Array.isArray(property)) {
|
|
487
|
+
if ("enum" in property && !("type" in property)) {
|
|
488
|
+
property.type = "string";
|
|
489
|
+
}
|
|
490
|
+
add_type_to_enums(property);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
return json_schema;
|
|
494
|
+
}
|
|
495
|
+
var ValibotJsonSchemaAdapter = class extends JsonSchemaAdapter {
|
|
496
|
+
/**
|
|
497
|
+
* Converts a Valibot schema to JSON Schema format
|
|
498
|
+
* @param {GenericSchema} schema - The Valibot schema to convert
|
|
499
|
+
* @returns {Promise<ReturnType<typeof toJsonSchema>>} - The converted JSON Schema
|
|
500
|
+
*/
|
|
501
|
+
async toJsonSchema(schema6) {
|
|
502
|
+
return add_type_to_enums(toJsonSchema(schema6));
|
|
503
|
+
}
|
|
504
|
+
};
|
|
505
|
+
|
|
506
|
+
// ../mcp-server/src/mcp/index.ts
|
|
507
|
+
import { McpServer } from "tmcp";
|
|
508
|
+
|
|
509
|
+
// ../mcp-server/src/mcp/handlers/tools/index.ts
|
|
510
|
+
var tools_exports = {};
|
|
511
|
+
__export(tools_exports, {
|
|
512
|
+
get_component: () => get_component,
|
|
513
|
+
get_component_demo: () => get_component_demo,
|
|
514
|
+
get_utils: () => get_utils,
|
|
515
|
+
list_components: () => list_components,
|
|
516
|
+
list_exports: () => list_exports,
|
|
517
|
+
search_components: () => search_components
|
|
518
|
+
});
|
|
519
|
+
|
|
520
|
+
// ../../node_modules/.pnpm/valibot@1.4.1_typescript@5.9.3/node_modules/valibot/dist/index.mjs
|
|
521
|
+
var store$4;
|
|
522
|
+
var DEFAULT_CONFIG = {
|
|
523
|
+
lang: void 0,
|
|
524
|
+
message: void 0,
|
|
525
|
+
abortEarly: void 0,
|
|
526
|
+
abortPipeEarly: void 0
|
|
527
|
+
};
|
|
528
|
+
// @__NO_SIDE_EFFECTS__
|
|
529
|
+
function getGlobalConfig(config$1) {
|
|
530
|
+
if (!config$1 && !store$4) return DEFAULT_CONFIG;
|
|
531
|
+
return {
|
|
532
|
+
lang: config$1?.lang ?? store$4?.lang,
|
|
533
|
+
message: config$1?.message,
|
|
534
|
+
abortEarly: config$1?.abortEarly ?? store$4?.abortEarly,
|
|
535
|
+
abortPipeEarly: config$1?.abortPipeEarly ?? store$4?.abortPipeEarly
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
var store$3;
|
|
539
|
+
// @__NO_SIDE_EFFECTS__
|
|
540
|
+
function getGlobalMessage(lang) {
|
|
541
|
+
return store$3?.get(lang);
|
|
542
|
+
}
|
|
543
|
+
var store$2;
|
|
544
|
+
// @__NO_SIDE_EFFECTS__
|
|
545
|
+
function getSchemaMessage(lang) {
|
|
546
|
+
return store$2?.get(lang);
|
|
547
|
+
}
|
|
548
|
+
var store$1;
|
|
549
|
+
// @__NO_SIDE_EFFECTS__
|
|
550
|
+
function getSpecificMessage(reference, lang) {
|
|
551
|
+
return store$1?.get(reference)?.get(lang);
|
|
552
|
+
}
|
|
553
|
+
// @__NO_SIDE_EFFECTS__
|
|
554
|
+
function _stringify(input) {
|
|
555
|
+
const type = typeof input;
|
|
556
|
+
if (type === "string") return `"${input}"`;
|
|
557
|
+
if (type === "number" || type === "bigint" || type === "boolean") return `${input}`;
|
|
558
|
+
if (type === "object" || type === "function") return (input && Object.getPrototypeOf(input)?.constructor?.name) ?? "null";
|
|
559
|
+
return type;
|
|
560
|
+
}
|
|
561
|
+
function _addIssue(context, label, dataset, config$1, other) {
|
|
562
|
+
const input = other && "input" in other ? other.input : dataset.value;
|
|
563
|
+
const expected = other?.expected ?? context.expects ?? null;
|
|
564
|
+
const received = other?.received ?? /* @__PURE__ */ _stringify(input);
|
|
565
|
+
const issue = {
|
|
566
|
+
kind: context.kind,
|
|
567
|
+
type: context.type,
|
|
568
|
+
input,
|
|
569
|
+
expected,
|
|
570
|
+
received,
|
|
571
|
+
message: `Invalid ${label}: ${expected ? `Expected ${expected} but r` : "R"}eceived ${received}`,
|
|
572
|
+
requirement: context.requirement,
|
|
573
|
+
path: other?.path,
|
|
574
|
+
issues: other?.issues,
|
|
575
|
+
lang: config$1.lang,
|
|
576
|
+
abortEarly: config$1.abortEarly,
|
|
577
|
+
abortPipeEarly: config$1.abortPipeEarly
|
|
578
|
+
};
|
|
579
|
+
const isSchema = context.kind === "schema";
|
|
580
|
+
const message$1 = other?.message ?? context.message ?? /* @__PURE__ */ getSpecificMessage(context.reference, issue.lang) ?? (isSchema ? /* @__PURE__ */ getSchemaMessage(issue.lang) : null) ?? config$1.message ?? /* @__PURE__ */ getGlobalMessage(issue.lang);
|
|
581
|
+
if (message$1 !== void 0) issue.message = typeof message$1 === "function" ? message$1(issue) : message$1;
|
|
582
|
+
if (isSchema) dataset.typed = false;
|
|
583
|
+
if (dataset.issues) dataset.issues.push(issue);
|
|
584
|
+
else dataset.issues = [issue];
|
|
585
|
+
}
|
|
586
|
+
var _standardCache = /* @__PURE__ */ new WeakMap();
|
|
587
|
+
// @__NO_SIDE_EFFECTS__
|
|
588
|
+
function _getStandardProps(context) {
|
|
589
|
+
let cached = _standardCache.get(context);
|
|
590
|
+
if (!cached) {
|
|
591
|
+
cached = {
|
|
592
|
+
version: 1,
|
|
593
|
+
vendor: "valibot",
|
|
594
|
+
validate(value$1) {
|
|
595
|
+
return context["~run"]({ value: value$1 }, /* @__PURE__ */ getGlobalConfig());
|
|
596
|
+
}
|
|
597
|
+
};
|
|
598
|
+
_standardCache.set(context, cached);
|
|
599
|
+
}
|
|
600
|
+
return cached;
|
|
601
|
+
}
|
|
602
|
+
// @__NO_SIDE_EFFECTS__
|
|
603
|
+
function _joinExpects(values$1, separator) {
|
|
604
|
+
const list = [...new Set(values$1)];
|
|
605
|
+
if (list.length > 1) return `(${list.join(` ${separator} `)})`;
|
|
606
|
+
return list[0] ?? "never";
|
|
607
|
+
}
|
|
608
|
+
var EMOJI_REGEX = new RegExp("^(?:[\\u{1F1E6}-\\u{1F1FF}]{2}|\\u{1F3F4}[\\u{E0061}-\\u{E007A}]{2}[\\u{E0030}-\\u{E0039}\\u{E0061}-\\u{E007A}]{1,3}\\u{E007F}|(?:\\p{Emoji}\\uFE0F\\u20E3?|\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|(?![\\p{Emoji_Modifier_Base}\\u{1F1E6}-\\u{1F1FF}])\\p{Emoji_Presentation})(?:\\u200D(?:\\p{Emoji}\\uFE0F\\u20E3?|\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|(?![\\p{Emoji_Modifier_Base}\\u{1F1E6}-\\u{1F1FF}])\\p{Emoji_Presentation}))*)+$", "u");
|
|
609
|
+
// @__NO_SIDE_EFFECTS__
|
|
610
|
+
function description(description_) {
|
|
611
|
+
return {
|
|
612
|
+
kind: "metadata",
|
|
613
|
+
type: "description",
|
|
614
|
+
reference: description,
|
|
615
|
+
description: description_
|
|
616
|
+
};
|
|
617
|
+
}
|
|
618
|
+
// @__NO_SIDE_EFFECTS__
|
|
619
|
+
function integer(message$1) {
|
|
620
|
+
return {
|
|
621
|
+
kind: "validation",
|
|
622
|
+
type: "integer",
|
|
623
|
+
reference: integer,
|
|
624
|
+
async: false,
|
|
625
|
+
expects: null,
|
|
626
|
+
requirement: Number.isInteger,
|
|
627
|
+
message: message$1,
|
|
628
|
+
"~run"(dataset, config$1) {
|
|
629
|
+
if (dataset.typed && !this.requirement(dataset.value)) _addIssue(this, "integer", dataset, config$1);
|
|
630
|
+
return dataset;
|
|
631
|
+
}
|
|
632
|
+
};
|
|
633
|
+
}
|
|
634
|
+
// @__NO_SIDE_EFFECTS__
|
|
635
|
+
function maxValue(requirement, message$1) {
|
|
636
|
+
return {
|
|
637
|
+
kind: "validation",
|
|
638
|
+
type: "max_value",
|
|
639
|
+
reference: maxValue,
|
|
640
|
+
async: false,
|
|
641
|
+
expects: `<=${requirement instanceof Date ? requirement.toJSON() : /* @__PURE__ */ _stringify(requirement)}`,
|
|
642
|
+
requirement,
|
|
643
|
+
message: message$1,
|
|
644
|
+
"~run"(dataset, config$1) {
|
|
645
|
+
if (dataset.typed && !(dataset.value <= this.requirement)) _addIssue(this, "value", dataset, config$1, { received: dataset.value instanceof Date ? dataset.value.toJSON() : /* @__PURE__ */ _stringify(dataset.value) });
|
|
646
|
+
return dataset;
|
|
647
|
+
}
|
|
648
|
+
};
|
|
649
|
+
}
|
|
650
|
+
// @__NO_SIDE_EFFECTS__
|
|
651
|
+
function minLength(requirement, message$1) {
|
|
652
|
+
return {
|
|
653
|
+
kind: "validation",
|
|
654
|
+
type: "min_length",
|
|
655
|
+
reference: minLength,
|
|
656
|
+
async: false,
|
|
657
|
+
expects: `>=${requirement}`,
|
|
658
|
+
requirement,
|
|
659
|
+
message: message$1,
|
|
660
|
+
"~run"(dataset, config$1) {
|
|
661
|
+
if (dataset.typed && dataset.value.length < this.requirement) _addIssue(this, "length", dataset, config$1, { received: `${dataset.value.length}` });
|
|
662
|
+
return dataset;
|
|
663
|
+
}
|
|
664
|
+
};
|
|
665
|
+
}
|
|
666
|
+
// @__NO_SIDE_EFFECTS__
|
|
667
|
+
function minValue(requirement, message$1) {
|
|
668
|
+
return {
|
|
669
|
+
kind: "validation",
|
|
670
|
+
type: "min_value",
|
|
671
|
+
reference: minValue,
|
|
672
|
+
async: false,
|
|
673
|
+
expects: `>=${requirement instanceof Date ? requirement.toJSON() : /* @__PURE__ */ _stringify(requirement)}`,
|
|
674
|
+
requirement,
|
|
675
|
+
message: message$1,
|
|
676
|
+
"~run"(dataset, config$1) {
|
|
677
|
+
if (dataset.typed && !(dataset.value >= this.requirement)) _addIssue(this, "value", dataset, config$1, { received: dataset.value instanceof Date ? dataset.value.toJSON() : /* @__PURE__ */ _stringify(dataset.value) });
|
|
678
|
+
return dataset;
|
|
679
|
+
}
|
|
680
|
+
};
|
|
681
|
+
}
|
|
682
|
+
// @__NO_SIDE_EFFECTS__
|
|
683
|
+
function getFallback(schema6, dataset, config$1) {
|
|
684
|
+
return typeof schema6.fallback === "function" ? schema6.fallback(dataset, config$1) : schema6.fallback;
|
|
685
|
+
}
|
|
686
|
+
// @__NO_SIDE_EFFECTS__
|
|
687
|
+
function getDefault(schema6, dataset, config$1) {
|
|
688
|
+
return typeof schema6.default === "function" ? schema6.default(dataset, config$1) : schema6.default;
|
|
689
|
+
}
|
|
690
|
+
// @__NO_SIDE_EFFECTS__
|
|
691
|
+
function number(message$1) {
|
|
692
|
+
return {
|
|
693
|
+
kind: "schema",
|
|
694
|
+
type: "number",
|
|
695
|
+
reference: number,
|
|
696
|
+
expects: "number",
|
|
697
|
+
async: false,
|
|
698
|
+
message: message$1,
|
|
699
|
+
get "~standard"() {
|
|
700
|
+
return /* @__PURE__ */ _getStandardProps(this);
|
|
701
|
+
},
|
|
702
|
+
"~run"(dataset, config$1) {
|
|
703
|
+
if (typeof dataset.value === "number" && !isNaN(dataset.value)) dataset.typed = true;
|
|
704
|
+
else _addIssue(this, "type", dataset, config$1);
|
|
705
|
+
return dataset;
|
|
706
|
+
}
|
|
707
|
+
};
|
|
708
|
+
}
|
|
709
|
+
// @__NO_SIDE_EFFECTS__
|
|
710
|
+
function object(entries$1, message$1) {
|
|
711
|
+
return {
|
|
712
|
+
kind: "schema",
|
|
713
|
+
type: "object",
|
|
714
|
+
reference: object,
|
|
715
|
+
expects: "Object",
|
|
716
|
+
async: false,
|
|
717
|
+
entries: entries$1,
|
|
718
|
+
message: message$1,
|
|
719
|
+
get "~standard"() {
|
|
720
|
+
return /* @__PURE__ */ _getStandardProps(this);
|
|
721
|
+
},
|
|
722
|
+
"~run"(dataset, config$1) {
|
|
723
|
+
const input = dataset.value;
|
|
724
|
+
if (input && typeof input === "object") {
|
|
725
|
+
dataset.typed = true;
|
|
726
|
+
dataset.value = {};
|
|
727
|
+
for (const key in this.entries) {
|
|
728
|
+
const valueSchema = this.entries[key];
|
|
729
|
+
if (key in input || (valueSchema.type === "exact_optional" || valueSchema.type === "optional" || valueSchema.type === "nullish") && valueSchema.default !== void 0) {
|
|
730
|
+
const value$1 = key in input ? input[key] : /* @__PURE__ */ getDefault(valueSchema);
|
|
731
|
+
const valueDataset = valueSchema["~run"]({ value: value$1 }, config$1);
|
|
732
|
+
if (valueDataset.issues) {
|
|
733
|
+
const pathItem = {
|
|
734
|
+
type: "object",
|
|
735
|
+
origin: "value",
|
|
736
|
+
input,
|
|
737
|
+
key,
|
|
738
|
+
value: value$1
|
|
739
|
+
};
|
|
740
|
+
for (const issue of valueDataset.issues) {
|
|
741
|
+
if (issue.path) issue.path.unshift(pathItem);
|
|
742
|
+
else issue.path = [pathItem];
|
|
743
|
+
dataset.issues?.push(issue);
|
|
744
|
+
}
|
|
745
|
+
if (!dataset.issues) dataset.issues = valueDataset.issues;
|
|
746
|
+
if (config$1.abortEarly) {
|
|
747
|
+
dataset.typed = false;
|
|
748
|
+
break;
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
if (!valueDataset.typed) dataset.typed = false;
|
|
752
|
+
dataset.value[key] = valueDataset.value;
|
|
753
|
+
} else if (valueSchema.fallback !== void 0) dataset.value[key] = /* @__PURE__ */ getFallback(valueSchema);
|
|
754
|
+
else if (valueSchema.type !== "exact_optional" && valueSchema.type !== "optional" && valueSchema.type !== "nullish") {
|
|
755
|
+
_addIssue(this, "key", dataset, config$1, {
|
|
756
|
+
input: void 0,
|
|
757
|
+
expected: `"${key}"`,
|
|
758
|
+
path: [{
|
|
759
|
+
type: "object",
|
|
760
|
+
origin: "key",
|
|
761
|
+
input,
|
|
762
|
+
key,
|
|
763
|
+
value: input[key]
|
|
764
|
+
}]
|
|
765
|
+
});
|
|
766
|
+
if (config$1.abortEarly) break;
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
} else _addIssue(this, "type", dataset, config$1);
|
|
770
|
+
return dataset;
|
|
771
|
+
}
|
|
772
|
+
};
|
|
773
|
+
}
|
|
774
|
+
// @__NO_SIDE_EFFECTS__
|
|
775
|
+
function optional(wrapped, default_) {
|
|
776
|
+
return {
|
|
777
|
+
kind: "schema",
|
|
778
|
+
type: "optional",
|
|
779
|
+
reference: optional,
|
|
780
|
+
expects: `(${wrapped.expects} | undefined)`,
|
|
781
|
+
async: false,
|
|
782
|
+
wrapped,
|
|
783
|
+
default: default_,
|
|
784
|
+
get "~standard"() {
|
|
785
|
+
return /* @__PURE__ */ _getStandardProps(this);
|
|
786
|
+
},
|
|
787
|
+
"~run"(dataset, config$1) {
|
|
788
|
+
if (dataset.value === void 0) {
|
|
789
|
+
if (this.default !== void 0) dataset.value = /* @__PURE__ */ getDefault(this, dataset, config$1);
|
|
790
|
+
if (dataset.value === void 0) {
|
|
791
|
+
dataset.typed = true;
|
|
792
|
+
return dataset;
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
return this.wrapped["~run"](dataset, config$1);
|
|
796
|
+
}
|
|
797
|
+
};
|
|
798
|
+
}
|
|
799
|
+
// @__NO_SIDE_EFFECTS__
|
|
800
|
+
function picklist(options, message$1) {
|
|
801
|
+
return {
|
|
802
|
+
kind: "schema",
|
|
803
|
+
type: "picklist",
|
|
804
|
+
reference: picklist,
|
|
805
|
+
expects: /* @__PURE__ */ _joinExpects(options.map(_stringify), "|"),
|
|
806
|
+
async: false,
|
|
807
|
+
options,
|
|
808
|
+
message: message$1,
|
|
809
|
+
get "~standard"() {
|
|
810
|
+
return /* @__PURE__ */ _getStandardProps(this);
|
|
811
|
+
},
|
|
812
|
+
"~run"(dataset, config$1) {
|
|
813
|
+
if (this.options.includes(dataset.value)) dataset.typed = true;
|
|
814
|
+
else _addIssue(this, "type", dataset, config$1);
|
|
815
|
+
return dataset;
|
|
816
|
+
}
|
|
817
|
+
};
|
|
818
|
+
}
|
|
819
|
+
// @__NO_SIDE_EFFECTS__
|
|
820
|
+
function string(message$1) {
|
|
821
|
+
return {
|
|
822
|
+
kind: "schema",
|
|
823
|
+
type: "string",
|
|
824
|
+
reference: string,
|
|
825
|
+
expects: "string",
|
|
826
|
+
async: false,
|
|
827
|
+
message: message$1,
|
|
828
|
+
get "~standard"() {
|
|
829
|
+
return /* @__PURE__ */ _getStandardProps(this);
|
|
830
|
+
},
|
|
831
|
+
"~run"(dataset, config$1) {
|
|
832
|
+
if (typeof dataset.value === "string") dataset.typed = true;
|
|
833
|
+
else _addIssue(this, "type", dataset, config$1);
|
|
834
|
+
return dataset;
|
|
835
|
+
}
|
|
836
|
+
};
|
|
837
|
+
}
|
|
838
|
+
// @__NO_SIDE_EFFECTS__
|
|
839
|
+
function pipe(...pipe$1) {
|
|
840
|
+
return {
|
|
841
|
+
...pipe$1[0],
|
|
842
|
+
pipe: pipe$1,
|
|
843
|
+
get "~standard"() {
|
|
844
|
+
return /* @__PURE__ */ _getStandardProps(this);
|
|
845
|
+
},
|
|
846
|
+
"~run"(dataset, config$1) {
|
|
847
|
+
for (const item of pipe$1) if (item.kind !== "metadata") {
|
|
848
|
+
if (dataset.issues && (item.kind === "schema" || item.kind === "transformation")) {
|
|
849
|
+
dataset.typed = false;
|
|
850
|
+
break;
|
|
851
|
+
}
|
|
852
|
+
if (!dataset.issues || !config$1.abortEarly && !config$1.abortPipeEarly) dataset = item["~run"](dataset, config$1);
|
|
853
|
+
}
|
|
854
|
+
return dataset;
|
|
855
|
+
}
|
|
856
|
+
};
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
// ../mcp-server/src/mcp/handlers/tools/list-components.ts
|
|
860
|
+
import { tool } from "tmcp/utils";
|
|
861
|
+
|
|
862
|
+
// ../mcp-server/src/constants.ts
|
|
863
|
+
import { resolve } from "path";
|
|
864
|
+
import { fileURLToPath } from "url";
|
|
865
|
+
var PKG_DIR = fileURLToPath(new URL("..", import.meta.url));
|
|
866
|
+
var ALUS_ROOT = process.env.ALUS_ROOT ?? resolve(PKG_DIR, "../..");
|
|
867
|
+
var COMPONENTS_DIR = `${ALUS_ROOT}/packages/alus/src/lib/components`;
|
|
868
|
+
var ROUTES_DIR = `${ALUS_ROOT}/src/routes/components`;
|
|
869
|
+
var UTILS_ROOT = `${ALUS_ROOT}/packages/alus/src/lib/utils`;
|
|
870
|
+
var CHARACTER_LIMIT = 25e3;
|
|
871
|
+
var CATEGORIES = [
|
|
872
|
+
"form",
|
|
873
|
+
"navigation",
|
|
874
|
+
"feedback",
|
|
875
|
+
"display",
|
|
876
|
+
"overlay",
|
|
877
|
+
"layout",
|
|
878
|
+
"interactive",
|
|
879
|
+
"utility"
|
|
880
|
+
];
|
|
881
|
+
|
|
882
|
+
// ../mcp-server/src/lib/fs.ts
|
|
883
|
+
import { readdir, readFile } from "fs/promises";
|
|
884
|
+
async function list_all_components() {
|
|
885
|
+
const entries = [];
|
|
886
|
+
for (const category of CATEGORIES) {
|
|
887
|
+
const cat_dir = `${COMPONENTS_DIR}/${category}`;
|
|
888
|
+
let items;
|
|
889
|
+
try {
|
|
890
|
+
items = await readdir(cat_dir);
|
|
891
|
+
} catch {
|
|
892
|
+
continue;
|
|
893
|
+
}
|
|
894
|
+
for (const item of items) {
|
|
895
|
+
const comp_dir = `${cat_dir}/${item}`;
|
|
896
|
+
let files;
|
|
897
|
+
try {
|
|
898
|
+
files = await readdir(comp_dir);
|
|
899
|
+
} catch {
|
|
900
|
+
continue;
|
|
901
|
+
}
|
|
902
|
+
const source_files = files.filter((f) => f.endsWith(".svelte") || f.endsWith(".ts"));
|
|
903
|
+
if (!source_files.length) continue;
|
|
904
|
+
const name = item.split("-").map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join("");
|
|
905
|
+
entries.push({ name, category, dir: comp_dir, files: source_files });
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
return entries;
|
|
909
|
+
}
|
|
910
|
+
async function read_component_source(entry) {
|
|
911
|
+
const parts = [];
|
|
912
|
+
for (const file of entry.files) {
|
|
913
|
+
const content = await readFile(`${entry.dir}/${file}`, "utf-8");
|
|
914
|
+
parts.push(`// FILE: ${file}
|
|
915
|
+
${content}`);
|
|
916
|
+
}
|
|
917
|
+
return parts.join("\n\n");
|
|
918
|
+
}
|
|
919
|
+
function truncate(text, hint) {
|
|
920
|
+
if (text.length <= CHARACTER_LIMIT) return text;
|
|
921
|
+
return text.slice(0, CHARACTER_LIMIT) + `
|
|
922
|
+
|
|
923
|
+
[... truncated. ${hint}]`;
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
// ../mcp-server/src/mcp/handlers/tools/list-components.ts
|
|
927
|
+
var schema = object({
|
|
928
|
+
category: optional(
|
|
929
|
+
picklist(CATEGORIES, "Must be one of the alus-ui component categories")
|
|
930
|
+
),
|
|
931
|
+
response_format: optional(picklist(["markdown", "json"]), "markdown")
|
|
932
|
+
});
|
|
933
|
+
async function list_components_handler(params) {
|
|
934
|
+
const { category, response_format = "markdown" } = params;
|
|
935
|
+
const all = await list_all_components();
|
|
936
|
+
const filtered = category ? all.filter((c) => c.category === category) : all;
|
|
937
|
+
if (response_format === "json") {
|
|
938
|
+
return JSON.stringify(
|
|
939
|
+
{
|
|
940
|
+
total: filtered.length,
|
|
941
|
+
components: filtered.map((c) => ({
|
|
942
|
+
name: c.name,
|
|
943
|
+
category: c.category,
|
|
944
|
+
dir: c.dir.replace(`${COMPONENTS_DIR}/`, "")
|
|
945
|
+
}))
|
|
946
|
+
},
|
|
947
|
+
null,
|
|
948
|
+
2
|
|
949
|
+
);
|
|
950
|
+
}
|
|
951
|
+
const grouped = {};
|
|
952
|
+
for (const c of filtered) {
|
|
953
|
+
(grouped[c.category] ??= []).push(c.name);
|
|
954
|
+
}
|
|
955
|
+
const lines = [`# alus-ui Components (${filtered.length} total)`, ""];
|
|
956
|
+
for (const [cat, names] of Object.entries(grouped)) {
|
|
957
|
+
lines.push(`## ${cat}`, "", names.map((n) => `- ${n}`).join("\n"), "");
|
|
958
|
+
}
|
|
959
|
+
return lines.join("\n");
|
|
960
|
+
}
|
|
961
|
+
function list_components(server2) {
|
|
962
|
+
server2.tool(
|
|
963
|
+
{
|
|
964
|
+
name: "alus_list_components",
|
|
965
|
+
description: "List all components in the alus-ui Svelte 5 library grouped by category. Call this first to discover component names before using alus_get_component. Optionally filter by category.",
|
|
966
|
+
schema,
|
|
967
|
+
annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: false }
|
|
968
|
+
},
|
|
969
|
+
async (params) => {
|
|
970
|
+
try {
|
|
971
|
+
return tool.text(await list_components_handler(params));
|
|
972
|
+
} catch (e) {
|
|
973
|
+
return tool.error(e.message);
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
);
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
// ../mcp-server/src/mcp/handlers/tools/get-component.ts
|
|
980
|
+
import { tool as tool2 } from "tmcp/utils";
|
|
981
|
+
var schema2 = object({
|
|
982
|
+
name: pipe(
|
|
983
|
+
string(),
|
|
984
|
+
description("Component name, case-insensitive (e.g. 'Button', 'accordion', 'date-picker')")
|
|
985
|
+
),
|
|
986
|
+
category: optional(picklist(CATEGORIES, "Narrow search when name is ambiguous"))
|
|
987
|
+
});
|
|
988
|
+
function get_component(server2) {
|
|
989
|
+
server2.tool(
|
|
990
|
+
{
|
|
991
|
+
name: "alus_get_component",
|
|
992
|
+
description: "Read the full source of an alus-ui component (.svelte + index.ts). Use alus_list_components first to find valid names. Supports partial, case-insensitive matching (e.g. 'button', 'Button', 'date-picker').",
|
|
993
|
+
schema: schema2,
|
|
994
|
+
annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: false }
|
|
995
|
+
},
|
|
996
|
+
async ({ name, category }) => {
|
|
997
|
+
try {
|
|
998
|
+
const all = await list_all_components();
|
|
999
|
+
const needle = name.toLowerCase().replace(/[-_\s]/g, "");
|
|
1000
|
+
let matches = all.filter(
|
|
1001
|
+
(c) => c.name.toLowerCase().replace(/[-_\s]/g, "") === needle
|
|
1002
|
+
);
|
|
1003
|
+
if (category) matches = matches.filter((c) => c.category === category);
|
|
1004
|
+
if (!matches.length) {
|
|
1005
|
+
const similar = all.filter(
|
|
1006
|
+
(c) => c.name.toLowerCase().includes(needle) || needle.includes(c.name.toLowerCase())
|
|
1007
|
+
).map((c) => `${c.name} (${c.category})`).slice(0, 5).join(", ");
|
|
1008
|
+
return tool2.text(
|
|
1009
|
+
`Component '${name}' not found.${similar ? ` Similar: ${similar}` : " Use alus_list_components to browse."}`
|
|
1010
|
+
);
|
|
1011
|
+
}
|
|
1012
|
+
const entry = matches[0];
|
|
1013
|
+
const src = await read_component_source(entry);
|
|
1014
|
+
return tool2.text(
|
|
1015
|
+
truncate(
|
|
1016
|
+
`# ${entry.name} (${entry.category})
|
|
1017
|
+
|
|
1018
|
+
${src}`,
|
|
1019
|
+
"Use alus_search_components for targeted lookup."
|
|
1020
|
+
)
|
|
1021
|
+
);
|
|
1022
|
+
} catch (e) {
|
|
1023
|
+
return tool2.error(e.message);
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
);
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
// ../mcp-server/src/mcp/handlers/tools/search-components.ts
|
|
1030
|
+
import { tool as tool3 } from "tmcp/utils";
|
|
1031
|
+
import { readFile as readFile2 } from "fs/promises";
|
|
1032
|
+
var schema3 = object({
|
|
1033
|
+
query: pipe(string(), minLength(2), description("Case-insensitive search string")),
|
|
1034
|
+
category: optional(picklist(CATEGORIES)),
|
|
1035
|
+
limit: optional(pipe(number(), integer(), minValue(1), maxValue(50)), 20),
|
|
1036
|
+
response_format: optional(picklist(["markdown", "json"]), "markdown")
|
|
1037
|
+
});
|
|
1038
|
+
function search_components(server2) {
|
|
1039
|
+
server2.tool(
|
|
1040
|
+
{
|
|
1041
|
+
name: "alus_search_components",
|
|
1042
|
+
description: "Full-text search across all alus-ui component source files. Useful for finding which component uses a specific prop, ARIA pattern, utility function, or type. Returns matches with \xB12 lines of context.",
|
|
1043
|
+
schema: schema3,
|
|
1044
|
+
annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: false }
|
|
1045
|
+
},
|
|
1046
|
+
async ({ query, category, limit = 20, response_format = "markdown" }) => {
|
|
1047
|
+
try {
|
|
1048
|
+
const all = await list_all_components();
|
|
1049
|
+
const pool = category ? all.filter((c) => c.category === category) : all;
|
|
1050
|
+
const needle = query.toLowerCase();
|
|
1051
|
+
const hits = [];
|
|
1052
|
+
for (const entry of pool) {
|
|
1053
|
+
if (hits.length >= limit) break;
|
|
1054
|
+
for (const file of entry.files) {
|
|
1055
|
+
if (hits.length >= limit) break;
|
|
1056
|
+
const content = await readFile2(`${entry.dir}/${file}`, "utf-8");
|
|
1057
|
+
const lines2 = content.split("\n");
|
|
1058
|
+
for (let i = 0; i < lines2.length; i++) {
|
|
1059
|
+
if (lines2[i].toLowerCase().includes(needle)) {
|
|
1060
|
+
const start = Math.max(0, i - 2);
|
|
1061
|
+
const end = Math.min(lines2.length - 1, i + 2);
|
|
1062
|
+
hits.push({
|
|
1063
|
+
component: entry.name,
|
|
1064
|
+
category: entry.category,
|
|
1065
|
+
file,
|
|
1066
|
+
line: i + 1,
|
|
1067
|
+
context: lines2.slice(start, end + 1).join("\n")
|
|
1068
|
+
});
|
|
1069
|
+
if (hits.length >= limit) break;
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
if (!hits.length) return tool3.text(`No results for '${query}'.`);
|
|
1075
|
+
if (response_format === "json") {
|
|
1076
|
+
return tool3.text(JSON.stringify({ query, total: hits.length, hits }, null, 2));
|
|
1077
|
+
}
|
|
1078
|
+
const lines = [`# Search: '${query}' \u2014 ${hits.length} hit(s)`, ""];
|
|
1079
|
+
for (const h of hits) {
|
|
1080
|
+
lines.push(
|
|
1081
|
+
`## ${h.component} (${h.category}) \xB7 ${h.file}:${h.line}`,
|
|
1082
|
+
"```svelte",
|
|
1083
|
+
h.context,
|
|
1084
|
+
"```",
|
|
1085
|
+
""
|
|
1086
|
+
);
|
|
1087
|
+
}
|
|
1088
|
+
return tool3.text(truncate(lines.join("\n"), "Narrow with category or a more specific query."));
|
|
1089
|
+
} catch (e) {
|
|
1090
|
+
return tool3.error(e.message);
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
);
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
// ../mcp-server/src/mcp/handlers/tools/get-component-demo.ts
|
|
1097
|
+
import { tool as tool4 } from "tmcp/utils";
|
|
1098
|
+
import { readFile as readFile3, readdir as readdir2 } from "fs/promises";
|
|
1099
|
+
var schema4 = object({
|
|
1100
|
+
name: pipe(
|
|
1101
|
+
string(),
|
|
1102
|
+
description("Component route folder name, lowercase hyphenated (e.g. 'button', 'date-picker')")
|
|
1103
|
+
)
|
|
1104
|
+
});
|
|
1105
|
+
function get_component_demo(server2) {
|
|
1106
|
+
server2.tool(
|
|
1107
|
+
{
|
|
1108
|
+
name: "alus_get_component_demo",
|
|
1109
|
+
description: "Read the SvelteKit showcase demo page for a component. Shows real usage with props, events, and the Japanese Creative aesthetic. Path: src/routes/components/{name}/+page.svelte.",
|
|
1110
|
+
schema: schema4,
|
|
1111
|
+
annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: false }
|
|
1112
|
+
},
|
|
1113
|
+
async ({ name }) => {
|
|
1114
|
+
try {
|
|
1115
|
+
const demo_path = `${ROUTES_DIR}/${name.toLowerCase()}/+page.svelte`;
|
|
1116
|
+
let content;
|
|
1117
|
+
try {
|
|
1118
|
+
content = await readFile3(demo_path, "utf-8");
|
|
1119
|
+
} catch {
|
|
1120
|
+
let available = [];
|
|
1121
|
+
try {
|
|
1122
|
+
available = await readdir2(ROUTES_DIR);
|
|
1123
|
+
} catch {
|
|
1124
|
+
}
|
|
1125
|
+
const hint = available.length ? ` Available: ${available.slice(0, 10).join(", ")}${available.length > 10 ? "\u2026" : ""}` : "";
|
|
1126
|
+
return tool4.text(`Demo not found for '${name}'.${hint}`);
|
|
1127
|
+
}
|
|
1128
|
+
return tool4.text(
|
|
1129
|
+
truncate(
|
|
1130
|
+
`# Demo: ${name}
|
|
1131
|
+
\`\`\`svelte
|
|
1132
|
+
${content}
|
|
1133
|
+
\`\`\``,
|
|
1134
|
+
"Use alus_get_component for source."
|
|
1135
|
+
)
|
|
1136
|
+
);
|
|
1137
|
+
} catch (e) {
|
|
1138
|
+
return tool4.error(e.message);
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
);
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
// ../mcp-server/src/mcp/handlers/tools/list-exports.ts
|
|
1145
|
+
import { tool as tool5 } from "tmcp/utils";
|
|
1146
|
+
import { readFile as readFile4 } from "fs/promises";
|
|
1147
|
+
function list_exports(server2) {
|
|
1148
|
+
server2.tool(
|
|
1149
|
+
{
|
|
1150
|
+
name: "alus_list_exports",
|
|
1151
|
+
description: "Return the full contents of packages/alus/src/lib/components/index.ts \u2014 the canonical public API of alus-ui with exact import paths, exported types, and context helpers.",
|
|
1152
|
+
annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: false }
|
|
1153
|
+
},
|
|
1154
|
+
async () => {
|
|
1155
|
+
try {
|
|
1156
|
+
const content = await readFile4(`${COMPONENTS_DIR}/index.ts`, "utf-8");
|
|
1157
|
+
return tool5.text(`\`\`\`typescript
|
|
1158
|
+
${content}
|
|
1159
|
+
\`\`\``);
|
|
1160
|
+
} catch (e) {
|
|
1161
|
+
return tool5.error(e.message);
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
);
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
// ../mcp-server/src/mcp/handlers/tools/get-utils.ts
|
|
1168
|
+
import { tool as tool6 } from "tmcp/utils";
|
|
1169
|
+
import { readFile as readFile5 } from "fs/promises";
|
|
1170
|
+
var MODULES = ["aria", "focus", "id", "keyboard", "index", "form/state"];
|
|
1171
|
+
var schema5 = object({
|
|
1172
|
+
module: picklist(MODULES, "Utility module \u2014 one of: aria, focus, id, keyboard, index, form/state")
|
|
1173
|
+
});
|
|
1174
|
+
function get_utils(server2) {
|
|
1175
|
+
server2.tool(
|
|
1176
|
+
{
|
|
1177
|
+
name: "alus_get_utils",
|
|
1178
|
+
description: "Read source of an alus-ui utility module (a11y helpers, form state). Available: aria, focus, id, keyboard, index, form/state.",
|
|
1179
|
+
schema: schema5,
|
|
1180
|
+
annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: false }
|
|
1181
|
+
},
|
|
1182
|
+
async ({ module }) => {
|
|
1183
|
+
try {
|
|
1184
|
+
const path = module === "index" ? `${UTILS_ROOT}/a11y/index.ts` : module === "form/state" ? `${UTILS_ROOT}/form/state.ts` : `${UTILS_ROOT}/a11y/${module}.ts`;
|
|
1185
|
+
const content = await readFile5(path, "utf-8");
|
|
1186
|
+
return tool6.text(`\`\`\`typescript
|
|
1187
|
+
${content}
|
|
1188
|
+
\`\`\``);
|
|
1189
|
+
} catch (e) {
|
|
1190
|
+
return tool6.error(e.message);
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
);
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1196
|
+
// ../mcp-server/src/mcp/handlers/index.ts
|
|
1197
|
+
function setup_tools(server2) {
|
|
1198
|
+
for (const tool7 in tools_exports) {
|
|
1199
|
+
tools_exports[tool7](server2);
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
// ../mcp-server/src/mcp/index.ts
|
|
1204
|
+
var server = new McpServer(
|
|
1205
|
+
{
|
|
1206
|
+
name: "alus-ui MCP",
|
|
1207
|
+
version: "0.0.1",
|
|
1208
|
+
description: "MCP server for the alus-ui Svelte 5 component library"
|
|
1209
|
+
},
|
|
1210
|
+
{
|
|
1211
|
+
adapter: new ValibotJsonSchemaAdapter(),
|
|
1212
|
+
capabilities: { tools: {} },
|
|
1213
|
+
instructions: "This MCP server provides direct access to alus-ui \u2014 an unstyled, accessible Svelte 5 component library. Use it to browse components, read source, search patterns, and find usage examples. Always call alus_list_components first to discover available components."
|
|
1214
|
+
}
|
|
1215
|
+
).withContext();
|
|
1216
|
+
setup_tools(server);
|
|
1217
|
+
|
|
1218
|
+
// src/index.ts
|
|
1219
|
+
import { StdioTransport } from "@tmcp/transport-stdio";
|
|
1220
|
+
var transport = new StdioTransport(server);
|
|
1221
|
+
transport.listen();
|
package/package.json
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "alus-ui-mcp",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "MCP stdio server for the alus-ui Svelte 5 component library — gives LLMs direct access to component source, demos, exports, and utilities",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"author": {
|
|
8
|
+
"name": "Hanivan Rizky",
|
|
9
|
+
"email": "hanivan20@gmail.com"
|
|
10
|
+
},
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "git+https://github.com/Hanivan/alus.git"
|
|
14
|
+
},
|
|
15
|
+
"homepage": "https://github.com/Hanivan/alus#readme",
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/Hanivan/alus/issues"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"mcp",
|
|
21
|
+
"model-context-protocol",
|
|
22
|
+
"svelte",
|
|
23
|
+
"svelte5",
|
|
24
|
+
"ui-components",
|
|
25
|
+
"alus-ui",
|
|
26
|
+
"llm",
|
|
27
|
+
"claude",
|
|
28
|
+
"cursor",
|
|
29
|
+
"ai"
|
|
30
|
+
],
|
|
31
|
+
"bin": {
|
|
32
|
+
"alus-mcp": "./dist/index.js"
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"dist",
|
|
36
|
+
"!dist/**/*.test.*",
|
|
37
|
+
"!dist/**/*.spec.*"
|
|
38
|
+
],
|
|
39
|
+
"scripts": {
|
|
40
|
+
"build": "tsup",
|
|
41
|
+
"dev:build": "tsup --watch",
|
|
42
|
+
"dev": "tsx watch src/index.ts",
|
|
43
|
+
"start": "tsx src/index.ts",
|
|
44
|
+
"prepublishOnly": "npm run build",
|
|
45
|
+
"release": "release-it",
|
|
46
|
+
"release:dry": "release-it --dry-run",
|
|
47
|
+
"release:patch": "release-it patch",
|
|
48
|
+
"release:minor": "release-it minor",
|
|
49
|
+
"release:major": "release-it major"
|
|
50
|
+
},
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"@alus-ui/mcp-server": "workspace:*",
|
|
53
|
+
"@tmcp/transport-stdio": "latest",
|
|
54
|
+
"tmcp": "latest"
|
|
55
|
+
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"@release-it/conventional-changelog": "latest",
|
|
58
|
+
"publint": "latest",
|
|
59
|
+
"release-it": "latest",
|
|
60
|
+
"tsup": "latest",
|
|
61
|
+
"tsx": "latest",
|
|
62
|
+
"typescript": "^6.0.2"
|
|
63
|
+
},
|
|
64
|
+
"publishConfig": {
|
|
65
|
+
"access": "public"
|
|
66
|
+
},
|
|
67
|
+
"engines": {
|
|
68
|
+
"node": ">=18.0.0",
|
|
69
|
+
"pnpm": ">=8.0.0"
|
|
70
|
+
}
|
|
71
|
+
}
|