@aleph-alpha/lib-mcp 2.0.0 → 2.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 +75 -14
- package/components-meta.json +45 -49
- package/dist/cli.js +31 -10
- package/dist/scripts/generate-component-meta.js +22 -7
- package/dist/server.js +31 -10
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,17 +1,30 @@
|
|
|
1
1
|
# @aleph-alpha/lib-mcp
|
|
2
2
|
|
|
3
|
-
MCP (Model Context Protocol) Server for UI Library component discovery tools.
|
|
3
|
+
MCP (Model Context Protocol) Server for UI Library and ChatKit component discovery tools.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
This package provides an MCP server that enables AI assistants (like Claude and Cursor) to discover and understand
|
|
7
|
+
This package provides an MCP server that enables AI assistants (like Claude and Cursor) to discover and understand components from:
|
|
8
|
+
|
|
9
|
+
- [`@aleph-alpha/ui-library`](../ui-library) — `Ui*` components
|
|
10
|
+
- [`@aleph-alpha/chat-kit`](../chat-kit) — `Ck*` components
|
|
11
|
+
|
|
12
|
+
It offers tools to list available components and retrieve detailed documentation including props, examples, and usage guidance.
|
|
8
13
|
|
|
9
14
|
## Installation
|
|
10
15
|
|
|
16
|
+
Install `@aleph-alpha/lib-mcp` together with the component packages whose docs you want to query. UI Library is required; ChatKit is optional and only needed if you want `Ck*` component docs.
|
|
17
|
+
|
|
11
18
|
```bash
|
|
19
|
+
# UI Library only
|
|
12
20
|
pnpm add @aleph-alpha/lib-mcp @aleph-alpha/ui-library
|
|
21
|
+
|
|
22
|
+
# UI Library + ChatKit
|
|
23
|
+
pnpm add @aleph-alpha/lib-mcp @aleph-alpha/ui-library @aleph-alpha/chat-kit
|
|
13
24
|
```
|
|
14
25
|
|
|
26
|
+
> ChatKit docs require `@aleph-alpha/chat-kit` to publish its `src/` directory (component `types.ts` and `*.stories.ts` files). If `get_chat_kit_docs` returns "Could not find chat-kit source directory", upgrade `@aleph-alpha/chat-kit` to a version that includes `src/` in its published files.
|
|
27
|
+
|
|
15
28
|
## Usage
|
|
16
29
|
|
|
17
30
|
### Configure MCP Server
|
|
@@ -24,6 +37,9 @@ npx @aleph-alpha/lib-mcp mcp-install
|
|
|
24
37
|
|
|
25
38
|
# For both Claude Code and Cursor
|
|
26
39
|
npx @aleph-alpha/lib-mcp mcp-install --cursor
|
|
40
|
+
|
|
41
|
+
# For VS Code
|
|
42
|
+
npx @aleph-alpha/lib-mcp mcp-install --vscode
|
|
27
43
|
```
|
|
28
44
|
|
|
29
45
|
After installation, restart your IDE to activate the MCP tools.
|
|
@@ -32,9 +48,11 @@ After installation, restart your IDE to activate the MCP tools.
|
|
|
32
48
|
|
|
33
49
|
Once configured, the following tools are available to your AI assistant:
|
|
34
50
|
|
|
35
|
-
####
|
|
51
|
+
#### UI Library tools
|
|
52
|
+
|
|
53
|
+
##### `list_components`
|
|
36
54
|
|
|
37
|
-
Lists all available UI components. Supports optional filtering by name, category, or description.
|
|
55
|
+
Lists all available UI Library components. Supports optional filtering by name, category, or description.
|
|
38
56
|
|
|
39
57
|
```
|
|
40
58
|
list_components
|
|
@@ -42,9 +60,9 @@ list_components --filter="button"
|
|
|
42
60
|
list_components --filter="form"
|
|
43
61
|
```
|
|
44
62
|
|
|
45
|
-
|
|
63
|
+
##### `get_component_docs`
|
|
46
64
|
|
|
47
|
-
Retrieves full documentation for a specific component including:
|
|
65
|
+
Retrieves full documentation for a specific UI Library component including:
|
|
48
66
|
|
|
49
67
|
- Component description
|
|
50
68
|
- Props with types, defaults, and descriptions
|
|
@@ -57,6 +75,45 @@ get_component_docs UiButton
|
|
|
57
75
|
get_component_docs Button # "Ui" prefix is optional
|
|
58
76
|
```
|
|
59
77
|
|
|
78
|
+
#### ChatKit tools
|
|
79
|
+
|
|
80
|
+
Available when `@aleph-alpha/chat-kit` is installed alongside this package.
|
|
81
|
+
|
|
82
|
+
##### `list_chat_kit_components`
|
|
83
|
+
|
|
84
|
+
Lists all available ChatKit (`Ck*`) components. Supports optional filtering by name, category, or description.
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
list_chat_kit_components
|
|
88
|
+
list_chat_kit_components --filter="history"
|
|
89
|
+
list_chat_kit_components --filter="message"
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
##### `get_chat_kit_docs`
|
|
93
|
+
|
|
94
|
+
Retrieves full documentation for a specific ChatKit component, with the same shape as `get_component_docs`:
|
|
95
|
+
|
|
96
|
+
- Component description
|
|
97
|
+
- Props with types, defaults, and descriptions
|
|
98
|
+
- Sub-components (if applicable)
|
|
99
|
+
- Usage guidance
|
|
100
|
+
- Code examples
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
get_chat_kit_docs CkHistory
|
|
104
|
+
get_chat_kit_docs History # "Ck" prefix is optional
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
#### Setup tool
|
|
108
|
+
|
|
109
|
+
##### `get_setup_guide`
|
|
110
|
+
|
|
111
|
+
Returns the setup and installation guide for integrating the UI library into a project (UnoCSS config, Vite config, required dependencies, and MCP setup instructions).
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
get_setup_guide
|
|
115
|
+
```
|
|
116
|
+
|
|
60
117
|
## Development
|
|
61
118
|
|
|
62
119
|
### Building
|
|
@@ -67,6 +124,8 @@ pnpm build
|
|
|
67
124
|
|
|
68
125
|
### Generating Component Metadata
|
|
69
126
|
|
|
127
|
+
Regenerates `components-meta.json` (UI Library) and `chat-kit-components-meta.json` (ChatKit) by scanning each package's source files.
|
|
128
|
+
|
|
70
129
|
```bash
|
|
71
130
|
pnpm generate:component-meta
|
|
72
131
|
```
|
|
@@ -79,21 +138,23 @@ pnpm test
|
|
|
79
138
|
|
|
80
139
|
## How It Works
|
|
81
140
|
|
|
82
|
-
The MCP server reads component metadata from:
|
|
141
|
+
The MCP server reads component metadata from each package's source layout:
|
|
83
142
|
|
|
84
143
|
1. **`types.ts`**: Extracts props, their types, descriptions, and component-level JSDoc tags (`@category`, `@useCases`, `@keywords`, `@related`)
|
|
85
144
|
2. **`*.stories.ts`**: Extracts code examples and usage guidance from Storybook stories
|
|
86
|
-
3. **`
|
|
145
|
+
3. **`index.ts`**: Detects sub-component exports for the documented component
|
|
146
|
+
4. **`components-meta.json` / `chat-kit-components-meta.json`**: Pre-generated metadata for faster lookups
|
|
147
|
+
|
|
148
|
+
UI Library components are read from `@aleph-alpha/ui-library/src/**`, and ChatKit components from `@aleph-alpha/chat-kit/src/components/**`. Both packages must publish their `src/` directory for docs to resolve when consumed from `node_modules`.
|
|
87
149
|
|
|
88
150
|
## CLI Commands
|
|
89
151
|
|
|
90
|
-
| Command
|
|
91
|
-
|
|
92
|
-
| `mcp-install` | Configure MCP server for IDE |
|
|
93
|
-
| `serve`
|
|
94
|
-
| `--help`
|
|
152
|
+
| Command | Description |
|
|
153
|
+
| ------------- | ----------------------------------------------------------------------- |
|
|
154
|
+
| `mcp-install` | Configure MCP server for IDE (`--cursor`, `--vscode` to add extra IDEs) |
|
|
155
|
+
| `serve` | Start the MCP server (used internally by IDE) |
|
|
156
|
+
| `--help` | Show help message |
|
|
95
157
|
|
|
96
158
|
## License
|
|
97
159
|
|
|
98
160
|
Apache-2.0
|
|
99
|
-
|
package/components-meta.json
CHANGED
|
@@ -526,7 +526,7 @@
|
|
|
526
526
|
"WithRadioItems",
|
|
527
527
|
"WithDestructiveAction",
|
|
528
528
|
"WithSubmenu",
|
|
529
|
-
"
|
|
529
|
+
"WithIconTrigger",
|
|
530
530
|
"WithSoftToggleTrigger",
|
|
531
531
|
"WithSoftToggleTriggerAndText",
|
|
532
532
|
"WithAvatarTrigger"
|
|
@@ -714,53 +714,7 @@
|
|
|
714
714
|
"examples": [
|
|
715
715
|
"Default",
|
|
716
716
|
"Sizes",
|
|
717
|
-
"
|
|
718
|
-
],
|
|
719
|
-
"_autoGenerated": true
|
|
720
|
-
},
|
|
721
|
-
"UiIconButton": {
|
|
722
|
-
"description": "A button that displays only an icon without text. Use for compact actions like close, edit, delete, or toolbar buttons. It is being merged into `UiButton` — use `UiButton` with an icon-only child and an `aria-label` instead (e.g. `<UiButton size=\"icon-sm\" aria-label=\"Close\"><UiIcon name=\"x\" /></UiButton>`).",
|
|
723
|
-
"category": "Actions",
|
|
724
|
-
"useCases": [
|
|
725
|
-
"close button",
|
|
726
|
-
"edit action",
|
|
727
|
-
"toolbar button",
|
|
728
|
-
"compact action"
|
|
729
|
-
],
|
|
730
|
-
"keywords": [
|
|
731
|
-
"iconbutton",
|
|
732
|
-
"icon",
|
|
733
|
-
"button",
|
|
734
|
-
"action",
|
|
735
|
-
"close",
|
|
736
|
-
"edit",
|
|
737
|
-
"delete"
|
|
738
|
-
],
|
|
739
|
-
"related": [
|
|
740
|
-
"UiButton",
|
|
741
|
-
"UiIcon"
|
|
742
|
-
],
|
|
743
|
-
"props": [
|
|
744
|
-
"variant",
|
|
745
|
-
"size",
|
|
746
|
-
"asChild",
|
|
747
|
-
"type",
|
|
748
|
-
"disabled",
|
|
749
|
-
"loading",
|
|
750
|
-
"ariaLabel"
|
|
751
|
-
],
|
|
752
|
-
"examples": [
|
|
753
|
-
"Default",
|
|
754
|
-
"Secondary",
|
|
755
|
-
"Destructive",
|
|
756
|
-
"Outline",
|
|
757
|
-
"Ghost",
|
|
758
|
-
"Link",
|
|
759
|
-
"Loading",
|
|
760
|
-
"Disabled",
|
|
761
|
-
"AllVariants",
|
|
762
|
-
"AllSizes",
|
|
763
|
-
"AsChild"
|
|
717
|
+
"IconLibrary"
|
|
764
718
|
],
|
|
765
719
|
"_autoGenerated": true
|
|
766
720
|
},
|
|
@@ -1349,6 +1303,48 @@
|
|
|
1349
1303
|
],
|
|
1350
1304
|
"_autoGenerated": true
|
|
1351
1305
|
},
|
|
1306
|
+
"UiSnackbar": {
|
|
1307
|
+
"description": "Toast notification container (Sonner). Place once near the app root, then call `toast()` (or `toast.success()`, `toast.error()`, etc.) from anywhere to display a non-blocking notification.",
|
|
1308
|
+
"category": "Feedback",
|
|
1309
|
+
"useCases": [
|
|
1310
|
+
"success confirmation",
|
|
1311
|
+
"error notice",
|
|
1312
|
+
"undo action",
|
|
1313
|
+
"async progress",
|
|
1314
|
+
"background updates"
|
|
1315
|
+
],
|
|
1316
|
+
"keywords": [
|
|
1317
|
+
"snackbar",
|
|
1318
|
+
"toast",
|
|
1319
|
+
"sonner",
|
|
1320
|
+
"notification",
|
|
1321
|
+
"alert",
|
|
1322
|
+
"message",
|
|
1323
|
+
"banner",
|
|
1324
|
+
"undo"
|
|
1325
|
+
],
|
|
1326
|
+
"related": [
|
|
1327
|
+
"UiAlert",
|
|
1328
|
+
"UiAlertDialog"
|
|
1329
|
+
],
|
|
1330
|
+
"props": [],
|
|
1331
|
+
"examples": [
|
|
1332
|
+
"SuccessHigh",
|
|
1333
|
+
"SuccessLow",
|
|
1334
|
+
"InfoHigh",
|
|
1335
|
+
"InfoLow",
|
|
1336
|
+
"WarningHigh",
|
|
1337
|
+
"WarningLow",
|
|
1338
|
+
"ErrorHigh",
|
|
1339
|
+
"ErrorLow",
|
|
1340
|
+
"AllVariants",
|
|
1341
|
+
"Default",
|
|
1342
|
+
"WithDescription",
|
|
1343
|
+
"PromiseSnackbar",
|
|
1344
|
+
"WithDialog"
|
|
1345
|
+
],
|
|
1346
|
+
"_autoGenerated": true
|
|
1347
|
+
},
|
|
1352
1348
|
"UiSpinner": {
|
|
1353
1349
|
"description": "An animated loading indicator. Use while content is loading or an action is processing.",
|
|
1354
1350
|
"category": "Feedback",
|
|
@@ -1681,7 +1677,7 @@
|
|
|
1681
1677
|
],
|
|
1682
1678
|
"examples": [
|
|
1683
1679
|
"Default",
|
|
1684
|
-
"
|
|
1680
|
+
"WithIconTrigger",
|
|
1685
1681
|
"InstantDelay",
|
|
1686
1682
|
"LongDelay",
|
|
1687
1683
|
"Disabled",
|
package/dist/cli.js
CHANGED
|
@@ -21425,11 +21425,15 @@ function detectCategoryDirs() {
|
|
|
21425
21425
|
return [];
|
|
21426
21426
|
}
|
|
21427
21427
|
const entries = fs4.readdirSync(srcPath, { withFileTypes: true });
|
|
21428
|
-
return entries.filter((entry) => entry.isDirectory()).filter(
|
|
21428
|
+
return entries.filter((entry) => entry.isDirectory()).filter(
|
|
21429
|
+
(entry) => !entry.name.startsWith(".") && entry.name !== "node_modules"
|
|
21430
|
+
).filter((entry) => {
|
|
21429
21431
|
try {
|
|
21430
21432
|
const dirPath = path4.join(srcPath, entry.name);
|
|
21431
21433
|
const subEntries = fs4.readdirSync(dirPath, { withFileTypes: true });
|
|
21432
|
-
return subEntries.some(
|
|
21434
|
+
return subEntries.some(
|
|
21435
|
+
(sub) => sub.isDirectory() && sub.name.startsWith(COMPONENT_PREFIX)
|
|
21436
|
+
);
|
|
21433
21437
|
} catch {
|
|
21434
21438
|
return false;
|
|
21435
21439
|
}
|
|
@@ -21970,7 +21974,10 @@ function parseInterface2(content, interfaceName) {
|
|
|
21970
21974
|
const propName = propMatch[2];
|
|
21971
21975
|
const isOptional = !!propMatch[3];
|
|
21972
21976
|
const typeStartIndex = propMatch.index + propMatch[0].length;
|
|
21973
|
-
const { type: propType, endIndex } = extractType2(
|
|
21977
|
+
const { type: propType, endIndex } = extractType2(
|
|
21978
|
+
interfaceBody,
|
|
21979
|
+
typeStartIndex
|
|
21980
|
+
);
|
|
21974
21981
|
propStartRegex.lastIndex = endIndex + 1;
|
|
21975
21982
|
const jsdoc = parseJSDoc2(jsdocComment);
|
|
21976
21983
|
props.push({
|
|
@@ -21987,7 +21994,9 @@ function parseInterface2(content, interfaceName) {
|
|
|
21987
21994
|
function extractComponentDescription2(content, interfaceName) {
|
|
21988
21995
|
const lines = content.split("\n");
|
|
21989
21996
|
const interfaceLineIndex = lines.findIndex(
|
|
21990
|
-
(line) => line.match(
|
|
21997
|
+
(line) => line.match(
|
|
21998
|
+
new RegExp(`export\\s+${TYPE_OR_INTERFACE2}\\s+${interfaceName}`)
|
|
21999
|
+
)
|
|
21991
22000
|
);
|
|
21992
22001
|
if (interfaceLineIndex === -1) {
|
|
21993
22002
|
return "";
|
|
@@ -22013,7 +22022,9 @@ function extractComponentDescription2(content, interfaceName) {
|
|
|
22013
22022
|
return "";
|
|
22014
22023
|
}
|
|
22015
22024
|
function resolveUnionOrIntersectionProps2(content, typeName) {
|
|
22016
|
-
const typeDefRegex = new RegExp(
|
|
22025
|
+
const typeDefRegex = new RegExp(
|
|
22026
|
+
`export\\s+type\\s+${typeName}\\s*=\\s*([^;]+)`
|
|
22027
|
+
);
|
|
22017
22028
|
const match = content.match(typeDefRegex);
|
|
22018
22029
|
if (!match) return [];
|
|
22019
22030
|
const referencedTypes = match[1].split(/[|&]/).map((t) => t.trim()).filter((t) => t.endsWith("Props"));
|
|
@@ -22041,7 +22052,9 @@ function readChatKitTypesFile(filePath, componentName) {
|
|
|
22041
22052
|
return null;
|
|
22042
22053
|
}
|
|
22043
22054
|
const resolvedName = componentName || path9.basename(path9.dirname(filePath));
|
|
22044
|
-
const exactRegex = new RegExp(
|
|
22055
|
+
const exactRegex = new RegExp(
|
|
22056
|
+
`export\\s+${TYPE_OR_INTERFACE2}\\s+(${resolvedName}Props)\\b`
|
|
22057
|
+
);
|
|
22045
22058
|
let propsInterfaceMatch = content.match(exactRegex);
|
|
22046
22059
|
if (!propsInterfaceMatch) {
|
|
22047
22060
|
const prefixRegex = new RegExp(
|
|
@@ -22307,7 +22320,9 @@ async function startServer() {
|
|
|
22307
22320
|
server.tool(
|
|
22308
22321
|
"list_chat_kit_components",
|
|
22309
22322
|
"List all Chat Kit components. Optionally filter by name, category, or description.",
|
|
22310
|
-
{
|
|
22323
|
+
{
|
|
22324
|
+
filter: external_exports.string().optional().describe("Filter by name/category/description")
|
|
22325
|
+
},
|
|
22311
22326
|
async ({ filter }) => {
|
|
22312
22327
|
try {
|
|
22313
22328
|
const components = listChatKitComponents(filter);
|
|
@@ -22322,7 +22337,10 @@ async function startServer() {
|
|
|
22322
22337
|
},
|
|
22323
22338
|
{}
|
|
22324
22339
|
);
|
|
22325
|
-
const sections = [
|
|
22340
|
+
const sections = [
|
|
22341
|
+
`Found ${components.length} chat-kit component(s):`,
|
|
22342
|
+
""
|
|
22343
|
+
];
|
|
22326
22344
|
Object.entries(grouped).forEach(([category, comps]) => {
|
|
22327
22345
|
sections.push(`## ${category}`, "");
|
|
22328
22346
|
comps.forEach((comp) => {
|
|
@@ -22339,11 +22357,14 @@ async function startServer() {
|
|
|
22339
22357
|
server.tool(
|
|
22340
22358
|
"get_chat_kit_docs",
|
|
22341
22359
|
"Get full documentation for a Chat Kit component including props, examples, and usage.",
|
|
22342
|
-
{
|
|
22360
|
+
{
|
|
22361
|
+
componentName: external_exports.string().describe('Component name (e.g., "CkChatBubble" or "ChatBubble")')
|
|
22362
|
+
},
|
|
22343
22363
|
async ({ componentName }) => {
|
|
22344
22364
|
try {
|
|
22345
22365
|
const docs = getChatKitComponentDocs(componentName);
|
|
22346
|
-
if (!docs)
|
|
22366
|
+
if (!docs)
|
|
22367
|
+
return error2(`Chat Kit component "${componentName}" not found.`);
|
|
22347
22368
|
return text(formatComponentDocs(docs));
|
|
22348
22369
|
} catch (e) {
|
|
22349
22370
|
return handleError(e);
|
|
@@ -97,11 +97,15 @@ function detectCategoryDirs() {
|
|
|
97
97
|
return [];
|
|
98
98
|
}
|
|
99
99
|
const entries = fs3.readdirSync(srcPath, { withFileTypes: true });
|
|
100
|
-
return entries.filter((entry) => entry.isDirectory()).filter(
|
|
100
|
+
return entries.filter((entry) => entry.isDirectory()).filter(
|
|
101
|
+
(entry) => !entry.name.startsWith(".") && entry.name !== "node_modules"
|
|
102
|
+
).filter((entry) => {
|
|
101
103
|
try {
|
|
102
104
|
const dirPath = path2.join(srcPath, entry.name);
|
|
103
105
|
const subEntries = fs3.readdirSync(dirPath, { withFileTypes: true });
|
|
104
|
-
return subEntries.some(
|
|
106
|
+
return subEntries.some(
|
|
107
|
+
(sub) => sub.isDirectory() && sub.name.startsWith(COMPONENT_PREFIX)
|
|
108
|
+
);
|
|
105
109
|
} catch {
|
|
106
110
|
return false;
|
|
107
111
|
}
|
|
@@ -177,7 +181,10 @@ var __filename2 = fileURLToPath2(import.meta.url);
|
|
|
177
181
|
var __dirname2 = path3.dirname(__filename2);
|
|
178
182
|
var PACKAGE_ROOT = getPackageRoot();
|
|
179
183
|
var OUTPUT_PATH = path3.join(PACKAGE_ROOT, "components-meta.json");
|
|
180
|
-
var CHAT_KIT_OUTPUT_PATH = path3.join(
|
|
184
|
+
var CHAT_KIT_OUTPUT_PATH = path3.join(
|
|
185
|
+
PACKAGE_ROOT,
|
|
186
|
+
"chat-kit-components-meta.json"
|
|
187
|
+
);
|
|
181
188
|
function extractJSDocTags(content, interfaceName) {
|
|
182
189
|
const declarationRegex = new RegExp(
|
|
183
190
|
`export\\s+(?:interface|type)\\s+${escapeRegex(interfaceName)}\\b`
|
|
@@ -265,13 +272,17 @@ function processComponent(componentDir, componentName) {
|
|
|
265
272
|
typesContent = fs4.readFileSync(typesPath, "utf-8");
|
|
266
273
|
}
|
|
267
274
|
const escapedName = escapeRegex(componentName);
|
|
268
|
-
const exactPropsRegex = new RegExp(
|
|
275
|
+
const exactPropsRegex = new RegExp(
|
|
276
|
+
`export\\s+(?:interface|type)\\s+(${escapedName}Props)\\b`
|
|
277
|
+
);
|
|
269
278
|
const exactMatch = typesContent.match(exactPropsRegex);
|
|
270
279
|
const subComponentPropsRegex = new RegExp(
|
|
271
280
|
`export\\s+(?:interface|type)\\s+(${escapedName}\\w*Props)\\b`
|
|
272
281
|
);
|
|
273
282
|
const subComponentMatch = typesContent.match(subComponentPropsRegex);
|
|
274
|
-
const anyPropsMatch = typesContent.match(
|
|
283
|
+
const anyPropsMatch = typesContent.match(
|
|
284
|
+
/export\s+(?:interface|type)\s+((?:Ui|Ck)\w+Props)/
|
|
285
|
+
);
|
|
275
286
|
const interfaceName = exactMatch?.[1] || subComponentMatch?.[1] || anyPropsMatch?.[1] || `${componentName}Props`;
|
|
276
287
|
const jsdocData = extractJSDocTags(typesContent, interfaceName);
|
|
277
288
|
const nameKeywords = extractKeywordsFromName(componentName);
|
|
@@ -342,8 +353,12 @@ function scanChatKitComponents() {
|
|
|
342
353
|
}
|
|
343
354
|
function summarize(label, meta) {
|
|
344
355
|
const total = Object.keys(meta).length;
|
|
345
|
-
const withUseCases = Object.values(meta).filter(
|
|
346
|
-
|
|
356
|
+
const withUseCases = Object.values(meta).filter(
|
|
357
|
+
(m) => m.useCases.length > 0
|
|
358
|
+
).length;
|
|
359
|
+
const withKeywords = Object.values(meta).filter(
|
|
360
|
+
(m) => m.keywords.length > 0
|
|
361
|
+
).length;
|
|
347
362
|
console.log(`
|
|
348
363
|
${label} summary:`);
|
|
349
364
|
console.log(` Components with @useCases: ${withUseCases}/${total}`);
|
package/dist/server.js
CHANGED
|
@@ -21313,11 +21313,15 @@ function detectCategoryDirs() {
|
|
|
21313
21313
|
return [];
|
|
21314
21314
|
}
|
|
21315
21315
|
const entries = fs3.readdirSync(srcPath, { withFileTypes: true });
|
|
21316
|
-
return entries.filter((entry) => entry.isDirectory()).filter(
|
|
21316
|
+
return entries.filter((entry) => entry.isDirectory()).filter(
|
|
21317
|
+
(entry) => !entry.name.startsWith(".") && entry.name !== "node_modules"
|
|
21318
|
+
).filter((entry) => {
|
|
21317
21319
|
try {
|
|
21318
21320
|
const dirPath = path3.join(srcPath, entry.name);
|
|
21319
21321
|
const subEntries = fs3.readdirSync(dirPath, { withFileTypes: true });
|
|
21320
|
-
return subEntries.some(
|
|
21322
|
+
return subEntries.some(
|
|
21323
|
+
(sub) => sub.isDirectory() && sub.name.startsWith(COMPONENT_PREFIX)
|
|
21324
|
+
);
|
|
21321
21325
|
} catch {
|
|
21322
21326
|
return false;
|
|
21323
21327
|
}
|
|
@@ -21858,7 +21862,10 @@ function parseInterface2(content, interfaceName) {
|
|
|
21858
21862
|
const propName = propMatch[2];
|
|
21859
21863
|
const isOptional = !!propMatch[3];
|
|
21860
21864
|
const typeStartIndex = propMatch.index + propMatch[0].length;
|
|
21861
|
-
const { type: propType, endIndex } = extractType2(
|
|
21865
|
+
const { type: propType, endIndex } = extractType2(
|
|
21866
|
+
interfaceBody,
|
|
21867
|
+
typeStartIndex
|
|
21868
|
+
);
|
|
21862
21869
|
propStartRegex.lastIndex = endIndex + 1;
|
|
21863
21870
|
const jsdoc = parseJSDoc2(jsdocComment);
|
|
21864
21871
|
props.push({
|
|
@@ -21875,7 +21882,9 @@ function parseInterface2(content, interfaceName) {
|
|
|
21875
21882
|
function extractComponentDescription2(content, interfaceName) {
|
|
21876
21883
|
const lines = content.split("\n");
|
|
21877
21884
|
const interfaceLineIndex = lines.findIndex(
|
|
21878
|
-
(line) => line.match(
|
|
21885
|
+
(line) => line.match(
|
|
21886
|
+
new RegExp(`export\\s+${TYPE_OR_INTERFACE2}\\s+${interfaceName}`)
|
|
21887
|
+
)
|
|
21879
21888
|
);
|
|
21880
21889
|
if (interfaceLineIndex === -1) {
|
|
21881
21890
|
return "";
|
|
@@ -21901,7 +21910,9 @@ function extractComponentDescription2(content, interfaceName) {
|
|
|
21901
21910
|
return "";
|
|
21902
21911
|
}
|
|
21903
21912
|
function resolveUnionOrIntersectionProps2(content, typeName) {
|
|
21904
|
-
const typeDefRegex = new RegExp(
|
|
21913
|
+
const typeDefRegex = new RegExp(
|
|
21914
|
+
`export\\s+type\\s+${typeName}\\s*=\\s*([^;]+)`
|
|
21915
|
+
);
|
|
21905
21916
|
const match = content.match(typeDefRegex);
|
|
21906
21917
|
if (!match) return [];
|
|
21907
21918
|
const referencedTypes = match[1].split(/[|&]/).map((t) => t.trim()).filter((t) => t.endsWith("Props"));
|
|
@@ -21929,7 +21940,9 @@ function readChatKitTypesFile(filePath, componentName) {
|
|
|
21929
21940
|
return null;
|
|
21930
21941
|
}
|
|
21931
21942
|
const resolvedName = componentName || path8.basename(path8.dirname(filePath));
|
|
21932
|
-
const exactRegex = new RegExp(
|
|
21943
|
+
const exactRegex = new RegExp(
|
|
21944
|
+
`export\\s+${TYPE_OR_INTERFACE2}\\s+(${resolvedName}Props)\\b`
|
|
21945
|
+
);
|
|
21933
21946
|
let propsInterfaceMatch = content.match(exactRegex);
|
|
21934
21947
|
if (!propsInterfaceMatch) {
|
|
21935
21948
|
const prefixRegex = new RegExp(
|
|
@@ -22195,7 +22208,9 @@ async function startServer() {
|
|
|
22195
22208
|
server.tool(
|
|
22196
22209
|
"list_chat_kit_components",
|
|
22197
22210
|
"List all Chat Kit components. Optionally filter by name, category, or description.",
|
|
22198
|
-
{
|
|
22211
|
+
{
|
|
22212
|
+
filter: external_exports.string().optional().describe("Filter by name/category/description")
|
|
22213
|
+
},
|
|
22199
22214
|
async ({ filter }) => {
|
|
22200
22215
|
try {
|
|
22201
22216
|
const components = listChatKitComponents(filter);
|
|
@@ -22210,7 +22225,10 @@ async function startServer() {
|
|
|
22210
22225
|
},
|
|
22211
22226
|
{}
|
|
22212
22227
|
);
|
|
22213
|
-
const sections = [
|
|
22228
|
+
const sections = [
|
|
22229
|
+
`Found ${components.length} chat-kit component(s):`,
|
|
22230
|
+
""
|
|
22231
|
+
];
|
|
22214
22232
|
Object.entries(grouped).forEach(([category, comps]) => {
|
|
22215
22233
|
sections.push(`## ${category}`, "");
|
|
22216
22234
|
comps.forEach((comp) => {
|
|
@@ -22227,11 +22245,14 @@ async function startServer() {
|
|
|
22227
22245
|
server.tool(
|
|
22228
22246
|
"get_chat_kit_docs",
|
|
22229
22247
|
"Get full documentation for a Chat Kit component including props, examples, and usage.",
|
|
22230
|
-
{
|
|
22248
|
+
{
|
|
22249
|
+
componentName: external_exports.string().describe('Component name (e.g., "CkChatBubble" or "ChatBubble")')
|
|
22250
|
+
},
|
|
22231
22251
|
async ({ componentName }) => {
|
|
22232
22252
|
try {
|
|
22233
22253
|
const docs = getChatKitComponentDocs(componentName);
|
|
22234
|
-
if (!docs)
|
|
22254
|
+
if (!docs)
|
|
22255
|
+
return error2(`Chat Kit component "${componentName}" not found.`);
|
|
22235
22256
|
return text(formatComponentDocs(docs));
|
|
22236
22257
|
} catch (e) {
|
|
22237
22258
|
return handleError(e);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aleph-alpha/lib-mcp",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/server.js",
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
"@aleph-alpha/tsconfig-frontend": "0.6.0"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
|
-
"@aleph-alpha/
|
|
40
|
-
"@aleph-alpha/
|
|
39
|
+
"@aleph-alpha/ui-library": "2.2.0",
|
|
40
|
+
"@aleph-alpha/chat-kit": "1.1.0"
|
|
41
41
|
},
|
|
42
42
|
"homepage": "https://docs.aleph-alpha.com",
|
|
43
43
|
"scripts": {
|