@svgrid/mcp 3.0.16 → 3.0.18
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 +21 -9
- package/dist/core-tools.js +31 -6
- package/dist/data.js +960 -43
- package/dist/enterprise.d.ts +36 -0
- package/dist/enterprise.js +43 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +5 -1
- package/dist/installed.js +4 -4
- package/dist/preview.d.ts +1 -1
- package/dist/preview.js +1 -1
- package/package.json +2 -2
- package/server.json +2 -2
package/README.md
CHANGED
|
@@ -22,19 +22,20 @@
|
|
|
22
22
|
|
|
23
23
|
Point any MCP-capable client - Claude Desktop, Claude Code, Cursor, Zed - at this server and the model answers with **accurate, version-pinned** facts about SvGrid: real prop, method, and event names, plus every demo's source as grounding. No hallucinated APIs, no stale blog posts.
|
|
24
24
|
|
|
25
|
-
**Why this beats pasting docs into the chat.** A model working from memory invents plausible SvGrid APIs, because it learned from a mix of other grids and older versions. Pasting docs helps for one question and then falls out of the context window. This server puts the current API surface and
|
|
25
|
+
**Why this beats pasting docs into the chat.** A model working from memory invents plausible SvGrid APIs, because it learned from a mix of other grids and older versions. Pasting docs helps for one question and then falls out of the context window. This server puts the current API surface and every working demo source one tool call away, for every question, pinned to the version you installed.
|
|
26
26
|
|
|
27
27
|
## Tools exposed
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
Five. `tools/list` is sent on **every** request, so the tool surface is pure
|
|
30
30
|
overhead on every turn - this server used to spend ~4,710 tokens of it on 36
|
|
31
31
|
tools, 79% of them Studio tools most sessions never call once.
|
|
32
32
|
|
|
33
33
|
| Tool | Purpose |
|
|
34
34
|
| --- | --- |
|
|
35
|
-
| `svgrid_search` | Search the docs,
|
|
35
|
+
| `svgrid_search` | Search the docs, every demo and the API surface **in one call**. No arguments returns an index. |
|
|
36
36
|
| `svgrid_get` | Read one thing in full: a doc slug, a demo id, or `api`. |
|
|
37
37
|
| `svgrid_check_code` | **Verify** a file against the real API surface + the Svelte compiler. |
|
|
38
|
+
| `svgrid_preview` | Render a live, interactive grid in the conversation from columns + rows (MCP Apps). |
|
|
38
39
|
| `svgrid_scaffold` | Studio: turn a Drizzle schema, sample rows or an `EntitySchema` into runnable SvelteKit files. |
|
|
39
40
|
|
|
40
41
|
The docs and demos are also served as **MCP resources**
|
|
@@ -89,8 +90,8 @@ What it checks:
|
|
|
89
90
|
too. The result says which of the two ran in its `compiler` field, so
|
|
90
91
|
"no errors" is never mistaken for "this compiles".
|
|
91
92
|
|
|
92
|
-
It is tuned to shut up when the code is right: it reports **nothing** across
|
|
93
|
-
|
|
93
|
+
It is tuned to shut up when the code is right: it reports **nothing** across
|
|
94
|
+
every demo in this repo, which is what a CI test asserts. A verifier that cries
|
|
94
95
|
wolf is worse than none, because a model will happily "fix" working code.
|
|
95
96
|
|
|
96
97
|
### Studio: drive the app model (agent co-designer)
|
|
@@ -122,8 +123,8 @@ failure reports which op failed and what already applied.
|
|
|
122
123
|
| --- | --- | --- |
|
|
123
124
|
| Install | `npx @svgrid/mcp` | `https://mcp.svgrid.com/mcp` |
|
|
124
125
|
| Needs Node | yes | no |
|
|
125
|
-
| `
|
|
126
|
-
| Studio `studio_*` tools | yes (
|
|
126
|
+
| `svgrid_check_code` compiles | yes | static checks only |
|
|
127
|
+
| Studio `studio_*` tools | yes (opt-in) | no |
|
|
127
128
|
| Works offline | yes | no |
|
|
128
129
|
|
|
129
130
|
```bash
|
|
@@ -136,8 +137,8 @@ claude mcp add --transport http svgrid https://mcp.svgrid.com/mcp
|
|
|
136
137
|
<a href="https://insiders.vscode.dev/redirect/mcp/install?name=svgrid&config=%7B%22name%22%3A%22svgrid%22%2C%22type%22%3A%22http%22%2C%22url%22%3A%22https%3A%2F%2Fmcp.svgrid.com%2Fmcp%22%7D"><img src="https://img.shields.io/badge/Add%20to-VS%20Code-0098FF?logo=visualstudiocode&logoColor=white" alt="Add to VS Code" /></a>
|
|
137
138
|
</p>
|
|
138
139
|
|
|
139
|
-
The remote server is live at **https://mcp.svgrid.com/mcp** and carries the
|
|
140
|
-
|
|
140
|
+
The remote server is live at **https://mcp.svgrid.com/mcp** and carries the docs,
|
|
141
|
+
verification and preview tools ([source](../../workers/svgrid-mcp)). Use stdio when
|
|
141
142
|
you want the compiler pass, the Studio tools, or no third-party endpoint in the
|
|
142
143
|
loop.
|
|
143
144
|
|
|
@@ -206,6 +207,17 @@ node dist/index.js
|
|
|
206
207
|
`examples/src/demos/*.svelte` and `docs/**/*.md` from the workspace and inlines
|
|
207
208
|
them into `src/data.ts`, so the published package is fully self-contained.
|
|
208
209
|
|
|
210
|
+
## Enterprise features
|
|
211
|
+
|
|
212
|
+
Export to Excel and PDF, pivot tables, the Kanban board, the scheduler, the
|
|
213
|
+
spreadsheet and the server-side row model live in `@svgrid/enterprise`, which
|
|
214
|
+
is commercial. Answers say so: a paid doc or demo in `svgrid_search` results
|
|
215
|
+
carries `"enterprise": true`, a question about a paid feature gets one line
|
|
216
|
+
with the trial link, and `svgrid_check_code` adds it when the fix is to install
|
|
217
|
+
the package. The package runs without a license key and shows a watermark
|
|
218
|
+
until one is set. The [30-day trial](https://svgrid.com/pricing/?trial=mcp-docs)
|
|
219
|
+
adds a download of every demo and 30 days of email support.
|
|
220
|
+
|
|
209
221
|
## Licensing
|
|
210
222
|
|
|
211
223
|
MIT - free to run, no license key. Some tools generate SvGrid Studio projects, and Studio itself is
|
package/dist/core-tools.js
CHANGED
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import { apiReference, apiSurface, docs, examples, schemas } from './data.js';
|
|
17
17
|
import { meaningfulTerms, rankDocs } from './search.js';
|
|
18
|
-
|
|
18
|
+
import { ENTERPRISE_LINE, ENTERPRISE_NOTE, importsEnterprise, isEnterpriseDoc, isPaidQuestion } from './enterprise.js';
|
|
19
|
+
const DOCS_FOOTER = `\n\nSvGrid reference: full docs & ${examples.length} live demos at https://svgrid.com/docs`;
|
|
19
20
|
const text = (body) => ({ content: [{ type: 'text', text: body }] });
|
|
20
21
|
const withDocs = (body) => text(body + DOCS_FOOTER);
|
|
21
22
|
const fail = (message) => ({
|
|
@@ -59,8 +60,20 @@ const apiNames = (() => {
|
|
|
59
60
|
add(c.name, 'column option');
|
|
60
61
|
for (const m of apiSurface.apiMethods)
|
|
61
62
|
add(m, 'grid api method');
|
|
62
|
-
|
|
63
|
+
// The methods installEnterprise(api) adds are searchable too, so "export"
|
|
64
|
+
// finds exportData and says where it comes from. Not every enterprise
|
|
65
|
+
// export: over a thousand names drowned the free API on ordinary queries
|
|
66
|
+
// (tools/mcp-tools.test.ts, "filler words"); the docs and demos cover them.
|
|
67
|
+
for (const m of apiSurface.enterpriseApiMethods)
|
|
68
|
+
add(m, 'enterprise api method (installEnterprise)');
|
|
69
|
+
return [...merged].map(([name, groups]) => {
|
|
70
|
+
const group = [...groups].join(', ');
|
|
71
|
+
return { name, group, ...(group.includes('enterprise') ? { enterprise: true } : {}) };
|
|
72
|
+
});
|
|
63
73
|
})();
|
|
74
|
+
/** Docs and demos that use the paid package, found once from their source. */
|
|
75
|
+
const enterpriseDocs = new Set(docs.filter((d) => isEnterpriseDoc(d.slug, d.markdown)).map((d) => d.slug));
|
|
76
|
+
const enterpriseExamples = new Set(examples.filter((e) => importsEnterprise(e.source)).map((e) => e.id));
|
|
64
77
|
export const CORE_TOOLS = [
|
|
65
78
|
{
|
|
66
79
|
name: 'svgrid_search',
|
|
@@ -240,7 +253,10 @@ function search(args) {
|
|
|
240
253
|
body.docs = {
|
|
241
254
|
total: ranked.total,
|
|
242
255
|
partial: partial || undefined,
|
|
243
|
-
hits: shown.map((h) =>
|
|
256
|
+
hits: shown.map((h) => {
|
|
257
|
+
const hit = detail === 'full' ? h : { ...h, excerpt: trimBlurb(String(h.excerpt ?? ''), 200) };
|
|
258
|
+
return enterpriseDocs.has(String(h.slug)) ? { ...hit, enterprise: true } : hit;
|
|
259
|
+
}),
|
|
244
260
|
};
|
|
245
261
|
if (partial) {
|
|
246
262
|
body.hint = `No page matched all of "${query}". These matched some of it - treat them as leads, not answers.`;
|
|
@@ -258,6 +274,7 @@ function search(args) {
|
|
|
258
274
|
title: e.title,
|
|
259
275
|
category: e.category,
|
|
260
276
|
blurb: detail === 'full' ? e.blurb : trimBlurb(e.blurb),
|
|
277
|
+
...(enterpriseExamples.has(e.id) ? { enterprise: true } : {}),
|
|
261
278
|
})),
|
|
262
279
|
};
|
|
263
280
|
}
|
|
@@ -268,6 +285,10 @@ function search(args) {
|
|
|
268
285
|
const empty = !body.docs?.total &&
|
|
269
286
|
!body.examples?.total &&
|
|
270
287
|
!body.api?.total;
|
|
288
|
+
// Once per answer, and only when the question is about a paid feature.
|
|
289
|
+
const lists = [body.docs, body.examples, body.api].map((c) => c?.hits ?? []);
|
|
290
|
+
if (isPaidQuestion(lists))
|
|
291
|
+
body.enterprise = ENTERPRISE_NOTE;
|
|
271
292
|
if (!empty) {
|
|
272
293
|
// A partial-match warning outranks the generic next-step hint: it is the
|
|
273
294
|
// one thing the caller must not miss, and it is set above.
|
|
@@ -352,15 +373,19 @@ function get(args) {
|
|
|
352
373
|
}
|
|
353
374
|
if (kind === 'doc' || kind === 'auto') {
|
|
354
375
|
const doc = docs.find((d) => d.slug === ref);
|
|
355
|
-
if (doc)
|
|
356
|
-
|
|
376
|
+
if (doc) {
|
|
377
|
+
// On top, where truncation cannot cut it off.
|
|
378
|
+
const paid = enterpriseDocs.has(doc.slug) ? `> ${ENTERPRISE_LINE}\n\n` : '';
|
|
379
|
+
return withDocs(clip(paid + doc.markdown));
|
|
380
|
+
}
|
|
357
381
|
if (kind === 'doc') {
|
|
358
382
|
return fail(`No doc with slug "${ref}". Use svgrid_search to find one.`);
|
|
359
383
|
}
|
|
360
384
|
}
|
|
361
385
|
const example = examples.find((e) => e.id === ref);
|
|
362
386
|
if (example) {
|
|
363
|
-
|
|
387
|
+
const paid = enterpriseExamples.has(example.id) ? `// ${ENTERPRISE_LINE}\n` : '';
|
|
388
|
+
return text(clip(`// ${example.path}\n// ${example.title} - ${example.blurb}\n${paid}\n${example.source}`));
|
|
364
389
|
}
|
|
365
390
|
// A miss is a chance to point somewhere useful rather than just say no.
|
|
366
391
|
const near = [
|