@lerpa/mcp-server 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 +94 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +259 -0
- package/package.json +63 -0
- package/registry/component-catalog.json +8275 -0
- package/registry/registry.json +19852 -0
package/README.md
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# @lerpa/mcp-server
|
|
2
|
+
|
|
3
|
+
Model Context Protocol (MCP) server that exposes the Lerpa UI registry to AI coding agents (Claude Code, Cursor, v0, Continue, Cline, Zed).
|
|
4
|
+
|
|
5
|
+
## Status
|
|
6
|
+
|
|
7
|
+
**Active** — `@modelcontextprotocol/sdk` is installed and `pnpm --filter @lerpa/mcp-server build` emits `dist/index.js`. Rebuild after editing `src/`:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pnpm --filter @lerpa/mcp-server build
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## What it exposes
|
|
14
|
+
|
|
15
|
+
Three read-only tools backed by `packages/registry/generated/manifest.json` and `apps/docs/src/data/component-catalog.json`:
|
|
16
|
+
|
|
17
|
+
| Tool | Description |
|
|
18
|
+
| --- | --- |
|
|
19
|
+
| `list_components(category?)` | Returns components filtered by category (`ai`, `buttons`, `cards`, `forms`, `creative`, `feedback`, `navigation`, `tables`, `calendars`, `ecommerce`, `dashboard`, `auth`, `account`, `docs`, `blog`). |
|
|
20
|
+
| `get_component(id)` | Returns the full registry item JSON for a single component, including embedded `files[].content` source code (copy-pasteable). |
|
|
21
|
+
| `search_components(query)` | Fuzzy search by name + description across all registry items. |
|
|
22
|
+
|
|
23
|
+
## Configure in Claude Code
|
|
24
|
+
|
|
25
|
+
Build first, then register the server. Easiest is the CLI:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pnpm --filter @lerpa/mcp-server build
|
|
29
|
+
claude mcp add lerpa --scope user -- node /absolute/path/to/packages/mcp-server/dist/index.js
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Or add a project-scoped `.mcp.json` at your repo root:
|
|
33
|
+
|
|
34
|
+
```json
|
|
35
|
+
{
|
|
36
|
+
"mcpServers": {
|
|
37
|
+
"lerpa": {
|
|
38
|
+
"command": "node",
|
|
39
|
+
"args": ["/absolute/path/to/packages/mcp-server/dist/index.js"]
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Restart Claude Code; the three tools above become callable.
|
|
46
|
+
|
|
47
|
+
## Configure in Cursor
|
|
48
|
+
|
|
49
|
+
`~/.cursor/mcp.json` — point at the built `dist/index.js` (works today, from inside this monorepo):
|
|
50
|
+
|
|
51
|
+
```json
|
|
52
|
+
{
|
|
53
|
+
"mcpServers": {
|
|
54
|
+
"lerpa": {
|
|
55
|
+
"command": "node",
|
|
56
|
+
"args": ["/absolute/path/to/packages/mcp-server/dist/index.js"]
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
> The registry data is bundled into the package, so `npx -y @lerpa/mcp-server` works as soon as it is published to npm. Until the first `npm publish`, use the `node …/dist/index.js` form above.
|
|
63
|
+
|
|
64
|
+
## Configure in Continue / Cline / Zed
|
|
65
|
+
|
|
66
|
+
Same shape — point `command`/`args` to `node /absolute/path/to/packages/mcp-server/dist/index.js` for local use (or the published `lerpa-mcp` binary once available).
|
|
67
|
+
|
|
68
|
+
## Publishing
|
|
69
|
+
|
|
70
|
+
The package is self-contained. `pnpm --filter @lerpa/mcp-server build` runs `tsc` then `scripts/copy-registry.cjs`, which bundles `registry/registry.json` (the aggregated registry with embedded source) and `registry/component-catalog.json` into the package. At runtime `src/index.ts` reads those bundled files, falling back to monorepo paths during local dev. `files` ships `dist` + `registry`; `prepublishOnly` rebuilds the registry first; `publishConfig.access` is `public`.
|
|
71
|
+
|
|
72
|
+
To publish (verified self-contained outside the monorepo — `npm pack` tarball ≈ 1.3 MB):
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
cd packages/mcp-server
|
|
76
|
+
npm publish # prepublishOnly rebuilds the registry + bundles, then publishes
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
After the first publish, any MCP client can use `npx -y @lerpa/mcp-server`.
|
|
80
|
+
|
|
81
|
+
## Data sources
|
|
82
|
+
|
|
83
|
+
Resolved bundled-first, with monorepo fallback for local development:
|
|
84
|
+
|
|
85
|
+
- Aggregated registry (names, types, embedded source): `registry/registry.json` ← `../registry/generated/registry.json`
|
|
86
|
+
- Component descriptions / categories: `registry/component-catalog.json` ← `../../apps/docs/src/data/component-catalog.json`
|
|
87
|
+
|
|
88
|
+
## Development
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
pnpm --filter @lerpa/mcp-server typecheck
|
|
92
|
+
pnpm --filter @lerpa/mcp-server build
|
|
93
|
+
node packages/mcp-server/dist/index.js # stdio MCP server
|
|
94
|
+
```
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @lerpa/mcp-server
|
|
4
|
+
*
|
|
5
|
+
* Model Context Protocol server exposing the Lerpa UI registry to AI coding
|
|
6
|
+
* agents (Claude Code, Cursor, v0, Continue, Cline, Zed).
|
|
7
|
+
*
|
|
8
|
+
* Status: ACTIVE. `@modelcontextprotocol/sdk` is installed; `pnpm --filter
|
|
9
|
+
* @lerpa/mcp-server build` emits `dist/index.js`, runnable as a stdio MCP
|
|
10
|
+
* server by any MCP client (Claude Code, Cursor, Continue, Cline, Zed).
|
|
11
|
+
*
|
|
12
|
+
* Tools exposed (read-only):
|
|
13
|
+
* - list_components(category?) -> components filtered by category
|
|
14
|
+
* - get_component(id) -> full registry item JSON with source
|
|
15
|
+
* - search_components(query) -> fuzzy match on name + description
|
|
16
|
+
*
|
|
17
|
+
* Note: data is read from the monorepo registry (see paths below), so this
|
|
18
|
+
* runs as-is from inside the repo. Publishing to npm for `npx` use additionally
|
|
19
|
+
* requires bundling the registry JSON into the package — see README.
|
|
20
|
+
*/
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;GAkBG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @lerpa/mcp-server
|
|
4
|
+
*
|
|
5
|
+
* Model Context Protocol server exposing the Lerpa UI registry to AI coding
|
|
6
|
+
* agents (Claude Code, Cursor, v0, Continue, Cline, Zed).
|
|
7
|
+
*
|
|
8
|
+
* Status: ACTIVE. `@modelcontextprotocol/sdk` is installed; `pnpm --filter
|
|
9
|
+
* @lerpa/mcp-server build` emits `dist/index.js`, runnable as a stdio MCP
|
|
10
|
+
* server by any MCP client (Claude Code, Cursor, Continue, Cline, Zed).
|
|
11
|
+
*
|
|
12
|
+
* Tools exposed (read-only):
|
|
13
|
+
* - list_components(category?) -> components filtered by category
|
|
14
|
+
* - get_component(id) -> full registry item JSON with source
|
|
15
|
+
* - search_components(query) -> fuzzy match on name + description
|
|
16
|
+
*
|
|
17
|
+
* Note: data is read from the monorepo registry (see paths below), so this
|
|
18
|
+
* runs as-is from inside the repo. Publishing to npm for `npx` use additionally
|
|
19
|
+
* requires bundling the registry JSON into the package — see README.
|
|
20
|
+
*/
|
|
21
|
+
import * as fs from "node:fs";
|
|
22
|
+
import * as path from "node:path";
|
|
23
|
+
import { fileURLToPath } from "node:url";
|
|
24
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
25
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
26
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
// Resolve data sources relative to this file (ESM-safe).
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
31
|
+
const __dirname = path.dirname(__filename);
|
|
32
|
+
// Data resolution: prefer the registry JSON bundled INTO this package by
|
|
33
|
+
// scripts/copy-registry.js (so the published package runs via `npx` outside the
|
|
34
|
+
// monorepo). Fall back to monorepo source paths for local development.
|
|
35
|
+
// dist/index.js -> packages/mcp-server
|
|
36
|
+
const PKG_ROOT = path.resolve(__dirname, "..");
|
|
37
|
+
// dist/index.js -> packages/mcp-server -> packages -> repo root
|
|
38
|
+
const REPO_ROOT = path.resolve(__dirname, "..", "..", "..");
|
|
39
|
+
function firstExisting(...candidates) {
|
|
40
|
+
for (const c of candidates) {
|
|
41
|
+
if (fs.existsSync(c))
|
|
42
|
+
return c;
|
|
43
|
+
}
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
// The aggregated registry array (every item with embedded source) is the single
|
|
47
|
+
// source of truth for list/get/search. component-catalog.json adds human
|
|
48
|
+
// descriptions + category tags.
|
|
49
|
+
const REGISTRY_JSON = firstExisting(path.join(PKG_ROOT, "registry", "registry.json"), path.join(REPO_ROOT, "packages", "registry", "generated", "registry.json"));
|
|
50
|
+
const CATALOG_JSON = firstExisting(path.join(PKG_ROOT, "registry", "component-catalog.json"), path.join(REPO_ROOT, "apps", "docs", "src", "data", "component-catalog.json"));
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
// Lazy-loaded data (only read once per process).
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
let _items = null;
|
|
55
|
+
let _catalog = null;
|
|
56
|
+
function readJson(filePath) {
|
|
57
|
+
return JSON.parse(fs.readFileSync(filePath, "utf-8"));
|
|
58
|
+
}
|
|
59
|
+
function loadItems() {
|
|
60
|
+
if (!_items) {
|
|
61
|
+
if (!REGISTRY_JSON) {
|
|
62
|
+
throw new Error("Lerpa UI registry data not found. From a monorepo checkout run " +
|
|
63
|
+
"`pnpm --filter @lerpa/registry run build`; a published package " +
|
|
64
|
+
"ships registry/registry.json (see scripts/copy-registry.js).");
|
|
65
|
+
}
|
|
66
|
+
_items = readJson(REGISTRY_JSON);
|
|
67
|
+
}
|
|
68
|
+
return _items;
|
|
69
|
+
}
|
|
70
|
+
function loadCatalog() {
|
|
71
|
+
if (!_catalog) {
|
|
72
|
+
try {
|
|
73
|
+
if (!CATALOG_JSON) {
|
|
74
|
+
_catalog = [];
|
|
75
|
+
return _catalog;
|
|
76
|
+
}
|
|
77
|
+
// component-catalog.json is { categories: [...], components: [...] };
|
|
78
|
+
// tolerate a bare array too.
|
|
79
|
+
const raw = readJson(CATALOG_JSON);
|
|
80
|
+
const arr = Array.isArray(raw)
|
|
81
|
+
? raw
|
|
82
|
+
: (raw.components ?? []);
|
|
83
|
+
_catalog = arr;
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
_catalog = [];
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return _catalog;
|
|
90
|
+
}
|
|
91
|
+
function findItem(id) {
|
|
92
|
+
const item = loadItems().find((it) => it.name === id);
|
|
93
|
+
if (!item) {
|
|
94
|
+
throw new Error(`Component not found: ${id}`);
|
|
95
|
+
}
|
|
96
|
+
return item;
|
|
97
|
+
}
|
|
98
|
+
// ---------------------------------------------------------------------------
|
|
99
|
+
// Tool implementations.
|
|
100
|
+
// ---------------------------------------------------------------------------
|
|
101
|
+
function tool_list_components(category) {
|
|
102
|
+
const catalog = loadCatalog();
|
|
103
|
+
// Build a quick lookup from id -> catalog entry for category info.
|
|
104
|
+
const catById = new Map(catalog.map((c) => [c.id ?? c.name, c]));
|
|
105
|
+
let items = loadItems();
|
|
106
|
+
if (category) {
|
|
107
|
+
const cat = category.toLowerCase();
|
|
108
|
+
items = items.filter((it) => {
|
|
109
|
+
const entry = catById.get(it.name);
|
|
110
|
+
if (entry?.category?.toLowerCase() === cat)
|
|
111
|
+
return true;
|
|
112
|
+
// Fallback: name-prefix heuristic (e.g. "ai-chat-stream" -> "ai")
|
|
113
|
+
return it.name.toLowerCase().startsWith(`${cat}-`);
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
total: items.length,
|
|
118
|
+
category: category ?? "all",
|
|
119
|
+
items: items.map((it) => ({
|
|
120
|
+
id: it.name,
|
|
121
|
+
type: it.type,
|
|
122
|
+
install: `pnpm dlx lerpa-cli add ${it.name}`,
|
|
123
|
+
registryUrl: `https://lerpaui.com/r/${it.name}`,
|
|
124
|
+
})),
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
function tool_get_component(id) {
|
|
128
|
+
const item = findItem(id);
|
|
129
|
+
return {
|
|
130
|
+
id: item.name,
|
|
131
|
+
type: item.type,
|
|
132
|
+
dependencies: item.dependencies ?? [],
|
|
133
|
+
registryDependencies: item.registryDependencies ?? [],
|
|
134
|
+
install: `pnpm dlx lerpa-cli add ${item.name}`,
|
|
135
|
+
files: item.files.map((f) => ({
|
|
136
|
+
path: f.path,
|
|
137
|
+
type: f.type,
|
|
138
|
+
source: f.content,
|
|
139
|
+
})),
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
function tool_search_components(query) {
|
|
143
|
+
const q = query.trim().toLowerCase();
|
|
144
|
+
if (!q)
|
|
145
|
+
return { total: 0, results: [] };
|
|
146
|
+
const catalog = loadCatalog();
|
|
147
|
+
const catById = new Map(catalog.map((c) => [c.id ?? c.name, c]));
|
|
148
|
+
const scored = [];
|
|
149
|
+
for (const it of loadItems()) {
|
|
150
|
+
const name = it.name.toLowerCase();
|
|
151
|
+
const entry = catById.get(it.name);
|
|
152
|
+
const desc = entry?.description?.toLowerCase() ?? "";
|
|
153
|
+
let score = 0;
|
|
154
|
+
if (name === q)
|
|
155
|
+
score += 100;
|
|
156
|
+
if (name.includes(q))
|
|
157
|
+
score += 50;
|
|
158
|
+
if (name.startsWith(q))
|
|
159
|
+
score += 25;
|
|
160
|
+
for (const token of q.split(/[\s-]+/).filter(Boolean)) {
|
|
161
|
+
if (name.includes(token))
|
|
162
|
+
score += 5;
|
|
163
|
+
if (desc.includes(token))
|
|
164
|
+
score += 3;
|
|
165
|
+
}
|
|
166
|
+
if (score > 0) {
|
|
167
|
+
scored.push({ id: it.name, type: it.type, score, description: entry?.description });
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
scored.sort((a, b) => b.score - a.score);
|
|
171
|
+
return {
|
|
172
|
+
total: scored.length,
|
|
173
|
+
query,
|
|
174
|
+
results: scored.slice(0, 50).map(({ score: _score, ...rest }) => rest),
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
// ---------------------------------------------------------------------------
|
|
178
|
+
// MCP server wiring.
|
|
179
|
+
// ---------------------------------------------------------------------------
|
|
180
|
+
const TOOLS = [
|
|
181
|
+
{
|
|
182
|
+
name: "list_components",
|
|
183
|
+
description: "List Lerpa UI components from the registry, optionally filtered by category " +
|
|
184
|
+
"(ai, buttons, cards, forms, creative, feedback, navigation, tables, calendars, " +
|
|
185
|
+
"ecommerce, dashboard, auth, account, docs, blog).",
|
|
186
|
+
inputSchema: {
|
|
187
|
+
type: "object",
|
|
188
|
+
properties: {
|
|
189
|
+
category: {
|
|
190
|
+
type: "string",
|
|
191
|
+
description: "Optional category slug to filter results.",
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
name: "get_component",
|
|
198
|
+
description: "Get the full registry item JSON for a single component, including embedded " +
|
|
199
|
+
"source code from `packages/registry/items/<id>.json`.",
|
|
200
|
+
inputSchema: {
|
|
201
|
+
type: "object",
|
|
202
|
+
required: ["id"],
|
|
203
|
+
properties: {
|
|
204
|
+
id: { type: "string", description: "Component id (registry name)." },
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
name: "search_components",
|
|
210
|
+
description: "Fuzzy search across all Lerpa UI registry items by name and description. Returns up to 50 matches.",
|
|
211
|
+
inputSchema: {
|
|
212
|
+
type: "object",
|
|
213
|
+
required: ["query"],
|
|
214
|
+
properties: {
|
|
215
|
+
query: { type: "string", description: "Free-text query." },
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
];
|
|
220
|
+
async function main() {
|
|
221
|
+
const server = new Server({ name: "@lerpa/mcp-server", version: "0.1.0" }, { capabilities: { tools: {} } });
|
|
222
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }));
|
|
223
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
224
|
+
const { name, arguments: args = {} } = request.params;
|
|
225
|
+
try {
|
|
226
|
+
let result;
|
|
227
|
+
switch (name) {
|
|
228
|
+
case "list_components":
|
|
229
|
+
result = tool_list_components(args.category);
|
|
230
|
+
break;
|
|
231
|
+
case "get_component":
|
|
232
|
+
result = tool_get_component(args.id);
|
|
233
|
+
break;
|
|
234
|
+
case "search_components":
|
|
235
|
+
result = tool_search_components(args.query);
|
|
236
|
+
break;
|
|
237
|
+
default:
|
|
238
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
239
|
+
}
|
|
240
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
241
|
+
}
|
|
242
|
+
catch (err) {
|
|
243
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
244
|
+
return {
|
|
245
|
+
isError: true,
|
|
246
|
+
content: [{ type: "text", text: `Error in ${name}: ${message}` }],
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
const transport = new StdioServerTransport();
|
|
251
|
+
await server.connect(transport);
|
|
252
|
+
// eslint-disable-next-line no-console
|
|
253
|
+
console.error("[lerpa-mcp] stdio server ready");
|
|
254
|
+
}
|
|
255
|
+
main().catch((err) => {
|
|
256
|
+
// eslint-disable-next-line no-console
|
|
257
|
+
console.error("[lerpa-mcp] fatal:", err);
|
|
258
|
+
process.exit(1);
|
|
259
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lerpa/mcp-server",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"description": "Model Context Protocol server exposing the Lerpa UI registry to AI agents (Claude Code, Cursor, v0, Continue).",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/cuibit-labs/lerpaui.git",
|
|
9
|
+
"directory": "packages/mcp-server"
|
|
10
|
+
},
|
|
11
|
+
"author": "Lerpa UI",
|
|
12
|
+
"homepage": "https://github.com/cuibit-labs/lerpaui#readme",
|
|
13
|
+
"bugs": "https://github.com/cuibit-labs/lerpaui/issues",
|
|
14
|
+
"publishConfig": {
|
|
15
|
+
"access": "public"
|
|
16
|
+
},
|
|
17
|
+
"type": "module",
|
|
18
|
+
"main": "./dist/index.js",
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"bin": {
|
|
21
|
+
"lerpa-mcp": "./dist/index.js"
|
|
22
|
+
},
|
|
23
|
+
"exports": {
|
|
24
|
+
".": {
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
26
|
+
"import": "./dist/index.js"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"dist",
|
|
31
|
+
"registry",
|
|
32
|
+
"README.md"
|
|
33
|
+
],
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "tsc && node ./scripts/copy-registry.cjs",
|
|
36
|
+
"dev": "tsc -w",
|
|
37
|
+
"lint": "eslint src --ext .ts",
|
|
38
|
+
"typecheck": "tsc --noEmit",
|
|
39
|
+
"start": "node ./dist/index.js",
|
|
40
|
+
"prepublishOnly": "pnpm --filter @lerpa/registry run build && pnpm run build"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@types/node": "^20.11.24",
|
|
44
|
+
"typescript": "^5.4.5"
|
|
45
|
+
},
|
|
46
|
+
"engines": {
|
|
47
|
+
"node": ">=20"
|
|
48
|
+
},
|
|
49
|
+
"keywords": [
|
|
50
|
+
"mcp",
|
|
51
|
+
"model-context-protocol",
|
|
52
|
+
"lerpa",
|
|
53
|
+
"shadcn",
|
|
54
|
+
"registry",
|
|
55
|
+
"ai",
|
|
56
|
+
"claude",
|
|
57
|
+
"cursor",
|
|
58
|
+
"v0"
|
|
59
|
+
],
|
|
60
|
+
"dependencies": {
|
|
61
|
+
"@modelcontextprotocol/sdk": "^1.29.0"
|
|
62
|
+
}
|
|
63
|
+
}
|