@svgrid/mcp 2.0.0 → 2.0.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.
Files changed (3) hide show
  1. package/dist/data.js +2174 -336
  2. package/dist/index.js +95 -0
  3. package/package.json +44 -41
package/dist/index.js CHANGED
@@ -15,6 +15,22 @@ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
15
15
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
16
16
  import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
17
17
  import { apiReference, docs, examples } from './data.js';
18
+ import { checkLicenseKey, introspectDrizzle, introspectJson, scaffold, summarizeVerify, verifyScaffold, } from '@svgrid/enterprise/studio';
19
+ /**
20
+ * Soft commercial gate. Uses the SAME classifier as the browser
21
+ * (checkLicenseKey), reading the key from the SVGRID_LICENSE_KEY env var. Never
22
+ * blocks - unlicensed generation still runs, it just prepends a nudge (and the
23
+ * generated app itself watermarks until a key is set).
24
+ */
25
+ function studioNote() {
26
+ return checkLicenseKey(process.env.SVGRID_LICENSE_KEY ?? null).valid
27
+ ? ''
28
+ : '// SvGrid Studio is a commercial feature. Set SVGRID_LICENSE_KEY (in your MCP\n' +
29
+ '// server config env) for licensed use. https://svgrid.com/pricing\n\n';
30
+ }
31
+ function errText(message) {
32
+ return { isError: true, content: [{ type: 'text', text: message }] };
33
+ }
18
34
  const server = new Server({
19
35
  name: '@svgrid/mcp',
20
36
  version: '0.1.0',
@@ -71,6 +87,43 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
71
87
  description: 'Return the curated SvGrid public-API surface, grouped by category (components, headless, row models, features, virtualization, accessibility, utilities).',
72
88
  inputSchema: { type: 'object', properties: {} },
73
89
  },
90
+ {
91
+ name: 'introspect_source',
92
+ description: 'SvGrid Studio (commercial): infer an EntitySchema from a data source. Pass a Drizzle schema file (kind:"drizzle", source: the file text) or sample rows (kind:"json", rows, name). Returns a DRAFT EntitySchema to review/refine before scaffolding code.',
93
+ inputSchema: {
94
+ type: 'object',
95
+ properties: {
96
+ kind: { type: 'string', enum: ['drizzle', 'json'], description: 'Source kind.' },
97
+ source: {
98
+ type: 'string',
99
+ description: 'For kind:"drizzle": the text of a schema file containing a pgTable / sqliteTable / mysqlTable definition.',
100
+ },
101
+ rows: {
102
+ type: 'array',
103
+ description: 'For kind:"json": a non-empty array of sample row objects.',
104
+ items: { type: 'object' },
105
+ },
106
+ name: { type: 'string', description: 'Entity/table name (required for kind:"json").' },
107
+ },
108
+ required: ['kind'],
109
+ },
110
+ },
111
+ {
112
+ name: 'scaffold_entity',
113
+ description: 'SvGrid Studio (commercial): generate runnable SvelteKit files from an EntitySchema - the $lib schema module, a +server.ts API route (createKitHandlers), and a +page.svelte with SvGrid + SvGridEditPanel. Returns files as { path, contents, description }. AFTER writing the files, run the project\'s own svelte-check / tsc to verify they compile, and fix any errors. Generated bodies are wrapped in svgrid:managed markers so regeneration preserves edits outside them.',
114
+ inputSchema: {
115
+ type: 'object',
116
+ properties: {
117
+ schema: {
118
+ type: 'object',
119
+ description: 'The EntitySchema (from introspect_source, optionally edited).',
120
+ },
121
+ route: { type: 'string', description: 'Route segment. Defaults to schema.name.' },
122
+ apiRoute: { type: 'string', description: 'API route. Defaults to /api/{route}.' },
123
+ },
124
+ required: ['schema'],
125
+ },
126
+ },
74
127
  ],
75
128
  };
76
129
  });
@@ -139,6 +192,48 @@ server.setRequestHandler(CallToolRequestSchema, async (req) => {
139
192
  case 'get_api_reference': {
140
193
  return { content: [{ type: 'text', text: JSON.stringify(apiReference, null, 2) }] };
141
194
  }
195
+ case 'introspect_source': {
196
+ const a = (args ?? {});
197
+ try {
198
+ let schema;
199
+ if (a.kind === 'drizzle') {
200
+ if (!a.source)
201
+ return errText('source is required for kind:"drizzle"');
202
+ schema = introspectDrizzle(a.source);
203
+ }
204
+ else if (a.kind === 'json') {
205
+ if (!Array.isArray(a.rows) || a.rows.length === 0) {
206
+ return errText('rows (a non-empty array) is required for kind:"json"');
207
+ }
208
+ schema = introspectJson(a.name ?? 'entity', a.rows);
209
+ }
210
+ else {
211
+ return errText('kind must be "drizzle" or "json"');
212
+ }
213
+ return { content: [{ type: 'text', text: studioNote() + JSON.stringify(schema, null, 2) }] };
214
+ }
215
+ catch (err) {
216
+ return errText(err instanceof Error ? err.message : String(err));
217
+ }
218
+ }
219
+ case 'scaffold_entity': {
220
+ const a = (args ?? {});
221
+ if (!a.schema || !Array.isArray(a.schema.fields) || a.schema.fields.length === 0) {
222
+ return errText('schema (an EntitySchema with a non-empty fields array) is required');
223
+ }
224
+ try {
225
+ const { files } = scaffold(a.schema, { route: a.route, apiRoute: a.apiRoute });
226
+ // Verify loop: compile the generated .svelte before handing files back.
227
+ const verify = await verifyScaffold(files);
228
+ const header = `// ${summarizeVerify(verify)}\n// After writing these files, run the project's svelte-check / tsc and fix any errors.\n\n`;
229
+ return {
230
+ content: [{ type: 'text', text: studioNote() + header + JSON.stringify({ files, verify }, null, 2) }],
231
+ };
232
+ }
233
+ catch (err) {
234
+ return errText(err instanceof Error ? err.message : String(err));
235
+ }
236
+ }
142
237
  default:
143
238
  return {
144
239
  isError: true,
package/package.json CHANGED
@@ -1,42 +1,45 @@
1
- {
2
- "name": "@svgrid/mcp",
3
- "version": "2.0.0",
4
- "description": "Model Context Protocol (MCP) server for SvGrid. Exposes example sources, docs, and API reference to AI assistants.",
5
- "license": "SEE LICENSE IN LICENSE",
6
- "author": "jQWidgets <sales@jqwidgets.com>",
7
- "homepage": "https://sv-grid.github.io/sv-grid/#/mcp",
8
- "repository": {
9
- "type": "git",
10
- "url": "https://github.com/sv-grid/sv-grid.git",
11
- "directory": "packages/mcp"
12
- },
13
- "type": "module",
14
- "main": "dist/index.js",
15
- "bin": {
16
- "@svgrid/mcp": "dist/index.js"
17
- },
18
- "files": [
19
- "dist",
20
- "README.md",
21
- "LICENSE"
22
- ],
23
- "scripts": {
24
- "build:manifests": "node ./scripts/build-manifests.mjs",
25
- "build:ts": "tsc -p tsconfig.json",
26
- "build": "pnpm build:manifests && pnpm build:ts",
27
- "start": "node dist/index.js",
28
- "test:types": "tsc -p tsconfig.json --noEmit"
29
- },
30
- "dependencies": {
31
- "@modelcontextprotocol/sdk": "^1.0.4",
32
- "@svgrid/enterprise": "workspace:*",
33
- "zod": "^3.23.8"
34
- },
35
- "devDependencies": {
36
- "@types/node": "^22.10.7",
37
- "typescript": "6.0.3"
38
- },
39
- "engines": {
40
- "node": ">=18"
41
- }
1
+ {
2
+ "name": "@svgrid/mcp",
3
+ "version": "2.0.1",
4
+ "description": "Model Context Protocol (MCP) server for SvGrid. Exposes example sources, docs, and API reference to AI assistants.",
5
+ "license": "SEE LICENSE IN LICENSE",
6
+ "author": "jQWidgets <sales@jqwidgets.com>",
7
+ "homepage": "https://sv-grid.github.io/sv-grid/#/mcp",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/sv-grid/sv-grid.git",
11
+ "directory": "packages/mcp"
12
+ },
13
+ "type": "module",
14
+ "main": "dist/index.js",
15
+ "bin": {
16
+ "@svgrid/mcp": "dist/index.js"
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "README.md",
21
+ "LICENSE"
22
+ ],
23
+ "publishConfig": {
24
+ "access": "public"
25
+ },
26
+ "dependencies": {
27
+ "@modelcontextprotocol/sdk": "^1.0.4",
28
+ "zod": "^3.23.8",
29
+ "@svgrid/enterprise": "^2.0.1"
30
+ },
31
+ "devDependencies": {
32
+ "@types/node": "^22.10.7",
33
+ "typescript": "6.0.3"
34
+ },
35
+ "engines": {
36
+ "node": ">=18"
37
+ },
38
+ "scripts": {
39
+ "build:manifests": "node ./scripts/build-manifests.mjs",
40
+ "build:ts": "tsc -p tsconfig.json",
41
+ "build": "pnpm build:manifests && pnpm build:ts",
42
+ "start": "node dist/index.js",
43
+ "test:types": "tsc -p tsconfig.json --noEmit"
44
+ }
42
45
  }