@cloudgrid-io/mcp 0.9.1 → 0.11.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 +33 -33
- package/package.json +2 -1
- package/src/corpus/capability-map.md +69 -0
- package/src/corpus/cookbook.md +1 -1
- package/src/corpus/install.md +1 -1
- package/src/corpus/skill-claim.md +1 -1
- package/src/corpus/skill-drop.md +2 -2
- package/src/corpus/skill-login.md +2 -2
- package/src/corpus/templates/app-with-data/cloudgrid.yaml +4 -0
- package/src/corpus/templates/app-with-data/index.md +10 -0
- package/src/corpus/templates/dashboard/cloudgrid.yaml +10 -0
- package/src/corpus/templates/dashboard/index.md +30 -0
- package/src/corpus/templates/deck/cloudgrid.yaml +10 -0
- package/src/corpus/templates/deck/index.md +30 -0
- package/src/corpus/templates/landing-page/cloudgrid.yaml +10 -0
- package/src/corpus/templates/landing-page/index.md +30 -0
- package/src/corpus/templates/report/cloudgrid.yaml +10 -0
- package/src/corpus/templates/report/index.md +30 -0
- package/src/corpus/templates/web-app/cloudgrid.yaml +10 -0
- package/src/corpus/templates/web-app/index.md +30 -0
- package/src/corpus/usage.md +2 -2
- package/src/corpus/workflows/app-with-data.md +5 -1
- package/src/corpus/workflows/dashboard.md +5 -1
- package/src/corpus/workflows/landing-page.md +5 -1
- package/src/corpus/workflows/presentation.md +5 -1
- package/src/corpus/workflows/report.md +5 -1
- package/src/corpus/workflows/web-app.md +5 -1
- package/src/tools.js +30 -44
- package/src/widgets/live-result.html +1 -1
- package/src/widgets/org-picker.html +1 -1
package/README.md
CHANGED
|
@@ -66,44 +66,44 @@ It speaks MCP over stdio. Point any MCP client at the `cloudgrid-mcp` command.
|
|
|
66
66
|
| `gridctl_claim` | `POST /api/v2/entities/:id/pickup` | Claim an anonymous drop into the signed-in account (the claim token IS the drop's owner token). Direct API. |
|
|
67
67
|
| `gridctl_fork` | `POST /api/v2/runtimes/:id/fork` | Start a new entity from an existing runtime (lineage recorded). Needs sign-in. |
|
|
68
68
|
| `gridctl_download` | `GET /api/v2/runtimes/:id/source` | Signed 15-minute source-bundle URLs. Needs sign-in. |
|
|
69
|
-
| `
|
|
70
|
-
| `
|
|
71
|
-
| `
|
|
69
|
+
| `gridctl_login` | `GET /auth/login` | Start a CLI-free sign-in; returns a URL to open. Direct API. |
|
|
70
|
+
| `gridctl_login_status` | `GET /auth/status` | Finish the sign-in; saves the token to the shared CLI credentials. |
|
|
71
|
+
| `gridctl_visibility` | `PATCH /api/v2/inspirations/<id>` | Change who can see a drop (private, space, authenticated, org, link). Needs sign-in. Direct API; also in the web edition. |
|
|
72
72
|
|
|
73
|
-
`
|
|
74
|
-
`
|
|
75
|
-
also work in the web edition where no CLI exists. `
|
|
73
|
+
`gridctl_drop`, `gridctl_claim`, `gridctl_visibility`, and the two
|
|
74
|
+
`gridctl_login` tools do not wrap the CLI -- they call the API directly, so they
|
|
75
|
+
also work in the web edition where no CLI exists. `gridctl_login` writes the same
|
|
76
76
|
`~/.cloudgrid/credentials` the CLI uses, so the two share one identity.
|
|
77
77
|
|
|
78
78
|
### CLI-wrapping tools (local edition only)
|
|
79
79
|
|
|
80
80
|
| Tool | Wraps | Notes |
|
|
81
81
|
|---|---|---|
|
|
82
|
-
| `
|
|
83
|
-
| `
|
|
84
|
-
| `
|
|
85
|
-
| `
|
|
86
|
-
| `
|
|
87
|
-
| `
|
|
88
|
-
| `
|
|
89
|
-
| `
|
|
90
|
-
| `
|
|
91
|
-
| `
|
|
92
|
-
| `
|
|
93
|
-
| `
|
|
94
|
-
| `
|
|
95
|
-
| `
|
|
96
|
-
| `
|
|
97
|
-
| `
|
|
98
|
-
| `
|
|
99
|
-
| `
|
|
100
|
-
| `
|
|
101
|
-
| `
|
|
102
|
-
| `
|
|
103
|
-
| `
|
|
104
|
-
|
|
105
|
-
`
|
|
106
|
-
wraps the CLI and defaults to `link`; `
|
|
82
|
+
| `gridctl_init` | `cloudgrid init` | Register an app or agent; optionally seed a web service. |
|
|
83
|
+
| `gridctl_logs` | `cloudgrid logs` | Snapshot of recent logs. Does not stream. Read-only. |
|
|
84
|
+
| `gridctl_share` | `cloudgrid visibility set` | Set visibility, default link. |
|
|
85
|
+
| `gridctl_feedback` | `cloudgrid feedback list` | Read the org feedback feed. Read-only. |
|
|
86
|
+
| `gridctl_whoami` | `cloudgrid whoami` | Show the signed-in user and active org. Read-only. |
|
|
87
|
+
| `gridctl_use` | `cloudgrid use` | Switch the active org. |
|
|
88
|
+
| `gridctl_logout` | `cloudgrid logout` | Sign out and clear local credentials. Destructive. |
|
|
89
|
+
| `gridctl_status` | `cloudgrid status` | Org dashboard or entity detail. Read-only. |
|
|
90
|
+
| `gridctl_info` | `cloudgrid info` | Entity metadata. Read-only. |
|
|
91
|
+
| `gridctl_get` | `cloudgrid get grids\|entities\|spaces` | List grids, entities, or spaces. Read-only. |
|
|
92
|
+
| `gridctl_describe_grid` | `cloudgrid describe grid <slug>` | Grid detail. Read-only. |
|
|
93
|
+
| `gridctl_pickup` | `cloudgrid pickup <name>` | Download an entity's source and bind the folder. |
|
|
94
|
+
| `gridctl_rename` | `cloudgrid rename` | Rename an entity's display name. |
|
|
95
|
+
| `gridctl_unplug` | `cloudgrid unplug` | Take an entity off the grid. Destructive; requires confirm. |
|
|
96
|
+
| `gridctl_delete` | `cloudgrid delete entity` | Archive an inspiration. Destructive; requires confirm. |
|
|
97
|
+
| `gridctl_rollback` | `cloudgrid rollback` | Rollback to a previous version. |
|
|
98
|
+
| `gridctl_versions` | `cloudgrid versions` | List published versions. Read-only. |
|
|
99
|
+
| `gridctl_env` | `cloudgrid env` | Get, set, or list environment variables. |
|
|
100
|
+
| `gridctl_secrets` | `cloudgrid secrets` | Set or list secret names. Never returns secret values. |
|
|
101
|
+
| `gridctl_scaffold` | `cloudgrid scaffold` | Generate starter files. |
|
|
102
|
+
| `gridctl_doctor` | `cloudgrid doctor` | Run local diagnostics. Read-only. |
|
|
103
|
+
| `gridctl_open` | `cloudgrid open --print` | Return the public URL. Does not open a browser. Read-only. |
|
|
104
|
+
|
|
105
|
+
`gridctl_share` and `gridctl_visibility` overlap on purpose: `gridctl_share`
|
|
106
|
+
wraps the CLI and defaults to `link`; `gridctl_visibility` is direct API, takes an
|
|
107
107
|
explicit scope, and defaults its target to the session's last drop -- it is the one
|
|
108
108
|
the web edition gets.
|
|
109
109
|
|
|
@@ -113,7 +113,7 @@ All tools carry MCP annotations (`readOnlyHint`, `destructiveHint`,
|
|
|
113
113
|
## Test
|
|
114
114
|
|
|
115
115
|
A smoke test spawns the server with a real MCP client, lists the tools, and calls
|
|
116
|
-
the read-only `
|
|
116
|
+
the read-only `gridctl_feedback` tool end to end:
|
|
117
117
|
|
|
118
118
|
```
|
|
119
119
|
cd mcp-server
|
|
@@ -127,5 +127,5 @@ It needs a logged-in CLI on `$PATH`.
|
|
|
127
127
|
|
|
128
128
|
- Shells out with `execFile` and an argument array, so there is no shell and no
|
|
129
129
|
injection surface.
|
|
130
|
-
- `
|
|
130
|
+
- `gridctl_logs` never uses `--follow`; a streaming call would never return.
|
|
131
131
|
- Stateless. Each call is one CLI invocation.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudgrid-io/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "MCP server for CloudGrid. Three editions: a local stdio server (full toolset), a hosted web server (light, CLI-free toolset), and a public docs server (search_cloudgrid_documentation) over MCP Streamable HTTP.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"test:error-reporting": "node test/error-reporting.test.mjs",
|
|
21
21
|
"test:source": "node test/source-fetch.test.mjs",
|
|
22
22
|
"test:app-with-data": "node test/app-with-data.test.mjs",
|
|
23
|
+
"test:self-describing": "node test/self-describing.test.mjs",
|
|
23
24
|
"test:content": "node test/content-handling.test.mjs",
|
|
24
25
|
"test:self-healing": "node test/self-healing.test.mjs",
|
|
25
26
|
"test:grid-picker": "node test/grid-picker.test.mjs",
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Capability map — intent → template → capabilities → deploy
|
|
2
|
+
|
|
3
|
+
This is the index an LLM uses to turn a user request into the right CloudGrid
|
|
4
|
+
template, the way Superpowers matches a skill's `when:`. Match the request to a
|
|
5
|
+
template by its `when:` triggers, adopt that template's `needs:`, then deploy:
|
|
6
|
+
|
|
7
|
+
- **static → inspiration** (instant, any client / any edition) via `gridctl_drop`.
|
|
8
|
+
- **anything needing `needs:` → runtime** (async build, **local edition** only)
|
|
9
|
+
via `gridctl_plug` on a linked folder.
|
|
10
|
+
|
|
11
|
+
Fetch this doc any time with `gridctl_fetch("doc", "capability-map")`.
|
|
12
|
+
|
|
13
|
+
## The 6 templates
|
|
14
|
+
|
|
15
|
+
| Intent (match on `when:`) | Template | `needs:` | Deploy | Edition |
|
|
16
|
+
|---|---|---|---|---|
|
|
17
|
+
| landing page, marketing/product/hero page, coming-soon, waitlist, pricing, portfolio, link-in-bio, event page | `landing-page` | none | inspiration (instant) | all |
|
|
18
|
+
| calculator, converter, generator, timer, quiz, interactive tool, mini-app, widget — computed client-side, no saved data | `web-app` | none | inspiration (instant) | all |
|
|
19
|
+
| dashboard, metrics, KPIs, stats page, status board, charts, analytics view — display-only, static data baked in | `dashboard` | none | inspiration (instant) | all |
|
|
20
|
+
| report, one-pager, summary, brief, whitepaper, case study, formatted document | `report` | none | inspiration (instant) | all |
|
|
21
|
+
| slides, deck, pitch, presentation, slideshow | `presentation` (dir: `deck`) | none | inspiration (instant) | all |
|
|
22
|
+
| to-do, task list, notes app, guestbook, CRUD app, a form that SAVES/STORES submissions, anything that PERSISTS data or shares state across users/sessions, sign-in/accounts | `app-with-data` | `database: true` | runtime (async, poll) | local |
|
|
23
|
+
|
|
24
|
+
**Rule of thumb:** if the app must SAVE/remember data, share state across
|
|
25
|
+
users/sessions, log in, or store submissions → it is persistent → `app-with-data`
|
|
26
|
+
(runtime, local edition). Otherwise a static template deploys instantly anywhere.
|
|
27
|
+
|
|
28
|
+
## The full `needs:` vocabulary (the whole menu)
|
|
29
|
+
|
|
30
|
+
`needs:` is a MAP declaring infrastructure capabilities. Values are `true` or an
|
|
31
|
+
engine hint. Cron is NOT a need — it is a **service type** (`type: cron` with
|
|
32
|
+
`schedule` + `timezone`). See the cloudgrid.yaml reference §5, §12, §14.
|
|
33
|
+
|
|
34
|
+
| `needs:` key | Provides | Injected env var(s) | Status |
|
|
35
|
+
|---|---|---|---|
|
|
36
|
+
| `database: true` | MongoDB primary datastore | `DATABASE_MONGODB_URL` (+legacy `MONGODB_URL`) | **Today via `requires: [mongodb]`** — `needs:` pending #1527 |
|
|
37
|
+
| `cache: true` | Redis, LRU eviction | `CACHE_REDIS_URL` (+legacy `REDIS_URL`) | **Today via `requires: [redis]`** — `needs:` pending #1527 |
|
|
38
|
+
| `kv: true` | Redis, no eviction | `KV_REDIS_URL` | Pending #1527 |
|
|
39
|
+
| `queue: true` | Redis durable job queue | `QUEUE_REDIS_URL` | Pending #1527 |
|
|
40
|
+
| `pubsub: true` | Redis pub/sub broadcast | `PUBSUB_REDIS_URL` | Pending #1527 |
|
|
41
|
+
| `vector: pgvector` | pgvector embeddings DB | `VECTOR_PGVECTOR_URL` (+legacy `PGVECTOR_URL`) | Pending #1527 |
|
|
42
|
+
| `object_storage: true` | GCS bucket | `OBJECT_STORAGE_GCS_BUCKET`, `OBJECT_STORAGE_GCS_REGION` | Pending #1527 |
|
|
43
|
+
| `disk: true` | Persistent filesystem at `/data` | `DISK_PATH` | Pending #1527 |
|
|
44
|
+
| `ai: true` | AI Gateway access | `AI_GATEWAY_URL` | **Today** (AI Gateway) |
|
|
45
|
+
| `type: cron` (service) | Scheduled job (`schedule`, `timezone`) | — | Service type, not a need |
|
|
46
|
+
|
|
47
|
+
### Injection status — today vs pending #1527
|
|
48
|
+
|
|
49
|
+
- **Injects TODAY:** `database` and `cache` — but ONLY via the deprecated
|
|
50
|
+
`requires:` field (`requires: [mongodb]` → `MONGODB_URL`; `requires: [redis]`
|
|
51
|
+
→ `REDIS_URL`). `needs:`-based provisioning does NOT inject anything on the
|
|
52
|
+
live deployer yet (bug #1527). `ai` (AI Gateway) is available today.
|
|
53
|
+
- **Pending #1527:** `needs:`-based provisioning for everything — `vector`,
|
|
54
|
+
`queue`, `pubsub`, `kv`, `object_storage`, `disk`, and `needs: database` /
|
|
55
|
+
`needs: cache` once the deployer honors `needs:`.
|
|
56
|
+
- **`needs:` and `requires:` cannot both be active** in one yaml — the validator
|
|
57
|
+
rejects the combination ("use one or the other"). So a DB template ships
|
|
58
|
+
`requires: [mongodb]` active with the canonical `needs: { database: true }`
|
|
59
|
+
shown only as a **comment** (and declared in the workflow frontmatter as
|
|
60
|
+
metadata), flipping to `needs:` when #1527 lands.
|
|
61
|
+
|
|
62
|
+
## How to choose
|
|
63
|
+
|
|
64
|
+
1. Read the request; match it against the workflow `when:` triggers above.
|
|
65
|
+
2. Adopt that template's `needs:`. Persistence → `database`. (Future: scheduled →
|
|
66
|
+
`cron` service; semantic search / RAG → `vector` + `ai`.)
|
|
67
|
+
3. Static (`needs: none`) → publish as an inspiration with `gridctl_drop`
|
|
68
|
+
(instant, any edition). Anything with a `needs:` → runtime, local edition,
|
|
69
|
+
`gridctl_plug` a linked folder, then poll to a live URL.
|
package/src/corpus/cookbook.md
CHANGED
|
@@ -74,7 +74,7 @@ curl -sS -X POST https://api.cloudgrid.io/api/v2/plug \
|
|
|
74
74
|
The response includes `url` (the live link — use it verbatim), `entity_id`,
|
|
75
75
|
`owner_token` (keep both to update the drop later), and `claim_url` (sign in
|
|
76
76
|
before it expires to keep it). This is what the `cloudgrid-drop` skill and the
|
|
77
|
-
`
|
|
77
|
+
`gridctl_drop` MCP tool do for you. It is anonymous and serves inspirations
|
|
78
78
|
only; a full app needs the signed-in `plug` flow above.
|
|
79
79
|
|
|
80
80
|
## Update your drop in place
|
package/src/corpus/install.md
CHANGED
|
@@ -113,7 +113,7 @@ https://github.com/cloudgrid-io/mcp/releases/latest/download/cloudgrid.mcpb
|
|
|
113
113
|
|
|
114
114
|
The bundle carries the full local toolset (including the `cloudgrid` CLI), so deploy
|
|
115
115
|
and secrets tools work without a separate install. Sign in from chat with the
|
|
116
|
-
`
|
|
116
|
+
`gridctl_login` tool on first use.
|
|
117
117
|
|
|
118
118
|
## For agents
|
|
119
119
|
|
|
@@ -69,5 +69,5 @@ new_expires_at, role_granted: "owner", ... }`.
|
|
|
69
69
|
## Notes
|
|
70
70
|
|
|
71
71
|
- One pickup claims one entity. To claim several, repeat with each entity id + token.
|
|
72
|
-
- The MCP `
|
|
72
|
+
- The MCP `gridctl_claim` tool does this for you, and remembers the entity id +
|
|
73
73
|
token from the last anonymous drop so you can claim with no arguments.
|
package/src/corpus/skill-drop.md
CHANGED
|
@@ -78,7 +78,7 @@ A signed-in drop returns HTTP 202 with `entity_id`, `url`, `slug` + `grid` and n
|
|
|
78
78
|
not compose it. The org is taken from the `X-CloudGrid-Org` header — there is no
|
|
79
79
|
`org_slug` form field. If the user is a member of several orgs and the header is
|
|
80
80
|
missing, the API replies with the list of orgs to choose from. The MCP
|
|
81
|
-
`
|
|
81
|
+
`gridctl_drop` tool does this automatically when credentials are present.
|
|
82
82
|
|
|
83
83
|
## Re-plug: update the same URL in place
|
|
84
84
|
|
|
@@ -120,7 +120,7 @@ Rules that matter:
|
|
|
120
120
|
- An anonymous edit without a valid `owner_token` returns **401**.
|
|
121
121
|
- Anonymous edits count against the same daily anonymous cap as creates.
|
|
122
122
|
- Only re-plug when the user is iterating on an existing artifact. If they want a
|
|
123
|
-
separate new link, omit `target_entity_id` (the MCP `
|
|
123
|
+
separate new link, omit `target_entity_id` (the MCP `gridctl_drop` tool's
|
|
124
124
|
`fresh` flag does the same: it forces a new entity instead of updating).
|
|
125
125
|
|
|
126
126
|
## After the drop
|
|
@@ -81,6 +81,6 @@ made an anonymous drop earlier, this is the moment to offer to claim it.
|
|
|
81
81
|
|
|
82
82
|
- Enterprise single sign-on is not supported in this flow yet; those users sign in
|
|
83
83
|
through the Console for now.
|
|
84
|
-
- The MCP server exposes the same flow as `
|
|
85
|
-
`
|
|
84
|
+
- The MCP server exposes the same flow as `gridctl_login` and
|
|
85
|
+
`gridctl_login_status`, which handle the polling and the credentials write for
|
|
86
86
|
you.
|
|
@@ -53,10 +53,20 @@ services:
|
|
|
53
53
|
web:
|
|
54
54
|
type: nextjs
|
|
55
55
|
path: /
|
|
56
|
+
# Canonical capability (metadata): this app needs a database.
|
|
57
|
+
# When #1527 lands (deployer honors needs:), replace requires: with:
|
|
58
|
+
# needs:
|
|
59
|
+
# database: true
|
|
56
60
|
requires:
|
|
57
61
|
- mongodb
|
|
58
62
|
```
|
|
59
63
|
|
|
64
|
+
> **Capability:** this template's canonical need is `database: true` (see the
|
|
65
|
+
> commented block above and the capability-map). The deployed yaml keeps
|
|
66
|
+
> `requires: [mongodb]` because only `requires:` injects `MONGODB_URL` today
|
|
67
|
+
> (#1527); `needs:` and `requires:` cannot co-exist active in the same yaml, so
|
|
68
|
+
> the canonical `needs:` is shown only as a comment until the deployer honors it.
|
|
69
|
+
|
|
60
70
|
## services/web/package.json
|
|
61
71
|
|
|
62
72
|
```json
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# static — deploys as an inspiration (instant, works on hosted) via gridctl_drop;
|
|
2
|
+
# this yaml is only for plugging it as an OWNED static runtime (async, local
|
|
3
|
+
# edition only). To publish the page, prefer gridctl_drop, not grid plug.
|
|
4
|
+
#
|
|
5
|
+
# needs: {} # none — static, no infrastructure
|
|
6
|
+
name: dashboard
|
|
7
|
+
services:
|
|
8
|
+
web:
|
|
9
|
+
type: static
|
|
10
|
+
path: /
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Template: dashboard (static)
|
|
2
|
+
|
|
3
|
+
A single self-contained HTML dashboard. **No infrastructure** — no database, no backend,
|
|
4
|
+
no `needs:`. State (if any) lives only in memory and is lost on refresh.
|
|
5
|
+
|
|
6
|
+
## How it deploys
|
|
7
|
+
|
|
8
|
+
To publish this page, use **`gridctl_drop`** (or `gridctl_plug` with the inline
|
|
9
|
+
HTML): it deploys as an **inspiration** — instant, and works on the **hosted**
|
|
10
|
+
edition (Claude Web) as well as local. The reference `cloudgrid.yaml` in this
|
|
11
|
+
directory (`type: static`) is ONLY for plugging the page as an OWNED static
|
|
12
|
+
runtime (async, local edition only); the fast path is `gridctl_drop`.
|
|
13
|
+
|
|
14
|
+
The fillable HTML is the real template — fetch it with
|
|
15
|
+
`gridctl_fetch("template", "dashboard")` and fill in the user's content.
|
|
16
|
+
|
|
17
|
+
## cloudgrid.yaml (reference only)
|
|
18
|
+
|
|
19
|
+
```yaml
|
|
20
|
+
# static — deploys as an inspiration (instant, works on hosted) via gridctl_drop;
|
|
21
|
+
# this yaml is only for plugging it as an OWNED static runtime (async, local
|
|
22
|
+
# edition only). To publish the page, prefer gridctl_drop, not grid plug.
|
|
23
|
+
#
|
|
24
|
+
# needs: {} # none — static, no infrastructure
|
|
25
|
+
name: dashboard
|
|
26
|
+
services:
|
|
27
|
+
web:
|
|
28
|
+
type: static
|
|
29
|
+
path: /
|
|
30
|
+
```
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# static — deploys as an inspiration (instant, works on hosted) via gridctl_drop;
|
|
2
|
+
# this yaml is only for plugging it as an OWNED static runtime (async, local
|
|
3
|
+
# edition only). To publish the page, prefer gridctl_drop, not grid plug.
|
|
4
|
+
#
|
|
5
|
+
# needs: {} # none — static, no infrastructure
|
|
6
|
+
name: deck
|
|
7
|
+
services:
|
|
8
|
+
web:
|
|
9
|
+
type: static
|
|
10
|
+
path: /
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Template: deck (static)
|
|
2
|
+
|
|
3
|
+
A single self-contained HTML deck. **No infrastructure** — no database, no backend,
|
|
4
|
+
no `needs:`. State (if any) lives only in memory and is lost on refresh.
|
|
5
|
+
|
|
6
|
+
## How it deploys
|
|
7
|
+
|
|
8
|
+
To publish this page, use **`gridctl_drop`** (or `gridctl_plug` with the inline
|
|
9
|
+
HTML): it deploys as an **inspiration** — instant, and works on the **hosted**
|
|
10
|
+
edition (Claude Web) as well as local. The reference `cloudgrid.yaml` in this
|
|
11
|
+
directory (`type: static`) is ONLY for plugging the page as an OWNED static
|
|
12
|
+
runtime (async, local edition only); the fast path is `gridctl_drop`.
|
|
13
|
+
|
|
14
|
+
The fillable HTML is the real template — fetch it with
|
|
15
|
+
`gridctl_fetch("template", "deck")` and fill in the user's content.
|
|
16
|
+
|
|
17
|
+
## cloudgrid.yaml (reference only)
|
|
18
|
+
|
|
19
|
+
```yaml
|
|
20
|
+
# static — deploys as an inspiration (instant, works on hosted) via gridctl_drop;
|
|
21
|
+
# this yaml is only for plugging it as an OWNED static runtime (async, local
|
|
22
|
+
# edition only). To publish the page, prefer gridctl_drop, not grid plug.
|
|
23
|
+
#
|
|
24
|
+
# needs: {} # none — static, no infrastructure
|
|
25
|
+
name: deck
|
|
26
|
+
services:
|
|
27
|
+
web:
|
|
28
|
+
type: static
|
|
29
|
+
path: /
|
|
30
|
+
```
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# static — deploys as an inspiration (instant, works on hosted) via gridctl_drop;
|
|
2
|
+
# this yaml is only for plugging it as an OWNED static runtime (async, local
|
|
3
|
+
# edition only). To publish the page, prefer gridctl_drop, not grid plug.
|
|
4
|
+
#
|
|
5
|
+
# needs: {} # none — static, no infrastructure
|
|
6
|
+
name: landing-page
|
|
7
|
+
services:
|
|
8
|
+
web:
|
|
9
|
+
type: static
|
|
10
|
+
path: /
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Template: landing-page (static)
|
|
2
|
+
|
|
3
|
+
A single self-contained HTML landing-page. **No infrastructure** — no database, no backend,
|
|
4
|
+
no `needs:`. State (if any) lives only in memory and is lost on refresh.
|
|
5
|
+
|
|
6
|
+
## How it deploys
|
|
7
|
+
|
|
8
|
+
To publish this page, use **`gridctl_drop`** (or `gridctl_plug` with the inline
|
|
9
|
+
HTML): it deploys as an **inspiration** — instant, and works on the **hosted**
|
|
10
|
+
edition (Claude Web) as well as local. The reference `cloudgrid.yaml` in this
|
|
11
|
+
directory (`type: static`) is ONLY for plugging the page as an OWNED static
|
|
12
|
+
runtime (async, local edition only); the fast path is `gridctl_drop`.
|
|
13
|
+
|
|
14
|
+
The fillable HTML is the real template — fetch it with
|
|
15
|
+
`gridctl_fetch("template", "landing-page")` and fill in the user's content.
|
|
16
|
+
|
|
17
|
+
## cloudgrid.yaml (reference only)
|
|
18
|
+
|
|
19
|
+
```yaml
|
|
20
|
+
# static — deploys as an inspiration (instant, works on hosted) via gridctl_drop;
|
|
21
|
+
# this yaml is only for plugging it as an OWNED static runtime (async, local
|
|
22
|
+
# edition only). To publish the page, prefer gridctl_drop, not grid plug.
|
|
23
|
+
#
|
|
24
|
+
# needs: {} # none — static, no infrastructure
|
|
25
|
+
name: landing-page
|
|
26
|
+
services:
|
|
27
|
+
web:
|
|
28
|
+
type: static
|
|
29
|
+
path: /
|
|
30
|
+
```
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# static — deploys as an inspiration (instant, works on hosted) via gridctl_drop;
|
|
2
|
+
# this yaml is only for plugging it as an OWNED static runtime (async, local
|
|
3
|
+
# edition only). To publish the page, prefer gridctl_drop, not grid plug.
|
|
4
|
+
#
|
|
5
|
+
# needs: {} # none — static, no infrastructure
|
|
6
|
+
name: report
|
|
7
|
+
services:
|
|
8
|
+
web:
|
|
9
|
+
type: static
|
|
10
|
+
path: /
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Template: report (static)
|
|
2
|
+
|
|
3
|
+
A single self-contained HTML report. **No infrastructure** — no database, no backend,
|
|
4
|
+
no `needs:`. State (if any) lives only in memory and is lost on refresh.
|
|
5
|
+
|
|
6
|
+
## How it deploys
|
|
7
|
+
|
|
8
|
+
To publish this page, use **`gridctl_drop`** (or `gridctl_plug` with the inline
|
|
9
|
+
HTML): it deploys as an **inspiration** — instant, and works on the **hosted**
|
|
10
|
+
edition (Claude Web) as well as local. The reference `cloudgrid.yaml` in this
|
|
11
|
+
directory (`type: static`) is ONLY for plugging the page as an OWNED static
|
|
12
|
+
runtime (async, local edition only); the fast path is `gridctl_drop`.
|
|
13
|
+
|
|
14
|
+
The fillable HTML is the real template — fetch it with
|
|
15
|
+
`gridctl_fetch("template", "report")` and fill in the user's content.
|
|
16
|
+
|
|
17
|
+
## cloudgrid.yaml (reference only)
|
|
18
|
+
|
|
19
|
+
```yaml
|
|
20
|
+
# static — deploys as an inspiration (instant, works on hosted) via gridctl_drop;
|
|
21
|
+
# this yaml is only for plugging it as an OWNED static runtime (async, local
|
|
22
|
+
# edition only). To publish the page, prefer gridctl_drop, not grid plug.
|
|
23
|
+
#
|
|
24
|
+
# needs: {} # none — static, no infrastructure
|
|
25
|
+
name: report
|
|
26
|
+
services:
|
|
27
|
+
web:
|
|
28
|
+
type: static
|
|
29
|
+
path: /
|
|
30
|
+
```
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# static — deploys as an inspiration (instant, works on hosted) via gridctl_drop;
|
|
2
|
+
# this yaml is only for plugging it as an OWNED static runtime (async, local
|
|
3
|
+
# edition only). To publish the page, prefer gridctl_drop, not grid plug.
|
|
4
|
+
#
|
|
5
|
+
# needs: {} # none — static, no infrastructure
|
|
6
|
+
name: web-app
|
|
7
|
+
services:
|
|
8
|
+
web:
|
|
9
|
+
type: static
|
|
10
|
+
path: /
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Template: web-app (static)
|
|
2
|
+
|
|
3
|
+
A single self-contained HTML web-app. **No infrastructure** — no database, no backend,
|
|
4
|
+
no `needs:`. State (if any) lives only in memory and is lost on refresh.
|
|
5
|
+
|
|
6
|
+
## How it deploys
|
|
7
|
+
|
|
8
|
+
To publish this page, use **`gridctl_drop`** (or `gridctl_plug` with the inline
|
|
9
|
+
HTML): it deploys as an **inspiration** — instant, and works on the **hosted**
|
|
10
|
+
edition (Claude Web) as well as local. The reference `cloudgrid.yaml` in this
|
|
11
|
+
directory (`type: static`) is ONLY for plugging the page as an OWNED static
|
|
12
|
+
runtime (async, local edition only); the fast path is `gridctl_drop`.
|
|
13
|
+
|
|
14
|
+
The fillable HTML is the real template — fetch it with
|
|
15
|
+
`gridctl_fetch("template", "web-app")` and fill in the user's content.
|
|
16
|
+
|
|
17
|
+
## cloudgrid.yaml (reference only)
|
|
18
|
+
|
|
19
|
+
```yaml
|
|
20
|
+
# static — deploys as an inspiration (instant, works on hosted) via gridctl_drop;
|
|
21
|
+
# this yaml is only for plugging it as an OWNED static runtime (async, local
|
|
22
|
+
# edition only). To publish the page, prefer gridctl_drop, not grid plug.
|
|
23
|
+
#
|
|
24
|
+
# needs: {} # none — static, no infrastructure
|
|
25
|
+
name: web-app
|
|
26
|
+
services:
|
|
27
|
+
web:
|
|
28
|
+
type: static
|
|
29
|
+
path: /
|
|
30
|
+
```
|
package/src/corpus/usage.md
CHANGED
|
@@ -16,7 +16,7 @@ Which one you use depends on the client. Pick your client below.
|
|
|
16
16
|
- **Node 18+** (for `npx`).
|
|
17
17
|
- **No login needed to try it** — anonymous drop works out of the box. For owned
|
|
18
18
|
drops (into your org), run `cloudgrid login` once, or use the `login` skill / the
|
|
19
|
-
`
|
|
19
|
+
`gridctl_login` MCP tool.
|
|
20
20
|
|
|
21
21
|
---
|
|
22
22
|
|
|
@@ -45,7 +45,7 @@ npx skills add cloudgrid-io/skills
|
|
|
45
45
|
```
|
|
46
46
|
claude mcp add cloudgrid -- npx -y @cloudgrid-io/mcp
|
|
47
47
|
```
|
|
48
|
-
- **Find it under `/mcp`.** Exposes tools `
|
|
48
|
+
- **Find it under `/mcp`.** Exposes tools `gridctl_drop`, `gridctl_login`, …
|
|
49
49
|
- Invoke by describing the task; the model calls the tool.
|
|
50
50
|
|
|
51
51
|
> Where did my install go? `/skills` (skills), `/plugin` (plugin), `/mcp` (MCP).
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: app-with-data
|
|
3
|
-
when:
|
|
3
|
+
when: to-do, task list, notes app, guestbook, CRUD app, form that SAVES/STORES submissions, anything that SAVES or PERSISTS data or shares state across users/sessions, sign-in/accounts, a backend/API/database — e.g. a to-do list, a CRUD dashboard, a form that stores entries, a guestbook. Needs a database → runtime → local edition.
|
|
4
|
+
needs: database
|
|
5
|
+
deploy: runtime
|
|
6
|
+
editions: local
|
|
7
|
+
capabilities_note: persistent — needs a database (Mongo). Runtime app, async build, local edition only. Canonical need is `database: true` (metadata); the deployed yaml uses `requires: [mongodb]` until #1527 lands.
|
|
4
8
|
summary: Build a real persistent Next.js + Mongo runtime app on the grid — edition-gate first, scaffold, put the app under services/web/, wire process.env.MONGODB_URL lazily, declare requires:[mongodb] (not needs:), deploy async, poll to a live URL.
|
|
5
9
|
---
|
|
6
10
|
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: dashboard
|
|
3
|
-
when:
|
|
3
|
+
when: dashboard, metrics, KPIs, stats page, status board, charts, analytics view — display-only (static data baked in).
|
|
4
|
+
needs: none
|
|
5
|
+
deploy: inspiration
|
|
6
|
+
editions: all
|
|
7
|
+
capabilities_note: static — no infrastructure, data is baked into the page. Publishes as an inspiration (instant, works on hosted) via gridctl_drop.
|
|
4
8
|
summary: Fetch the dashboard template, fill it with the user's metrics and inline charts, deploy it, and return the live share URL.
|
|
5
9
|
---
|
|
6
10
|
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: landing-page
|
|
3
|
-
when:
|
|
3
|
+
when: landing page, marketing page, product page, hero page, coming-soon, waitlist, pricing page, portfolio, link-in-bio, event page.
|
|
4
|
+
needs: none
|
|
5
|
+
deploy: inspiration
|
|
6
|
+
editions: all
|
|
7
|
+
capabilities_note: static — no infrastructure. Publishes as an inspiration (instant, works on hosted) via gridctl_drop.
|
|
4
8
|
summary: Fetch the landing-page template, fill it with the user's content, deploy it, and return the live share URL.
|
|
5
9
|
---
|
|
6
10
|
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: presentation
|
|
3
|
-
when:
|
|
3
|
+
when: slides, deck, pitch, presentation, slideshow.
|
|
4
|
+
needs: none
|
|
5
|
+
deploy: inspiration
|
|
6
|
+
editions: all
|
|
7
|
+
capabilities_note: static — no infrastructure. Publishes as an inspiration (instant, works on hosted) via gridctl_drop.
|
|
4
8
|
summary: Fetch the deck template, fill it with the user's content, deploy it, and return the live share URL.
|
|
5
9
|
---
|
|
6
10
|
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: report
|
|
3
|
-
when:
|
|
3
|
+
when: report, one-pager, summary, brief, whitepaper, case study, formatted document.
|
|
4
|
+
needs: none
|
|
5
|
+
deploy: inspiration
|
|
6
|
+
editions: all
|
|
7
|
+
capabilities_note: static — no infrastructure. Publishes as an inspiration (instant, works on hosted) via gridctl_drop.
|
|
4
8
|
summary: Fetch the report template, fill it with the user's content, deploy it, and return the live share URL.
|
|
5
9
|
---
|
|
6
10
|
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: web-app
|
|
3
|
-
when:
|
|
3
|
+
when: calculator, converter, generator, timer, quiz, interactive tool, mini-app, single-page tool, widget — anything computed client-side with no saved data.
|
|
4
|
+
needs: none
|
|
5
|
+
deploy: inspiration
|
|
6
|
+
editions: all
|
|
7
|
+
capabilities_note: static — no infrastructure, state lives only in memory. Publishes as an inspiration (instant, works on hosted) via gridctl_drop.
|
|
4
8
|
summary: Fetch the web-app template, adapt its markup and inline JS to the user's tool, deploy it, and return the live share URL.
|
|
5
9
|
---
|
|
6
10
|
|
package/src/tools.js
CHANGED
|
@@ -89,6 +89,7 @@ Operating rules:
|
|
|
89
89
|
9. To modify an existing drop when you don't already have its HTML in context, first call gridctl_source to fetch the current HTML, apply your change, then call gridctl_drop/gridctl_plug with target_entity_id (the drop's entity_id) to update the SAME URL in place. Do not ask the user to paste the HTML back.
|
|
90
90
|
10. Publishing a heavy or local file: in the local edition use the path parameter so it is read from disk (no inline size limit); never base64-encode HTML and never pass a file path (or an @-prefixed path) as html. If a drop looks empty, use gridctl_source to check what was actually published, then re-plug with the real HTML/path and target_entity_id.
|
|
91
91
|
11. Persistence check: if the user needs to SAVE data, share state across users/sessions, log in, or store submissions, that's a runtime app-with-data (Mongo-backed), NOT a static page — static templates keep state only in memory and lose it on refresh. Use the app-with-data workflow. This requires the LOCAL edition (Claude Desktop/Code or the CLI); on the hosted edition, tell the user persistence isn't available there and offer a static version.
|
|
92
|
+
12. To choose what to build: match the request against the workflow when: triggers and the capability-map (gridctl_fetch({kind:"doc", name:"capability-map"})). Pick the template whose needs: matches what the app requires (persistence → database; scheduled → cron; etc.). Static (needs: none) deploys as an inspiration (instant, any edition); anything needing needs: is a runtime (async, local edition).
|
|
92
93
|
|
|
93
94
|
Deploy is edition-dependent: on the hosted MCP call the drop tool with the HTML; on local MCP / CLI write the file and run the plug tool. An HTML page deploys synchronously, so you get a URL right away.`;
|
|
94
95
|
|
|
@@ -226,30 +227,30 @@ const MIN_CLI_VERSION = "0.12.0";
|
|
|
226
227
|
// Verb map for the drift guard: each CLI-wrapping tool's top-level verb(s).
|
|
227
228
|
// The drift-guard test imports this and asserts every verb exists in `cloudgrid --help`.
|
|
228
229
|
export const CLI_TOOL_VERBS = {
|
|
229
|
-
|
|
230
|
-
//
|
|
230
|
+
gridctl_init: ["init"],
|
|
231
|
+
// gridctl_plug is NOT here: gridctl_plug is now a direct-API tool
|
|
231
232
|
// (POST /api/v2/plug, spec v2 §3), not a CLI wrapper.
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
233
|
+
gridctl_logs: ["logs"],
|
|
234
|
+
gridctl_share: ["visibility"],
|
|
235
|
+
gridctl_feedback: ["feedback"],
|
|
236
|
+
gridctl_whoami: ["whoami"],
|
|
237
|
+
gridctl_use: ["use"],
|
|
238
|
+
gridctl_logout: ["logout"],
|
|
239
|
+
gridctl_status: ["status"],
|
|
240
|
+
gridctl_info: ["info"],
|
|
241
|
+
gridctl_get: ["get"],
|
|
242
|
+
gridctl_describe_grid: ["describe"],
|
|
243
|
+
gridctl_pickup: ["pickup"],
|
|
244
|
+
gridctl_rename: ["rename"],
|
|
245
|
+
gridctl_unplug: ["unplug"],
|
|
246
|
+
gridctl_delete: ["delete"],
|
|
247
|
+
gridctl_rollback: ["rollback"],
|
|
248
|
+
gridctl_versions: ["versions"],
|
|
249
|
+
gridctl_env: ["env"],
|
|
250
|
+
gridctl_secrets: ["secrets"],
|
|
251
|
+
gridctl_scaffold: ["scaffold"],
|
|
252
|
+
gridctl_doctor: ["doctor"],
|
|
253
|
+
gridctl_open: ["open"],
|
|
253
254
|
};
|
|
254
255
|
|
|
255
256
|
// Simple semver comparison: true when `version` >= MIN_CLI_VERSION.
|
|
@@ -2356,34 +2357,19 @@ export async function runSource(ctx, { entity_id, url, grid, slug } = {}) {
|
|
|
2356
2357
|
// Registers the tools onto `server`. ctx.edition decides whether the CLI-wrapping
|
|
2357
2358
|
// tools are included (they need a local machine).
|
|
2358
2359
|
export function registerTools(server, ctx) {
|
|
2359
|
-
// ── Tool naming: gridctl_*
|
|
2360
|
-
// Every tool is registered under its
|
|
2361
|
-
// `cloudgrid_*`
|
|
2362
|
-
//
|
|
2363
|
-
//
|
|
2360
|
+
// ── Tool naming: gridctl_* only ───────────────────────────────────────────
|
|
2361
|
+
// Every tool is registered under its `gridctl_*` name only. The legacy
|
|
2362
|
+
// deprecated `cloudgrid_*` aliases were removed in 0.10.0 — they doubled the
|
|
2363
|
+
// connector tool list and de-duplicated poorly in permission UIs. Clients
|
|
2364
|
+
// enumerate tools dynamically, so discovery is unaffected. `reg` wraps the
|
|
2364
2365
|
// object-config `server.registerTool`; `regTool` wraps the positional
|
|
2365
|
-
// `server.tool` shorthand.
|
|
2366
|
-
// alias by swapping the prefix.
|
|
2367
|
-
const aliasOf = (name) => name.replace(/^gridctl_/, "cloudgrid_");
|
|
2368
|
-
|
|
2366
|
+
// `server.tool` shorthand.
|
|
2369
2367
|
const reg = (name, config, handler) => {
|
|
2370
2368
|
server.registerTool(name, config, handler);
|
|
2371
|
-
const alias = aliasOf(name);
|
|
2372
|
-
if (alias !== name) {
|
|
2373
|
-
server.registerTool(
|
|
2374
|
-
alias,
|
|
2375
|
-
{ ...config, description: `(deprecated: use ${name}) ${config.description}` },
|
|
2376
|
-
handler,
|
|
2377
|
-
);
|
|
2378
|
-
}
|
|
2379
2369
|
};
|
|
2380
2370
|
|
|
2381
2371
|
const regTool = (name, description, schema, annotations, handler) => {
|
|
2382
2372
|
server.tool(name, description, schema, annotations, handler);
|
|
2383
|
-
const alias = aliasOf(name);
|
|
2384
|
-
if (alias !== name) {
|
|
2385
|
-
server.tool(alias, `(deprecated: use ${name}) ${description}`, schema, annotations, handler);
|
|
2386
|
-
}
|
|
2387
2373
|
};
|
|
2388
2374
|
|
|
2389
2375
|
// ── Widget resources (web edition, ChatGPT Apps SDK) ──────────────────────
|
|
@@ -124,7 +124,7 @@ body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;b
|
|
|
124
124
|
var statusEl = document.getElementById("vis-status");
|
|
125
125
|
if (statusEl) statusEl.textContent = "Updating\u2026";
|
|
126
126
|
if (!window.openai || !window.openai.callTool) return;
|
|
127
|
-
window.openai.callTool("
|
|
127
|
+
window.openai.callTool("gridctl_visibility", { visibility: vis }).then(function (res) {
|
|
128
128
|
var newVis = res && res.structuredContent && res.structuredContent.visibility;
|
|
129
129
|
if (newVis) {
|
|
130
130
|
data.current_visibility = newVis;
|
|
@@ -75,7 +75,7 @@ body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;b
|
|
|
75
75
|
if (input.fresh !== undefined) args.fresh = input.fresh;
|
|
76
76
|
args.grid = slug;
|
|
77
77
|
args.org = slug; // alias kept for compatibility
|
|
78
|
-
window.openai.callTool("
|
|
78
|
+
window.openai.callTool("gridctl_drop", args).then(function () {
|
|
79
79
|
// The host will render the new result with the live-result card.
|
|
80
80
|
}).catch(function () {
|
|
81
81
|
for (var m = 0; m < all.length; m++) all[m].classList.remove("loading");
|