@regle/mcp-server 1.14.0 → 1.14.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 +3 -1
- package/dist/regle-mcp-server.js +223 -242
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,7 +22,9 @@ Add to your `claude_desktop_config.json`:
|
|
|
22
22
|
|
|
23
23
|
### Cursor
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
[](https://cursor.com/en-US/install-mcp?name=regle&config=eyJjb21tYW5kIjoibnB4IEByZWdsZS9tY3Atc2VydmVyIn0%3D)
|
|
26
|
+
|
|
27
|
+
Or add to your MCP settings:
|
|
26
28
|
|
|
27
29
|
```json
|
|
28
30
|
{
|
package/dist/regle-mcp-server.js
CHANGED
|
@@ -21,7 +21,7 @@ var docs_data_default = {
|
|
|
21
21
|
},
|
|
22
22
|
{
|
|
23
23
|
"id": "advanced-usage-immutable-constructors",
|
|
24
|
-
"title": "
|
|
24
|
+
"title": "markStatic",
|
|
25
25
|
"category": "advanced-usage",
|
|
26
26
|
"path": "advanced-usage/immutable-constructors.md",
|
|
27
27
|
"content": "# Handling immutable constructors\n\nRegle works by tracking changes in the state and updating the validation rules accordingly.\n\nThis works great for objects and arrays, but not for immutable constructors (like `Decimal` from `decimal.js` or `Moment` from `moment.js`, etc...).\n\nThis constructors will be interpreted as regular objects and their properties treated as nested fields.\n\n## Default Usage\n\nTo handle these cases, you can use the `markStatic` helper to mark the value as static and treat the constructor as a regular raw Field.\n\n```vue\n<template>\n <input :value=\"r$.decimal.$value?.toString()\" @input=\"handleDecimalInput\" />\n</template>\n\n```\n\n## Schema Usage\n\nWhen using Regle with `@regle/schemas`, you will have to also declare the static constructor in the schema.\n\n```ts\nimport { markStatic, useRegleSchema } from '@regle/core'\nimport { z } from 'zod'\n\nconst StaticDecimal = markStatic(Decimal)\n\nconst schema = z.object({\n decimal: z.instanceof(StaticDecimal).refine((value) => value.toNumber() > 10),\n})\n\nconst { r$ } = useRegleSchema({ decimal: new StaticDecimal(0) }, schema)\n\n```\n\n## `isStatic` helper\n\nYou can use the `isStatic` helper to check if a value is a static value.\n\n```ts\nimport { isStatic } from '@regle/core';\n\nconst isStatic = isStatic(r$.$value.decimal); // true\n```\n\n## `UnwrapStatic` type helper\n\nYou can use the `UnwrapStatic` type to unwrap a static value.\n\n```ts\nimport { type UnwrapStatic } from '@regle/core';\n\ntype value = UnwrapStatic<typeof r$.$value.decimal>; // Decimal\n```\n\n## `isRegleStatic` type helper\n\nYou can use the `isRegleStatic` type helper to check if a value is a static value.\n\n```ts\nimport { type isRegleStatic } from '@regle/core';\n\ntype isStatic = isRegleStatic<typeof state.decimal>; // true\n```"
|
|
@@ -236,6 +236,13 @@ var docs_data_default = {
|
|
|
236
236
|
"path": "index.md",
|
|
237
237
|
"content": "<h2 class=\"hidden-title\">Vue validation library</h2>\n<h2 class=\"hidden-title\">Vue form library</h2>\n<h2 class=\"hidden-title\">Vue zod forms</h2>\n<h2 class=\"hidden-title\">Vue zod</h2>\n<h2 class=\"hidden-title\">Vuelidate Zod</h2>\n<h2 class=\"hidden-title\">Vuelidate alternative</h2>\n<h2 class=\"hidden-title\">Veevalidate alternative</h2>\n<h2 class=\"hidden-title\">Vueforms alternative</h2>\n<h2 class=\"hidden-title\">Tanstack forms alternative</h2>"
|
|
238
238
|
},
|
|
239
|
+
{
|
|
240
|
+
"id": "integrations-mcp-server",
|
|
241
|
+
"title": "Regle MCP server",
|
|
242
|
+
"category": "integrations",
|
|
243
|
+
"path": "integrations/mcp-server.md",
|
|
244
|
+
"content": "# MCP Server\n\nRegle offers an MCP server that can be used to get documentation and autocomplete in your favorite AI assistant editor.\n\nThe MCP server provides the following features:\n\n- Create form validation rules\n- Search documentation\n- Get precise information on any rule\n- Create custom rules\n- API information on every Regle helper\n\n## Cursor\n\n<a href=\"https://cursor.com/en-US/install-mcp?name=regle&config=eyJjb21tYW5kIjoibnB4IEByZWdsZS9tY3Atc2VydmVyIn0%3D\">\n <div class=\"light-only\">\n <img src=\"https://cursor.com/deeplink/mcp-install-dark.svg\" alt=\"Install MCP Server\" />\n </div>\n <div class=\"dark-only\">\n <img src=\"https://cursor.com/deeplink/mcp-install-light.svg\" alt=\"Install MCP Server\" />\n </div>\n</a>\n\nOr add to your `.cursor/mcp.json`\n```json\n{\n \"mcpServers\": {\n \"regle\": {\n \"command\": \"npx\",\n \"args\": [\"@regle/mcp-server\"]\n }\n }\n}\n```\n\n## Claude Desktop\n\nAdd to your `claude_desktop_config.json`:\n\n```json\n{\n \"mcpServers\": {\n \"regle\": {\n \"command\": \"npx\",\n \"args\": [\"@regle/mcp-server\"]\n }\n }\n}\n```"
|
|
245
|
+
},
|
|
239
246
|
{
|
|
240
247
|
"id": "integrations-nuxt",
|
|
241
248
|
"title": "Nuxt",
|
|
@@ -259,7 +266,7 @@ var docs_data_default = {
|
|
|
259
266
|
},
|
|
260
267
|
{
|
|
261
268
|
"id": "introduction-devtools",
|
|
262
|
-
"title": "
|
|
269
|
+
"title": "Devtools",
|
|
263
270
|
"category": "introduction",
|
|
264
271
|
"path": "introduction/devtools.md",
|
|
265
272
|
"content": "# Regle Devtools\n\nRegle offers a devtools extension for [Vue Devtools](https://devtools.vuejs.org/) to help you debug your validation tree.\n\n\n\n## Installation\n\nTo enable devtools, you need to install the Regle plugin in your app.\n\n:::tip\nIf you use the `@regle/nuxt` module, the devtools will be automatically enabled.\n:::\n\n```ts [main.ts]\nimport { createApp } from 'vue';\nimport App from './App.vue';\nimport { RegleVuePlugin } from '@regle/core';\n\nconst app = createApp(App);\n\napp.use(RegleVuePlugin); // <--\n\napp.mount('#app');\n```\n\n## Usage\n\nRegle devtools can inspect every variation of `useRegle`:\n\n- `useRegle`\n- `useRules`\n- `useRegleSchema`\n- `useScopedRegle`\n- `useScopedRegleSchema`\n\nYou can inspect every nested properties and rules of the `r$` instance.\n\n:::warning\nRules details inspection is not available for `useRegleSchema`\n:::\n\n### Actions\n\nYou can perform actions on the `r$` instance by clicking on the actions buttons in the devtools.\n\n\n\n- Validate: Validate the `r$` instance (with `$validate` method)\n- Reset validation state: Reset the validation state of the `r$` instance (with `$reset` method)\n- Restore to original state: Restore the `r$` instance to the original state (with `$reset` method)\n\n## Providing custom `r$` ids to devtools\n\nBy default, the devtools will use a generic name to display the `r$` instance. \n\nYou can provide a custom name to the `useRegle` composable to display a more descriptive name in the devtools.\n\n```ts [App.vue]\nimport { useRegle } from '@regle/core';\n\nconst { r$ } = useRegle({ name: '' }, {\n name: { required }\n}, {\n id: 'my-form'\n});\n```\n\n## Devtools demo\n\nYou can go in any of the [Stablitz exemples](/examples/index) and open the devtools by clicking on the <span data-title=\"vue\"></span> \"Open Devtools\" button in the bottom middle of the page.\n\n### Vite Devtools Integration\n\nRegle devtools also integrate cleanly with [Vite](https://vitejs.dev/) when you're running your app in development mode.\n\nYou should see the Regle panel show up automatically in the Vite devtools if you've installed the plugin correctly.\n\n<img src=\"/screenshots/vite-devtools.png\" alt=\"Vite Devtools with Regle panel\" width=\"100\"/>\n\nYou will see the Regle icon showing in the devtools. Just click on it!\n\n<img src=\"/screenshots/vite-devtools-regle.png\" alt=\"Vite Devtools with Regle panel\" />"
|
|
@@ -412,21 +419,21 @@ var docs_data_default = {
|
|
|
412
419
|
{
|
|
413
420
|
"name": "flatErrors",
|
|
414
421
|
"kind": "function",
|
|
415
|
-
"description": "Converts a nested
|
|
422
|
+
"description": "Converts a nested `$errors` object to a flat array of error strings.\nUseful for displaying a complete list of form errors or counting total errors.\n\nWith the `includePath` option, returns errors in Standard Schema Issue format\nincluding the path to each error field.",
|
|
416
423
|
"parameters": [{
|
|
417
424
|
"name": "errors",
|
|
418
425
|
"type": "$InternalRegleErrors",
|
|
419
|
-
"description": "",
|
|
426
|
+
"description": "- The `$errors` object from a Regle instance (e.g., `r$.$errors`)",
|
|
420
427
|
"optional": false
|
|
421
428
|
}, {
|
|
422
429
|
"name": "options",
|
|
423
430
|
"type": "{ includePath: true; }",
|
|
424
|
-
"description": "",
|
|
431
|
+
"description": "- Configuration options",
|
|
425
432
|
"optional": false
|
|
426
433
|
}],
|
|
427
434
|
"returnType": "StandardSchemaV1.Issue[]",
|
|
428
|
-
"example": "",
|
|
429
|
-
"tags": {}
|
|
435
|
+
"example": "import { flatErrors, useRegle } from '@regle/core';\nimport { required, email, minLength } from '@regle/rules';\n\nconst { r$ } = useRegle(\n { name: '', email: 'invalid' },\n { name: { required, minLength: minLength(3) }, email: { email } }\n);\n\nawait r$.$validate();\n\n// Get flat array of error messages\nconst errors = flatErrors(r$.$errors);\n// ['This field is required', 'Value must be a valid email address']\n\n// Get errors with paths (Standard Schema format)\nconst issues = flatErrors(r$.$errors, { includePath: true });\n// [{ message: 'This field is required', path: ['name'] }, ...]",
|
|
436
|
+
"tags": { "see": "://reglejs.dev/core-concepts/displaying-errors#display-flat-errors Documentation" }
|
|
430
437
|
},
|
|
431
438
|
{
|
|
432
439
|
"name": "inferRules",
|
|
@@ -539,11 +546,11 @@ var docs_data_default = {
|
|
|
539
546
|
{
|
|
540
547
|
"name": "RegleVuePlugin",
|
|
541
548
|
"kind": "const",
|
|
542
|
-
"description": "",
|
|
549
|
+
"description": "Vue plugin to enable Regle devtools integration with Vue Devtools.\nProvides debugging capabilities for inspecting validation trees, states, and actions.\n\nSupports inspection of: `useRegle`, `useRules`, `useRegleSchema`, `useScopedRegle`, `useScopedRegleSchema`.\n\nNote: If using `@regle/nuxt`, devtools are automatically enabled.",
|
|
543
550
|
"parameters": [],
|
|
544
551
|
"returnType": "",
|
|
545
|
-
"example": "",
|
|
546
|
-
"tags": {}
|
|
552
|
+
"example": "// main.ts\nimport { createApp } from 'vue';\nimport { RegleVuePlugin } from '@regle/core';\nimport App from './App.vue';\n\nconst app = createApp(App);\napp.use(RegleVuePlugin);\napp.mount('#app');",
|
|
553
|
+
"tags": { "see": "://reglejs.dev/introduction/devtools Documentation" }
|
|
547
554
|
},
|
|
548
555
|
{
|
|
549
556
|
"name": "unwrapRuleParameters",
|
|
@@ -562,16 +569,16 @@ var docs_data_default = {
|
|
|
562
569
|
{
|
|
563
570
|
"name": "useCollectScope",
|
|
564
571
|
"kind": "function",
|
|
565
|
-
"description": "",
|
|
572
|
+
"description": "Composable to collect and merge all Regle instances created with the default `useScopedRegle` within the same scope.\nReturns a merged `r$` object allowing validation across multiple components simultaneously.\n\nChildren properties like `$value` and `$errors` are converted to arrays instead of objects.\nYou have access to all validation properties like `$error`, `$invalid`, `$validate()`, etc.",
|
|
566
573
|
"parameters": [{
|
|
567
574
|
"name": "namespace",
|
|
568
575
|
"type": "MaybeRefOrGetter<string | string[]>",
|
|
569
|
-
"description": "",
|
|
576
|
+
"description": "- Optional namespace or array of namespaces to filter which scoped instances to collect",
|
|
570
577
|
"optional": true
|
|
571
578
|
}],
|
|
572
|
-
"returnType": "{
|
|
573
|
-
"example": "",
|
|
574
|
-
"tags": {}
|
|
579
|
+
"returnType": "{ r$: MergedScopedRegles<TValue>; }",
|
|
580
|
+
"example": "// ParentComponent.vue\nimport { useCollectScope } from '@regle/core';\n\nconst { r$ } = useCollectScope();\n// Or with namespace filtering\nconst { r$ } = useCollectScope('contacts');\n\n// Validate all collected forms\nconst { result, data } = await r$.$validate();\n// Access collected errors\nconsole.log(r$.$errors);",
|
|
581
|
+
"tags": { "see": "://reglejs.dev/advanced-usage/scoped-validation Documentation" }
|
|
575
582
|
},
|
|
576
583
|
{
|
|
577
584
|
"name": "useRegle",
|
|
@@ -594,7 +601,7 @@ var docs_data_default = {
|
|
|
594
601
|
"parameters": [],
|
|
595
602
|
"returnType": "{ regle: $InternalRegleStatusType; }",
|
|
596
603
|
"example": "",
|
|
597
|
-
"tags": {}
|
|
604
|
+
"tags": { "internal": "This is the internal function that creates the root storage for the Regle instance.\nThis allows shared logic between all `useRegle` like composables" }
|
|
598
605
|
},
|
|
599
606
|
{
|
|
600
607
|
"name": "useRules",
|
|
@@ -617,17 +624,17 @@ var docs_data_default = {
|
|
|
617
624
|
},
|
|
618
625
|
{
|
|
619
626
|
"name": "useScopedRegle",
|
|
620
|
-
"kind": "
|
|
621
|
-
"description": "",
|
|
627
|
+
"kind": "function",
|
|
628
|
+
"description": "Clone of `useRegle` that automatically registers its instance for collection by `useCollectScope`.\nEvery time it's called, a new instance is added for the parent scope to collect.\n\nCan be called multiple times anywhere in your app - not restricted to components or DOM.\nWhen the component is unmounted or scope is disposed, the instance is automatically unregistered.",
|
|
622
629
|
"parameters": [{
|
|
623
630
|
"name": "params",
|
|
624
631
|
"type": "[state: MaybeRef<TState> | DeepReactiveState<TState>, rulesFactory: TState extends PrimitiveTypes ? MaybeRefOrGetter<TDecl> : TState extends Record<...> ? MaybeRefOrComputedRef<...> | ((...args: any[]...",
|
|
625
632
|
"description": "",
|
|
626
633
|
"optional": false
|
|
627
634
|
}],
|
|
628
|
-
"returnType": "NonNullable<TState> extends PrimitiveTypes ?
|
|
629
|
-
"example": "",
|
|
630
|
-
"tags": {}
|
|
635
|
+
"returnType": "NonNullable<TState> extends PrimitiveTypes ? RegleSingleField<PrimitiveTypes & TState & {}, TDecl, never, { ...; }> : Regle<...>",
|
|
636
|
+
"example": "// ChildComponent.vue\nimport { useScopedRegle } from '@regle/core';\n\nconst { r$ } = useScopedRegle(\n { email: '' },\n { email: { required, email } },\n { namespace: 'contacts' }\n);",
|
|
637
|
+
"tags": { "see": "://reglejs.dev/advanced-usage/scoped-validation Documentation" }
|
|
631
638
|
},
|
|
632
639
|
{
|
|
633
640
|
"name": "variantToRef",
|
|
@@ -1656,9 +1663,23 @@ function searchApi(query) {
|
|
|
1656
1663
|
return results;
|
|
1657
1664
|
}
|
|
1658
1665
|
|
|
1659
|
-
var version = "1.14.
|
|
1666
|
+
var version = "1.14.2";
|
|
1660
1667
|
|
|
1661
|
-
|
|
1668
|
+
function jsonResponse(data$1) {
|
|
1669
|
+
return { content: [{
|
|
1670
|
+
type: "text",
|
|
1671
|
+
text: JSON.stringify(data$1, null, 2)
|
|
1672
|
+
}] };
|
|
1673
|
+
}
|
|
1674
|
+
function errorResponse(error, extra) {
|
|
1675
|
+
return {
|
|
1676
|
+
...jsonResponse({
|
|
1677
|
+
error,
|
|
1678
|
+
...extra
|
|
1679
|
+
}),
|
|
1680
|
+
isError: true
|
|
1681
|
+
};
|
|
1682
|
+
}
|
|
1662
1683
|
const server = new McpServer({
|
|
1663
1684
|
name: "regle-mcp-server",
|
|
1664
1685
|
version,
|
|
@@ -1666,55 +1687,66 @@ const server = new McpServer({
|
|
|
1666
1687
|
title: "Regle MCP Server",
|
|
1667
1688
|
websiteUrl: "https://reglejs.dev"
|
|
1668
1689
|
});
|
|
1669
|
-
server.registerTool("regle-list-
|
|
1690
|
+
server.registerTool("regle-list-documentation", {
|
|
1670
1691
|
title: "List all available Regle documentation pages",
|
|
1671
1692
|
inputSchema: z.object({ category: z.string().optional().describe("Filter by category (e.g., \"rules\", \"core-concepts\", \"introduction\")") })
|
|
1672
1693
|
}, async ({ category }) => {
|
|
1673
1694
|
const filteredDocs = category ? getDocsByCategory(category) : docs;
|
|
1674
|
-
return {
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
}))
|
|
1684
|
-
}, null, 2)
|
|
1685
|
-
}] };
|
|
1695
|
+
return jsonResponse({
|
|
1696
|
+
message: "Available Regle documentation pages",
|
|
1697
|
+
category: category || "all",
|
|
1698
|
+
count: filteredDocs.length,
|
|
1699
|
+
docs: filteredDocs.map((doc) => ({
|
|
1700
|
+
id: doc.id,
|
|
1701
|
+
title: doc.title
|
|
1702
|
+
}))
|
|
1703
|
+
});
|
|
1686
1704
|
});
|
|
1687
|
-
server.registerTool("regle-get-
|
|
1705
|
+
server.registerTool("regle-get-documentation", {
|
|
1688
1706
|
title: "Get the full content of a specific Regle documentation page",
|
|
1689
1707
|
inputSchema: z.object({ id: z.string().describe("The documentation page ID (e.g., \"core-concepts-rules-built-in-rules\")") })
|
|
1690
1708
|
}, async ({ id }) => {
|
|
1691
1709
|
const doc = getDocById(id);
|
|
1692
|
-
if (!doc) {
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
isError: true
|
|
1704
|
-
};
|
|
1705
|
-
}
|
|
1706
|
-
return { content: [{
|
|
1707
|
-
type: "text",
|
|
1708
|
-
text: JSON.stringify({
|
|
1709
|
-
id: doc.id,
|
|
1710
|
-
title: doc.title,
|
|
1711
|
-
category: doc.category,
|
|
1712
|
-
path: doc.path,
|
|
1713
|
-
content: doc.content
|
|
1714
|
-
}, null, 2)
|
|
1715
|
-
}] };
|
|
1710
|
+
if (!doc) return errorResponse("Documentation page not found", {
|
|
1711
|
+
requestedId: id,
|
|
1712
|
+
availableIds: docs.map((d) => d.id)
|
|
1713
|
+
});
|
|
1714
|
+
return jsonResponse({
|
|
1715
|
+
id: doc.id,
|
|
1716
|
+
title: doc.title,
|
|
1717
|
+
category: doc.category,
|
|
1718
|
+
path: doc.path,
|
|
1719
|
+
content: doc.content
|
|
1720
|
+
});
|
|
1716
1721
|
});
|
|
1717
|
-
server.registerTool("regle-
|
|
1722
|
+
server.registerTool("regle-get-usage-guide", {
|
|
1723
|
+
title: "Get a comprehensive guide on how to use the useRegle composable",
|
|
1724
|
+
inputSchema: z.object({})
|
|
1725
|
+
}, async () => {
|
|
1726
|
+
const doc = getDocById("core-concepts-index");
|
|
1727
|
+
if (!doc) return errorResponse("useRegle guide not found");
|
|
1728
|
+
return jsonResponse({
|
|
1729
|
+
id: doc.id,
|
|
1730
|
+
title: doc.title,
|
|
1731
|
+
category: doc.category,
|
|
1732
|
+
content: doc.content
|
|
1733
|
+
});
|
|
1734
|
+
});
|
|
1735
|
+
server.registerTool("regle-get-vuelidate-migration-guide", {
|
|
1736
|
+
title: "Get a guide on how to migrate from Vuelidate to Regle",
|
|
1737
|
+
inputSchema: z.object({})
|
|
1738
|
+
}, async () => {
|
|
1739
|
+
const doc = getDocById("introduction-migrate-from-vuelidate");
|
|
1740
|
+
if (!doc) return errorResponse("Vuelidate migration guide not found");
|
|
1741
|
+
return jsonResponse({
|
|
1742
|
+
id: doc.id,
|
|
1743
|
+
title: doc.title,
|
|
1744
|
+
category: doc.category,
|
|
1745
|
+
content: doc.content
|
|
1746
|
+
});
|
|
1747
|
+
});
|
|
1748
|
+
const categories = getCategories();
|
|
1749
|
+
server.registerTool("regle-search-documentation", {
|
|
1718
1750
|
title: "Search Regle documentation for specific topics, rules, or concepts",
|
|
1719
1751
|
inputSchema: z.object({
|
|
1720
1752
|
query: z.string().describe("Search query (e.g., \"required\", \"async validation\", \"useRegle\")"),
|
|
@@ -1722,53 +1754,39 @@ server.registerTool("regle-search-docs", {
|
|
|
1722
1754
|
})
|
|
1723
1755
|
}, async ({ query, limit }) => {
|
|
1724
1756
|
const results = searchDocs(query).slice(0, limit);
|
|
1725
|
-
if (results.length === 0) return {
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
suggestions: categories
|
|
1732
|
-
}, null, 2)
|
|
1733
|
-
}] };
|
|
1757
|
+
if (results.length === 0) return jsonResponse({
|
|
1758
|
+
query,
|
|
1759
|
+
resultCount: 0,
|
|
1760
|
+
results: [],
|
|
1761
|
+
suggestions: categories
|
|
1762
|
+
});
|
|
1734
1763
|
const formattedResults = results.map((doc) => ({
|
|
1735
1764
|
id: doc.id,
|
|
1736
1765
|
title: doc.title,
|
|
1737
1766
|
category: doc.category,
|
|
1738
1767
|
preview: doc.content.substring(0, 300) + "..."
|
|
1739
1768
|
}));
|
|
1740
|
-
return {
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
results: formattedResults
|
|
1746
|
-
}, null, 2)
|
|
1747
|
-
}] };
|
|
1769
|
+
return jsonResponse({
|
|
1770
|
+
query,
|
|
1771
|
+
resultCount: results.length,
|
|
1772
|
+
results: formattedResults
|
|
1773
|
+
});
|
|
1748
1774
|
});
|
|
1749
|
-
server.registerTool("regle-
|
|
1775
|
+
server.registerTool("regle-list-rules", {
|
|
1750
1776
|
title: "Get a quick reference of all built-in validation rules in Regle",
|
|
1751
1777
|
inputSchema: z.object({})
|
|
1752
1778
|
}, async () => {
|
|
1753
1779
|
const rules = getRulesFromDocs();
|
|
1754
|
-
if (rules.length === 0) return
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
title: "Built-in Rules",
|
|
1765
|
-
package: "@regle/rules",
|
|
1766
|
-
count: rules.length,
|
|
1767
|
-
rules: rules.map((r) => ({
|
|
1768
|
-
name: r.name,
|
|
1769
|
-
description: r.description
|
|
1770
|
-
})),
|
|
1771
|
-
usageExample: `import { useRegle } from '@regle/core';
|
|
1780
|
+
if (rules.length === 0) return errorResponse("Built-in rules documentation not found");
|
|
1781
|
+
return jsonResponse({
|
|
1782
|
+
title: "Built-in Rules",
|
|
1783
|
+
package: "@regle/rules",
|
|
1784
|
+
count: rules.length,
|
|
1785
|
+
rules: rules.map((r) => ({
|
|
1786
|
+
name: r.name,
|
|
1787
|
+
description: r.description
|
|
1788
|
+
})),
|
|
1789
|
+
usageExample: `import { useRegle } from '@regle/core';
|
|
1772
1790
|
import { required, email, minLength } from '@regle/rules';
|
|
1773
1791
|
|
|
1774
1792
|
const { r$ } = useRegle(
|
|
@@ -1778,44 +1796,45 @@ const { r$ } = useRegle(
|
|
|
1778
1796
|
password: { required, minLength: minLength(8) }
|
|
1779
1797
|
}
|
|
1780
1798
|
);`,
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1799
|
+
fullDocId: "core-concepts-rules-built-in-rules"
|
|
1800
|
+
});
|
|
1801
|
+
});
|
|
1802
|
+
server.registerTool("regle-get-rule-reference", {
|
|
1803
|
+
title: "Get details about a specific built-in validation rule",
|
|
1804
|
+
inputSchema: z.object({ name: z.string().describe("The rule name (e.g., \"required\", \"email\", \"minLength\")") })
|
|
1805
|
+
}, async ({ name }) => {
|
|
1806
|
+
const rule = getApiByName(name);
|
|
1807
|
+
if (!rule) {
|
|
1808
|
+
const allRules = getRulesFromDocs();
|
|
1809
|
+
return errorResponse(`Rule "${name}" not found`, { availableRules: allRules.map((r) => r.name) });
|
|
1810
|
+
}
|
|
1811
|
+
return jsonResponse({
|
|
1812
|
+
name: rule.name,
|
|
1813
|
+
description: rule.description,
|
|
1814
|
+
package: "@regle/rules",
|
|
1815
|
+
usageExample: rule.example,
|
|
1816
|
+
fullDocId: "core-concepts-rules-built-in-rules"
|
|
1817
|
+
});
|
|
1784
1818
|
});
|
|
1785
|
-
server.registerTool("regle-
|
|
1819
|
+
server.registerTool("regle-list-validation-properties", {
|
|
1786
1820
|
title: "Get documentation on all validation properties available on r$ and field objects",
|
|
1787
1821
|
inputSchema: z.object({})
|
|
1788
1822
|
}, async () => {
|
|
1789
1823
|
const doc = getDocById("core-concepts-validation-properties");
|
|
1790
|
-
if (!doc) return
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
};
|
|
1797
|
-
return { content: [{
|
|
1798
|
-
type: "text",
|
|
1799
|
-
text: JSON.stringify({
|
|
1800
|
-
id: doc.id,
|
|
1801
|
-
title: doc.title,
|
|
1802
|
-
category: doc.category,
|
|
1803
|
-
content: doc.content
|
|
1804
|
-
}, null, 2)
|
|
1805
|
-
}] };
|
|
1824
|
+
if (!doc) return errorResponse("Validation properties documentation not found");
|
|
1825
|
+
return jsonResponse({
|
|
1826
|
+
id: doc.id,
|
|
1827
|
+
title: doc.title,
|
|
1828
|
+
category: doc.category,
|
|
1829
|
+
content: doc.content
|
|
1830
|
+
});
|
|
1806
1831
|
});
|
|
1807
|
-
server.registerTool("regle-
|
|
1832
|
+
server.registerTool("regle-list-helpers", {
|
|
1808
1833
|
title: "Get a reference of all validation helper utilities available in Regle",
|
|
1809
1834
|
inputSchema: z.object({})
|
|
1810
1835
|
}, async () => {
|
|
1811
1836
|
const helpers = getHelpersFromDocs();
|
|
1812
|
-
if (helpers.length === 0) return
|
|
1813
|
-
content: [{
|
|
1814
|
-
type: "text",
|
|
1815
|
-
text: JSON.stringify({ error: "Validation helpers documentation not found" }, null, 2)
|
|
1816
|
-
}],
|
|
1817
|
-
isError: true
|
|
1818
|
-
};
|
|
1837
|
+
if (helpers.length === 0) return errorResponse("Validation helpers documentation not found");
|
|
1819
1838
|
const guards = helpers.filter((h) => h.category === "guard");
|
|
1820
1839
|
const operations = helpers.filter((h) => h.category === "operation");
|
|
1821
1840
|
const coerces = helpers.filter((h) => h.category === "coerce");
|
|
@@ -1823,27 +1842,25 @@ server.registerTool("regle-get-helpers-reference", {
|
|
|
1823
1842
|
name: h.name,
|
|
1824
1843
|
description: h.description
|
|
1825
1844
|
}));
|
|
1826
|
-
return {
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
},
|
|
1846
|
-
usageExample: `import { createRule, type Maybe } from '@regle/core';
|
|
1845
|
+
return jsonResponse({
|
|
1846
|
+
title: "Validation Helpers",
|
|
1847
|
+
package: "@regle/rules",
|
|
1848
|
+
totalCount: helpers.length,
|
|
1849
|
+
categories: {
|
|
1850
|
+
guards: {
|
|
1851
|
+
description: "Runtime and Type Guards",
|
|
1852
|
+
helpers: formatHelpers(guards)
|
|
1853
|
+
},
|
|
1854
|
+
operations: {
|
|
1855
|
+
description: "Operations Utils",
|
|
1856
|
+
helpers: formatHelpers(operations)
|
|
1857
|
+
},
|
|
1858
|
+
coerces: {
|
|
1859
|
+
description: "Coerce Utils",
|
|
1860
|
+
helpers: formatHelpers(coerces)
|
|
1861
|
+
}
|
|
1862
|
+
},
|
|
1863
|
+
usageExample: `import { createRule, type Maybe } from '@regle/core';
|
|
1847
1864
|
import { isFilled, getSize } from '@regle/rules';
|
|
1848
1865
|
|
|
1849
1866
|
const rule = createRule({
|
|
@@ -1855,31 +1872,26 @@ const rule = createRule({
|
|
|
1855
1872
|
},
|
|
1856
1873
|
message: 'Error'
|
|
1857
1874
|
});`,
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
}] };
|
|
1875
|
+
fullDocId: "core-concepts-rules-validations-helpers"
|
|
1876
|
+
});
|
|
1861
1877
|
});
|
|
1862
|
-
server.registerTool("regle-get-
|
|
1863
|
-
title: "Get
|
|
1864
|
-
inputSchema: z.object({})
|
|
1865
|
-
}, async () => {
|
|
1866
|
-
const
|
|
1867
|
-
if (!
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
category: doc.category,
|
|
1880
|
-
content: doc.content
|
|
1881
|
-
}, null, 2)
|
|
1882
|
-
}] };
|
|
1878
|
+
server.registerTool("regle-get-helper-reference", {
|
|
1879
|
+
title: "Get details about a specific validation helper utility",
|
|
1880
|
+
inputSchema: z.object({ name: z.string().describe("The helper name (e.g., \"isFilled\", \"getSize\", \"toNumber\")") })
|
|
1881
|
+
}, async ({ name }) => {
|
|
1882
|
+
const helper = getApiByName(name);
|
|
1883
|
+
if (!helper) {
|
|
1884
|
+
const allHelpers = getHelpersFromDocs();
|
|
1885
|
+
return errorResponse(`Helper "${name}" not found`, { availableHelpers: allHelpers.map((h) => h.name) });
|
|
1886
|
+
}
|
|
1887
|
+
return jsonResponse({
|
|
1888
|
+
name: helper.name,
|
|
1889
|
+
description: helper.description,
|
|
1890
|
+
category: helper.tags,
|
|
1891
|
+
package: "@regle/rules",
|
|
1892
|
+
usageExample: helper.example,
|
|
1893
|
+
fullDocId: "core-concepts-rules-validations-helpers"
|
|
1894
|
+
});
|
|
1883
1895
|
});
|
|
1884
1896
|
const apiPackages = getApiPackages();
|
|
1885
1897
|
server.registerTool("regle-get-api-reference", {
|
|
@@ -1892,84 +1904,53 @@ server.registerTool("regle-get-api-reference", {
|
|
|
1892
1904
|
}, async ({ package: packageName, name, search }) => {
|
|
1893
1905
|
if (name) {
|
|
1894
1906
|
const apiItem = getApiByName(name, packageName);
|
|
1895
|
-
if (!apiItem) return {
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
};
|
|
1905
|
-
return { content: [{
|
|
1906
|
-
type: "text",
|
|
1907
|
-
text: JSON.stringify({
|
|
1908
|
-
name: apiItem.name,
|
|
1909
|
-
kind: apiItem.kind,
|
|
1910
|
-
description: apiItem.description,
|
|
1911
|
-
parameters: apiItem.parameters,
|
|
1912
|
-
returnType: apiItem.returnType,
|
|
1913
|
-
example: apiItem.example,
|
|
1914
|
-
tags: apiItem.tags
|
|
1915
|
-
}, null, 2)
|
|
1916
|
-
}] };
|
|
1907
|
+
if (!apiItem) return errorResponse(`API export "${name}" not found`, { availablePackages: apiPackages });
|
|
1908
|
+
return jsonResponse({
|
|
1909
|
+
name: apiItem.name,
|
|
1910
|
+
kind: apiItem.kind,
|
|
1911
|
+
description: apiItem.description,
|
|
1912
|
+
parameters: apiItem.parameters,
|
|
1913
|
+
returnType: apiItem.returnType,
|
|
1914
|
+
example: apiItem.example,
|
|
1915
|
+
tags: apiItem.tags
|
|
1916
|
+
});
|
|
1917
1917
|
}
|
|
1918
1918
|
if (search) {
|
|
1919
1919
|
const results = searchApi(search);
|
|
1920
|
-
return {
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
}))
|
|
1931
|
-
}, null, 2)
|
|
1932
|
-
}] };
|
|
1920
|
+
return jsonResponse({
|
|
1921
|
+
query: search,
|
|
1922
|
+
resultCount: results.length,
|
|
1923
|
+
results: results.map((r) => ({
|
|
1924
|
+
name: r.name,
|
|
1925
|
+
package: r.package,
|
|
1926
|
+
kind: r.kind,
|
|
1927
|
+
description: r.description.substring(0, 200) + (r.description.length > 200 ? "..." : "")
|
|
1928
|
+
}))
|
|
1929
|
+
});
|
|
1933
1930
|
}
|
|
1934
1931
|
if (packageName) {
|
|
1935
1932
|
const apis = getApiByPackage(packageName);
|
|
1936
|
-
if (apis.length === 0) return {
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
text: JSON.stringify({
|
|
1949
|
-
package: packageName,
|
|
1950
|
-
exportCount: apis.length,
|
|
1951
|
-
exports: apis.map((a) => ({
|
|
1952
|
-
name: a.name,
|
|
1953
|
-
kind: a.kind,
|
|
1954
|
-
description: a.description.substring(0, 150) + (a.description.length > 150 ? "..." : ""),
|
|
1955
|
-
hasExample: !!a.example,
|
|
1956
|
-
parameterCount: a.parameters.length
|
|
1957
|
-
}))
|
|
1958
|
-
}, null, 2)
|
|
1959
|
-
}] };
|
|
1933
|
+
if (apis.length === 0) return errorResponse(`Package "${packageName}" not found or has no exports`, { availablePackages: apiPackages });
|
|
1934
|
+
return jsonResponse({
|
|
1935
|
+
package: packageName,
|
|
1936
|
+
exportCount: apis.length,
|
|
1937
|
+
exports: apis.map((a) => ({
|
|
1938
|
+
name: a.name,
|
|
1939
|
+
kind: a.kind,
|
|
1940
|
+
description: a.description.substring(0, 150) + (a.description.length > 150 ? "..." : ""),
|
|
1941
|
+
hasExample: !!a.example,
|
|
1942
|
+
parameterCount: a.parameters.length
|
|
1943
|
+
}))
|
|
1944
|
+
});
|
|
1960
1945
|
}
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
packages: packageSummary,
|
|
1970
|
-
usage: "Use \"package\" to list exports, \"name\" to get specific export details, or \"search\" to find exports"
|
|
1971
|
-
}, null, 2)
|
|
1972
|
-
}] };
|
|
1946
|
+
return jsonResponse({
|
|
1947
|
+
message: "Available Regle API packages",
|
|
1948
|
+
packages: apiPackages.map((pkg) => ({
|
|
1949
|
+
package: pkg,
|
|
1950
|
+
exportCount: getApiByPackage(pkg).length
|
|
1951
|
+
})),
|
|
1952
|
+
usage: "Use \"package\" to list exports, \"name\" to get specific export details, or \"search\" to find exports"
|
|
1953
|
+
});
|
|
1973
1954
|
});
|
|
1974
1955
|
async function main() {
|
|
1975
1956
|
const transport = new StdioServerTransport();
|