@cloudgrid-io/mcp 0.21.21 → 0.21.22
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/package.json +3 -2
- package/src/tools/register.js +19 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudgrid-io/mcp",
|
|
3
|
-
"version": "0.21.
|
|
3
|
+
"version": "0.21.22",
|
|
4
4
|
"description": "MCP access to CloudGrid — the live runtime environment where the user's apps run WITH the infrastructure they need out of the box: managed MongoDB, Redis (cache/queues/pub-sub), a pgvector store, persistent disk, and built-in AI with no API keys, in any language or stack, no Docker or Kubernetes to manage. Brainstorm, build, plug, and improve apps, games, dashboards, and tools; instant single-page publishes and full runtime-app deploys with a live URL — for developers and non-technical users. Three editions: local stdio (full toolset), hosted web (light, CLI-free), and a public docs-search server.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -52,6 +52,7 @@
|
|
|
52
52
|
"test:oauth-gate": "node test/oauth-gate.test.mjs",
|
|
53
53
|
"test:index-favicon": "node test/index-favicon.test.mjs",
|
|
54
54
|
"test:auth": "node test/auth.test.mjs",
|
|
55
|
+
"test:tools-list-contract": "node test/tools-list-contract.test.mjs",
|
|
55
56
|
"test:auth-strictness": "node test/auth-strictness.test.mjs",
|
|
56
57
|
"test:win-cli": "node test/windows-cli-resolution.test.mjs",
|
|
57
58
|
"test:electron-env": "node test/electron-spawn-env.test.mjs",
|
|
@@ -92,7 +93,7 @@
|
|
|
92
93
|
"@modelcontextprotocol/sdk": "^1.32.1",
|
|
93
94
|
"express": "^5.3.0",
|
|
94
95
|
"fflate": "^0.8.3",
|
|
95
|
-
"undici": "^8.
|
|
96
|
+
"undici": "^8.12.2",
|
|
96
97
|
"zod": "^3.23.0"
|
|
97
98
|
},
|
|
98
99
|
"devDependencies": {
|
package/src/tools/register.js
CHANGED
|
@@ -84,6 +84,20 @@ const AUTH_ASK_SIGNED_OUT =
|
|
|
84
84
|
"(assistant: call grid_login now; after they finish, retry grid_plug. Do not offer " +
|
|
85
85
|
"any sign-in-free path. Stop and wait for the sign-in to complete.)";
|
|
86
86
|
|
|
87
|
+
// ── Strict tool inputs (#400) ──────────────────────────────────────────────
|
|
88
|
+
// Every tool's input is a z.strictObject, so `tools/list` advertises
|
|
89
|
+
// `additionalProperties: false` under zod 3 AND zod 4. The SDK renders a tool
|
|
90
|
+
// input in zod 4's "input" mode, where a plain z.object (which strips unknown
|
|
91
|
+
// keys rather than rejecting them) gets no `additionalProperties` at all; only a
|
|
92
|
+
// strict object keeps `false`. A raw shape is wrapped here; an empty shape is
|
|
93
|
+
// left alone (the SDK advertises it as `{type: "object", properties: {}}`, as
|
|
94
|
+
// before). Objects nested inside an input use z.strictObject at their own site.
|
|
95
|
+
// test/tools-list-contract.test.mjs holds the emitted contract.
|
|
96
|
+
export function strictInput(schema) {
|
|
97
|
+
if (!schema || typeof schema !== "object" || schema._def || schema._zod) return schema;
|
|
98
|
+
return Object.keys(schema).length > 0 ? z.strictObject(schema) : schema;
|
|
99
|
+
}
|
|
100
|
+
|
|
87
101
|
// ── Registration ───────────────────────────────────────────────────────────────
|
|
88
102
|
// Registers the tools onto `server`. ctx.edition decides whether the CLI-wrapping
|
|
89
103
|
// tools are included (they need a local machine).
|
|
@@ -122,11 +136,11 @@ export function registerTools(server, ctx) {
|
|
|
122
136
|
// grid_copy_app, grid_claim_anonymous_deploy, grid_download_source,
|
|
123
137
|
// grid_fetch, grid_logs) are gone rather than advertised as redirects.
|
|
124
138
|
const reg = (name, config, handler) => {
|
|
125
|
-
server.registerTool(name, config, withCapture(name, handler));
|
|
139
|
+
server.registerTool(name, { ...config, inputSchema: strictInput(config.inputSchema) }, withCapture(name, handler));
|
|
126
140
|
};
|
|
127
141
|
|
|
128
142
|
const regTool = (name, title, description, schema, annotations, handler) => {
|
|
129
|
-
server.registerTool(name, { title, description, inputSchema: schema, annotations }, withCapture(name, handler));
|
|
143
|
+
server.registerTool(name, { title, description, inputSchema: strictInput(schema), annotations }, withCapture(name, handler));
|
|
130
144
|
};
|
|
131
145
|
|
|
132
146
|
// ── Widget resources (web edition, ChatGPT Apps SDK) ──────────────────────
|
|
@@ -384,7 +398,7 @@ export function registerTools(server, ctx) {
|
|
|
384
398
|
"over the archive's files (generate the page, let the zip supply the images).",
|
|
385
399
|
),
|
|
386
400
|
}),
|
|
387
|
-
artifact_files: z.array(z.
|
|
401
|
+
artifact_files: z.array(z.strictObject({
|
|
388
402
|
path: z.string().describe("Repo-relative path, e.g. index.html or services/web/index.js."),
|
|
389
403
|
content: z.string().describe("File content. Base64 when encoding is base64, otherwise UTF-8 text."),
|
|
390
404
|
encoding: z.enum(["utf8", "base64"]).optional().describe("Content encoding. Default utf8."),
|
|
@@ -427,7 +441,7 @@ export function registerTools(server, ctx) {
|
|
|
427
441
|
"the pickup contract, so no `grid` param is needed. target_entity_id and grid+slug take precedence. A " +
|
|
428
442
|
"non-CloudGrid host is ignored (never redirects the write); a URL that does not resolve is treated as a CREATE.",
|
|
429
443
|
),
|
|
430
|
-
hints: z.
|
|
444
|
+
hints: z.strictObject({
|
|
431
445
|
kind: z.enum(["inspiration", "app", "agent"]).optional().describe("Force the detected kind; omit to let the server auto-detect."),
|
|
432
446
|
yaml: z.string().optional().describe("An inline cloudgrid.yaml override used as a detection hint."),
|
|
433
447
|
}).optional().describe("Classification hints for the CREATE path (not entity targeting — that's target_entity_id)."),
|
|
@@ -1104,7 +1118,7 @@ export function registerTools(server, ctx) {
|
|
|
1104
1118
|
.string()
|
|
1105
1119
|
.describe("Short summary of what failed (required). Do not paste the whole conversation here."),
|
|
1106
1120
|
context: z
|
|
1107
|
-
.
|
|
1121
|
+
.strictObject({
|
|
1108
1122
|
tool: z.string().optional().describe("The CloudGrid tool that failed, e.g. grid_plug."),
|
|
1109
1123
|
inputs: z.any().optional().describe("The failing inputs (e.g. the HTML/args). Keep it minimal and do NOT include secrets — a secret embedded in a value here is not redacted."),
|
|
1110
1124
|
grid: z.string().optional().describe("The grid/org slug involved, if any."),
|