@svgrid/mcp 2.3.0 → 2.3.1
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/dist/data.js +80 -53
- package/dist/index.js +0 -0
- package/dist/project-tools.js +260 -1
- package/package.json +70 -67
- package/server.json +25 -0
package/dist/index.js
CHANGED
|
File without changes
|
package/dist/project-tools.js
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* The server holds one in-memory "current project" per session; `studio_get_config`
|
|
13
13
|
* / `studio_generate_app` are the outputs.
|
|
14
14
|
*/
|
|
15
|
-
import { createProject, parseProject, serializeProject, validateProject, addEntity, addScreen, addFreestandingScreen, addBlock, addComponentBlock, setEntityDataSource, setTheme, setAuth, setDataLayer, setDeployTarget, introspectDrizzle, introspectJson, flattenBlocks, blockPalette, UI_COMPONENT_REGISTRY, uiComponentSpec, studioThemes, emitStudioAppBundle, checkLicenseKey, entityDataSource, } from '@svgrid/enterprise/studio';
|
|
15
|
+
import { createProject, parseProject, serializeProject, validateProject, addEntity, addScreen, addFreestandingScreen, addBlock, addComponentBlock, updateBlock, removeBlock, moveBlock, updateScreen, removeScreen, setScreenLayout, setEntityDataSource, setJob, setTenancy, setTheme, setAuth, setDataLayer, setDeployTarget, introspectDrizzle, introspectJson, flattenBlocks, blockPalette, UI_COMPONENT_REGISTRY, uiComponentSpec, studioThemes, emitStudioAppBundle, checkLicenseKey, entityDataSource, } from '@svgrid/enterprise/studio';
|
|
16
16
|
// ---- session state --------------------------------------------------------
|
|
17
17
|
let project = null;
|
|
18
18
|
function requireProject() {
|
|
@@ -158,6 +158,71 @@ export const projectTools = [
|
|
|
158
158
|
required: ['screenId', 'component'],
|
|
159
159
|
},
|
|
160
160
|
},
|
|
161
|
+
{
|
|
162
|
+
name: 'studio_update_block',
|
|
163
|
+
description: 'Configure an EXISTING block: its config (columns, editing mode, export buttons, grouping, chart dimension/measure, rowLink, formatRules, ...), its width (span/colSpan), height, or CSS class. `config` is merged into the block\'s current config. Get block ids from studio_describe_project. This is how you configure a block after studio_add_block, which only adds a default one.',
|
|
164
|
+
inputSchema: {
|
|
165
|
+
type: 'object',
|
|
166
|
+
properties: {
|
|
167
|
+
screenId: { type: 'string' },
|
|
168
|
+
blockId: { type: 'string' },
|
|
169
|
+
config: { type: 'object', description: 'Partial BlockConfig, merged in. Grid example: { "editing": "inline", "export": { "xlsx": true }, "grouping": ["region"] }.' },
|
|
170
|
+
span: { type: 'number', enum: [1, 2, 3], description: 'Legacy 3-col width.' },
|
|
171
|
+
colSpan: { type: 'number', description: 'Width on the 12-column grid (1-12).' },
|
|
172
|
+
height: { type: 'number', description: 'Block height in px.' },
|
|
173
|
+
className: { type: 'string' },
|
|
174
|
+
},
|
|
175
|
+
required: ['screenId', 'blockId'],
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
name: 'studio_remove_block',
|
|
180
|
+
description: 'Remove a block from a screen. Get ids from studio_describe_project.',
|
|
181
|
+
inputSchema: {
|
|
182
|
+
type: 'object',
|
|
183
|
+
properties: { screenId: { type: 'string' }, blockId: { type: 'string' } },
|
|
184
|
+
required: ['screenId', 'blockId'],
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
name: 'studio_move_block',
|
|
189
|
+
description: 'Reorder a block within its screen: `dir` -1 moves it earlier, 1 later.',
|
|
190
|
+
inputSchema: {
|
|
191
|
+
type: 'object',
|
|
192
|
+
properties: { screenId: { type: 'string' }, blockId: { type: 'string' }, dir: { type: 'number', enum: [-1, 1] } },
|
|
193
|
+
required: ['screenId', 'blockId', 'dir'],
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
name: 'studio_update_screen',
|
|
198
|
+
description: 'Update a screen: title, route, nav entry, CSS class, or `renderMode`. Set renderMode "ssr" to emit idiomatic SvelteKit (a +page.server.ts `load` + form `actions`, progressive enhancement) instead of the default client-fetch SPA page; it applies to memory/sql-backed screens whose blocks are a single grid or read-only blocks, and falls back to "spa" otherwise.',
|
|
199
|
+
inputSchema: {
|
|
200
|
+
type: 'object',
|
|
201
|
+
properties: {
|
|
202
|
+
screenId: { type: 'string' },
|
|
203
|
+
title: { type: 'string' },
|
|
204
|
+
route: { type: 'string' },
|
|
205
|
+
className: { type: 'string' },
|
|
206
|
+
renderMode: { type: 'string', enum: ['spa', 'ssr'], description: 'Output shape for this screen.' },
|
|
207
|
+
nav: { type: 'object', description: '{ show?: boolean, label?: string }.' },
|
|
208
|
+
},
|
|
209
|
+
required: ['screenId'],
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
name: 'studio_remove_screen',
|
|
214
|
+
description: 'Remove a screen (and its blocks) from the project.',
|
|
215
|
+
inputSchema: { type: 'object', properties: { screenId: { type: 'string' } }, required: ['screenId'] },
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
name: 'studio_set_screen_layout',
|
|
219
|
+
description: 'Set how a screen arranges its blocks: grid (12-column, default) | stack (single column) | split (locked resizable panes) | dock (draggable/tabbable workspace) | canvas (free-form cell placement).',
|
|
220
|
+
inputSchema: {
|
|
221
|
+
type: 'object',
|
|
222
|
+
properties: { screenId: { type: 'string' }, layout: { type: 'string', enum: ['grid', 'stack', 'split', 'dock', 'canvas'] } },
|
|
223
|
+
required: ['screenId', 'layout'],
|
|
224
|
+
},
|
|
225
|
+
},
|
|
161
226
|
{
|
|
162
227
|
name: 'studio_set_entity_source',
|
|
163
228
|
description: 'Bind an entity to a data source. `source` is an EntityDataSource, e.g. { "kind": "sql", "table": "customers", "dialect": "postgres" } | { "kind": "memory" } | { "kind": "pglite", "table": "..." } | { "kind": "supabase", ... } | { "kind": "rest", ... }.',
|
|
@@ -210,6 +275,38 @@ export const projectTools = [
|
|
|
210
275
|
description: 'Turn the typed Drizzle data layer (schema.ts + typed repos + drizzle-kit migrations) on or off. Applies to SQL-bound entities.',
|
|
211
276
|
inputSchema: { type: 'object', properties: { enabled: { type: 'boolean' } }, required: ['enabled'] },
|
|
212
277
|
},
|
|
278
|
+
{
|
|
279
|
+
name: 'studio_set_tenancy',
|
|
280
|
+
description: 'Turn multi-tenancy on/off: every row is scoped to the signed-in user\'s tenant, enforced SERVER-side in each API route (reads filtered, creates stamped, update/delete ownership-checked). Requires auth + the Drizzle data layer + a SQL entity; without them it degrades to off. `sharedEntities` stay global (reference/lookup tables every tenant reads).',
|
|
281
|
+
inputSchema: {
|
|
282
|
+
type: 'object',
|
|
283
|
+
properties: {
|
|
284
|
+
enabled: { type: 'boolean' },
|
|
285
|
+
field: { type: 'string', description: "Scoping column. Default 'tenantId'." },
|
|
286
|
+
sharedEntities: { type: 'array', items: { type: 'string' }, description: 'Entities to leave global.' },
|
|
287
|
+
},
|
|
288
|
+
required: ['enabled'],
|
|
289
|
+
},
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
name: 'studio_set_job',
|
|
293
|
+
description: 'Add, replace, or remove a scheduled background job. Emits a secret-guarded /api/cron route plus the schedule config for the deploy target (vercel.json crons on Vercel, a GitHub Actions schedule elsewhere). `kind`:"email" sends a summary of `entity` to `to` (needs auth email enabled); `kind`:"code" runs a body you supply. Omit `cron` to REMOVE the job.',
|
|
294
|
+
inputSchema: {
|
|
295
|
+
type: 'object',
|
|
296
|
+
properties: {
|
|
297
|
+
id: { type: 'string', description: 'Stable job id.' },
|
|
298
|
+
name: { type: 'string', description: 'Human label.' },
|
|
299
|
+
cron: { type: 'string', description: "5-field cron in UTC, e.g. '0 6 * * *'. Omit to remove the job." },
|
|
300
|
+
kind: { type: 'string', enum: ['email', 'code'] },
|
|
301
|
+
enabled: { type: 'boolean', description: 'Default true. A disabled job keeps its handler but is skipped by the scheduled run.' },
|
|
302
|
+
entity: { type: 'string', description: 'email: entity to summarize.' },
|
|
303
|
+
to: { type: 'string', description: 'email: recipient address.' },
|
|
304
|
+
subject: { type: 'string', description: 'email: subject line (defaults to the job name).' },
|
|
305
|
+
code: { type: 'string', description: 'code: the handler body (TypeScript).' },
|
|
306
|
+
},
|
|
307
|
+
required: ['id'],
|
|
308
|
+
},
|
|
309
|
+
},
|
|
213
310
|
{
|
|
214
311
|
name: 'studio_set_deploy_target',
|
|
215
312
|
description: 'Set the deploy target: auto | vercel | netlify | cloudflare | node. Picks the SvelteKit adapter + emits provider config + a CI/CD pipeline.',
|
|
@@ -310,6 +407,105 @@ export function handleProjectTool(name, args) {
|
|
|
310
407
|
project = addComponentBlock(p, screenId, component, merged);
|
|
311
408
|
return confirm(`Added component "${component}" to screen ${screenId}.`);
|
|
312
409
|
}
|
|
410
|
+
case 'studio_update_block': {
|
|
411
|
+
const p = requireProject();
|
|
412
|
+
const screenId = String(args.screenId ?? '');
|
|
413
|
+
const blockId = String(args.blockId ?? '');
|
|
414
|
+
const screen = p.screens.find((s) => s.id === screenId);
|
|
415
|
+
if (!screen)
|
|
416
|
+
return fail(`No screen id=${screenId}. Call studio_describe_project.`);
|
|
417
|
+
const block = flattenBlocks(screen.blocks).find((b) => b.id === blockId);
|
|
418
|
+
if (!block)
|
|
419
|
+
return fail(`No block id=${blockId} on screen ${screenId}.`);
|
|
420
|
+
const patch = {};
|
|
421
|
+
if (args.config && typeof args.config === 'object')
|
|
422
|
+
patch.config = args.config;
|
|
423
|
+
if (typeof args.span === 'number')
|
|
424
|
+
patch.span = args.span;
|
|
425
|
+
if (typeof args.colSpan === 'number')
|
|
426
|
+
patch.colSpan = args.colSpan;
|
|
427
|
+
if (typeof args.height === 'number')
|
|
428
|
+
patch.height = args.height;
|
|
429
|
+
if (typeof args.className === 'string')
|
|
430
|
+
patch.className = args.className;
|
|
431
|
+
if (Object.keys(patch).length === 0)
|
|
432
|
+
return fail('Nothing to update - pass config, span, colSpan, height, or className.');
|
|
433
|
+
project = updateBlock(p, screenId, blockId, patch);
|
|
434
|
+
return confirm(`Updated ${block.config.kind} block ${blockId} (${Object.keys(patch).join(', ')}).`);
|
|
435
|
+
}
|
|
436
|
+
case 'studio_remove_block': {
|
|
437
|
+
const p = requireProject();
|
|
438
|
+
const screenId = String(args.screenId ?? '');
|
|
439
|
+
const blockId = String(args.blockId ?? '');
|
|
440
|
+
const screen = p.screens.find((s) => s.id === screenId);
|
|
441
|
+
if (!screen)
|
|
442
|
+
return fail(`No screen id=${screenId}.`);
|
|
443
|
+
if (!flattenBlocks(screen.blocks).some((b) => b.id === blockId))
|
|
444
|
+
return fail(`No block id=${blockId} on screen ${screenId}.`);
|
|
445
|
+
project = removeBlock(p, screenId, blockId);
|
|
446
|
+
return confirm(`Removed block ${blockId} from screen ${screenId}.`);
|
|
447
|
+
}
|
|
448
|
+
case 'studio_move_block': {
|
|
449
|
+
const p = requireProject();
|
|
450
|
+
const screenId = String(args.screenId ?? '');
|
|
451
|
+
const blockId = String(args.blockId ?? '');
|
|
452
|
+
const dir = args.dir === -1 ? -1 : args.dir === 1 ? 1 : null;
|
|
453
|
+
if (dir === null)
|
|
454
|
+
return fail('dir must be -1 (earlier) or 1 (later).');
|
|
455
|
+
const screen = p.screens.find((s) => s.id === screenId);
|
|
456
|
+
if (!screen)
|
|
457
|
+
return fail(`No screen id=${screenId}.`);
|
|
458
|
+
if (!flattenBlocks(screen.blocks).some((b) => b.id === blockId))
|
|
459
|
+
return fail(`No block id=${blockId} on screen ${screenId}.`);
|
|
460
|
+
project = moveBlock(p, screenId, blockId, dir);
|
|
461
|
+
return confirm(`Moved block ${blockId} ${dir === -1 ? 'earlier' : 'later'}.`);
|
|
462
|
+
}
|
|
463
|
+
case 'studio_update_screen': {
|
|
464
|
+
const p = requireProject();
|
|
465
|
+
const screenId = String(args.screenId ?? '');
|
|
466
|
+
if (!p.screens.some((s) => s.id === screenId))
|
|
467
|
+
return fail(`No screen id=${screenId}.`);
|
|
468
|
+
const patch = {};
|
|
469
|
+
if (typeof args.title === 'string')
|
|
470
|
+
patch.title = args.title;
|
|
471
|
+
if (typeof args.route === 'string')
|
|
472
|
+
patch.route = args.route;
|
|
473
|
+
if (typeof args.className === 'string')
|
|
474
|
+
patch.className = args.className;
|
|
475
|
+
if (args.renderMode === 'ssr' || args.renderMode === 'spa')
|
|
476
|
+
patch.renderMode = args.renderMode;
|
|
477
|
+
if (args.nav && typeof args.nav === 'object')
|
|
478
|
+
patch.nav = args.nav;
|
|
479
|
+
if (Object.keys(patch).length === 0)
|
|
480
|
+
return fail('Nothing to update - pass title, route, className, renderMode, or nav.');
|
|
481
|
+
project = updateScreen(p, screenId, patch);
|
|
482
|
+
// renderMode is a request, not a guarantee: the emitter falls back to the
|
|
483
|
+
// SPA page when a screen's blocks or source don't fit the SSR shape.
|
|
484
|
+
const ssrNote = patch.renderMode === 'ssr'
|
|
485
|
+
? ' SSR applies to memory/sql screens whose blocks are a single grid or read-only blocks; other screens still emit the SPA page.'
|
|
486
|
+
: '';
|
|
487
|
+
return confirm(`Updated screen ${screenId} (${Object.keys(patch).join(', ')}).${ssrNote}`);
|
|
488
|
+
}
|
|
489
|
+
case 'studio_remove_screen': {
|
|
490
|
+
const p = requireProject();
|
|
491
|
+
const screenId = String(args.screenId ?? '');
|
|
492
|
+
if (!p.screens.some((s) => s.id === screenId))
|
|
493
|
+
return fail(`No screen id=${screenId}.`);
|
|
494
|
+
project = removeScreen(p, screenId);
|
|
495
|
+
return confirm(`Removed screen ${screenId}.`);
|
|
496
|
+
}
|
|
497
|
+
case 'studio_set_screen_layout': {
|
|
498
|
+
const p = requireProject();
|
|
499
|
+
const screenId = String(args.screenId ?? '');
|
|
500
|
+
const layout = String(args.layout ?? '');
|
|
501
|
+
const allowed = ['grid', 'stack', 'split', 'dock', 'canvas'];
|
|
502
|
+
if (!p.screens.some((s) => s.id === screenId))
|
|
503
|
+
return fail(`No screen id=${screenId}.`);
|
|
504
|
+
if (!allowed.includes(layout))
|
|
505
|
+
return fail(`layout must be one of: ${allowed.join(' | ')}.`);
|
|
506
|
+
project = setScreenLayout(p, screenId, layout);
|
|
507
|
+
return confirm(`Screen ${screenId} now uses the ${layout} layout.`);
|
|
508
|
+
}
|
|
313
509
|
case 'studio_set_entity_source': {
|
|
314
510
|
const p = requireProject();
|
|
315
511
|
const entity = String(args.entity ?? '');
|
|
@@ -360,6 +556,69 @@ export function handleProjectTool(name, args) {
|
|
|
360
556
|
project = setDataLayer(requireProject(), args.enabled !== false);
|
|
361
557
|
return confirm(project.dataLayer === 'drizzle' ? 'Drizzle data layer enabled.' : 'Data layer disabled.');
|
|
362
558
|
}
|
|
559
|
+
case 'studio_set_tenancy': {
|
|
560
|
+
const p = requireProject();
|
|
561
|
+
const enabled = args.enabled === true;
|
|
562
|
+
if (!enabled) {
|
|
563
|
+
project = setTenancy(p, null);
|
|
564
|
+
return confirm('Multi-tenancy off.');
|
|
565
|
+
}
|
|
566
|
+
const shared = Array.isArray(args.sharedEntities) ? args.sharedEntities.map(String) : undefined;
|
|
567
|
+
const unknown = (shared ?? []).filter((e) => !p.entities.some((x) => x.name === e));
|
|
568
|
+
if (unknown.length)
|
|
569
|
+
return fail(`Unknown entities in sharedEntities: ${unknown.join(', ')}.`);
|
|
570
|
+
project = setTenancy(p, {
|
|
571
|
+
enabled: true,
|
|
572
|
+
...(typeof args.field === 'string' && args.field ? { field: args.field } : {}),
|
|
573
|
+
...(shared?.length ? { sharedEntities: shared } : {}),
|
|
574
|
+
});
|
|
575
|
+
// Tenancy silently no-ops without its prerequisites, so say so here rather
|
|
576
|
+
// than letting the agent believe an unscoped app is scoped.
|
|
577
|
+
const missing = [
|
|
578
|
+
p.auth?.enabled === true ? null : 'auth (studio_set_auth)',
|
|
579
|
+
p.dataLayer === 'drizzle' ? null : 'the Drizzle data layer (studio_set_data_layer)',
|
|
580
|
+
p.entities.some((e) => entityDataSource(p, e.name).kind === 'sql') ? null : 'a SQL-bound entity (studio_set_entity_source)',
|
|
581
|
+
].filter(Boolean);
|
|
582
|
+
const note = missing.length
|
|
583
|
+
? ` NOT YET ENFORCED - still needs: ${missing.join(', ')}.`
|
|
584
|
+
: ' Enforced server-side on every SQL route.';
|
|
585
|
+
return confirm(`Multi-tenancy on (column "${typeof args.field === 'string' && args.field ? args.field : 'tenantId'}").${note}`);
|
|
586
|
+
}
|
|
587
|
+
case 'studio_set_job': {
|
|
588
|
+
const p = requireProject();
|
|
589
|
+
const id = String(args.id ?? '');
|
|
590
|
+
if (!id)
|
|
591
|
+
return fail('id is required.');
|
|
592
|
+
// No cron = remove. Keeps one tool for the whole lifecycle.
|
|
593
|
+
if (!args.cron) {
|
|
594
|
+
if (!(p.jobs ?? []).some((j) => j.id === id))
|
|
595
|
+
return fail(`No job "${id}" to remove.`);
|
|
596
|
+
project = setJob(p, id, null);
|
|
597
|
+
return confirm(`Removed job "${id}".`);
|
|
598
|
+
}
|
|
599
|
+
const kind = args.kind === 'email' ? 'email' : 'code';
|
|
600
|
+
if (kind === 'email') {
|
|
601
|
+
if (!args.to)
|
|
602
|
+
return fail('An email job needs `to`.');
|
|
603
|
+
if (!args.entity || !p.entities.some((e) => e.name === args.entity)) {
|
|
604
|
+
return fail(`An email job needs a known \`entity\`${args.entity ? ` (no entity "${String(args.entity)}")` : ''}.`);
|
|
605
|
+
}
|
|
606
|
+
if (p.auth?.email !== true) {
|
|
607
|
+
return fail('An email job needs the email layer: call studio_set_auth with { enabled: true, email: true } first.');
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
project = setJob(p, id, {
|
|
611
|
+
name: String(args.name ?? id),
|
|
612
|
+
cron: String(args.cron),
|
|
613
|
+
kind,
|
|
614
|
+
...(args.enabled === false ? { enabled: false } : {}),
|
|
615
|
+
...(typeof args.entity === 'string' ? { entity: args.entity } : {}),
|
|
616
|
+
...(typeof args.to === 'string' ? { to: args.to } : {}),
|
|
617
|
+
...(typeof args.subject === 'string' ? { subject: args.subject } : {}),
|
|
618
|
+
...(typeof args.code === 'string' ? { code: args.code } : {}),
|
|
619
|
+
});
|
|
620
|
+
return confirm(`Job "${id}" scheduled at ${String(args.cron)} (${kind}).`);
|
|
621
|
+
}
|
|
363
622
|
case 'studio_set_deploy_target': {
|
|
364
623
|
const t = String(args.target ?? 'auto');
|
|
365
624
|
project = setDeployTarget(requireProject(), t);
|
package/package.json
CHANGED
|
@@ -1,67 +1,70 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@svgrid/mcp",
|
|
3
|
-
"
|
|
4
|
-
|
|
5
|
-
"
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
"
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
"
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
|
|
67
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@svgrid/mcp",
|
|
3
|
+
"mcpName": "com.svgrid/svgrid",
|
|
4
|
+
"funding": {
|
|
5
|
+
"type": "commercial",
|
|
6
|
+
"url": "https://svgrid.com/pricing"
|
|
7
|
+
},
|
|
8
|
+
"version": "2.3.1",
|
|
9
|
+
"description": "Model Context Protocol (MCP) server for SvGrid. Exposes example sources, docs, and API reference to AI assistants.",
|
|
10
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
11
|
+
"author": "jQWidgets <sales@jqwidgets.com>",
|
|
12
|
+
"homepage": "https://svgrid.com/docs/help/mcp-server/",
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://github.com/sv-grid/sv-grid.git",
|
|
16
|
+
"directory": "packages/mcp"
|
|
17
|
+
},
|
|
18
|
+
"type": "module",
|
|
19
|
+
"main": "dist/index.js",
|
|
20
|
+
"bin": {
|
|
21
|
+
"svgrid-mcp": "dist/index.js"
|
|
22
|
+
},
|
|
23
|
+
"files": [
|
|
24
|
+
"dist",
|
|
25
|
+
"README.md",
|
|
26
|
+
"LICENSE",
|
|
27
|
+
"server.json"
|
|
28
|
+
],
|
|
29
|
+
"publishConfig": {
|
|
30
|
+
"access": "public"
|
|
31
|
+
},
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build:manifests": "node ./scripts/build-manifests.mjs",
|
|
34
|
+
"build:ts": "tsc -p tsconfig.json",
|
|
35
|
+
"build": "pnpm build:manifests && pnpm build:ts",
|
|
36
|
+
"prepublishOnly": "pnpm build",
|
|
37
|
+
"start": "node dist/index.js",
|
|
38
|
+
"test:types": "tsc -p tsconfig.json --noEmit"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@modelcontextprotocol/sdk": "^1.0.4",
|
|
42
|
+
"@svgrid/enterprise": "workspace:^",
|
|
43
|
+
"zod": "^3.23.8"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@types/node": "^22.10.7",
|
|
47
|
+
"typescript": "6.0.3"
|
|
48
|
+
},
|
|
49
|
+
"engines": {
|
|
50
|
+
"node": ">=18"
|
|
51
|
+
},
|
|
52
|
+
"keywords": [
|
|
53
|
+
"mcp",
|
|
54
|
+
"model context protocol",
|
|
55
|
+
"model-context-protocol",
|
|
56
|
+
"ai",
|
|
57
|
+
"llm",
|
|
58
|
+
"claude",
|
|
59
|
+
"cursor",
|
|
60
|
+
"zed",
|
|
61
|
+
"svelte",
|
|
62
|
+
"svelte5",
|
|
63
|
+
"data grid",
|
|
64
|
+
"datagrid",
|
|
65
|
+
"svgrid",
|
|
66
|
+
"sv-grid",
|
|
67
|
+
"codegen",
|
|
68
|
+
"agent"
|
|
69
|
+
]
|
|
70
|
+
}
|
package/server.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
|
3
|
+
"name": "com.svgrid/svgrid",
|
|
4
|
+
"title": "SvGrid",
|
|
5
|
+
"description": "Version-pinned Svelte 5 data grid APIs, 373 demo sources, and SvelteKit app scaffolding.",
|
|
6
|
+
"version": "2.3.1",
|
|
7
|
+
"websiteUrl": "https://svgrid.com/docs/help/mcp-server/",
|
|
8
|
+
"repository": {
|
|
9
|
+
"url": "https://github.com/sv-grid/sv-grid",
|
|
10
|
+
"source": "github",
|
|
11
|
+
"subfolder": "packages/mcp"
|
|
12
|
+
},
|
|
13
|
+
"packages": [
|
|
14
|
+
{
|
|
15
|
+
"registryType": "npm",
|
|
16
|
+
"registryBaseUrl": "https://registry.npmjs.org",
|
|
17
|
+
"identifier": "@svgrid/mcp",
|
|
18
|
+
"version": "2.3.1",
|
|
19
|
+
"runtimeHint": "npx",
|
|
20
|
+
"transport": {
|
|
21
|
+
"type": "stdio"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|