@groundfloorcloud/mcp 0.1.0 → 0.1.2
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 +38 -3
- package/dist/index.js +212 -17
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,6 +22,8 @@ Switch workspace: `gf workspaces use <uuid>` (then MCP sees it). Expired session
|
|
|
22
22
|
|
|
23
23
|
`gf` must be on `PATH` and you must have run `gf login` (and usually `gf workspaces use`).
|
|
24
24
|
|
|
25
|
+
Clients that spawn a real Node (Claude Code, some IDEs) can use:
|
|
26
|
+
|
|
25
27
|
```json
|
|
26
28
|
{
|
|
27
29
|
"mcpServers": {
|
|
@@ -33,7 +35,28 @@ Switch workspace: `gf workspaces use <uuid>` (then MCP sees it). Expired session
|
|
|
33
35
|
}
|
|
34
36
|
```
|
|
35
37
|
|
|
36
|
-
|
|
38
|
+
**Cursor on macOS:** do not use bare `npx`. Cursor runs npm with its bundled Node, which then looks for `Cursor.app/.../resources/lib` and fails with `ENOENT`. Install the package with *your* Node, then point MCP at that binary:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm i -g @groundfloorcloud/mcp
|
|
42
|
+
which node
|
|
43
|
+
# → /Users/you/.nvm/versions/node/v20.x.x/bin/node
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"mcpServers": {
|
|
49
|
+
"groundfloor": {
|
|
50
|
+
"command": "/FULL/PATH/TO/node",
|
|
51
|
+
"args": [
|
|
52
|
+
"/FULL/PATH/TO/lib/node_modules/@groundfloorcloud/mcp/dist/index.js"
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The `command` must be your Node (from `which node`), not `npx` and not Cursor’s helper Node. Do not put a JWT in mcp.json.
|
|
37
60
|
|
|
38
61
|
## Tools
|
|
39
62
|
|
|
@@ -44,11 +67,23 @@ Optional: `"GROUNDFLOOR_API_URL"` only if you are not using the cell from `gf lo
|
|
|
44
67
|
| `coderunner_list` / `_get_status` / `_get_logs` | Inspect workloads |
|
|
45
68
|
| `apps_list` / `apps_get` | Inspect product Apps |
|
|
46
69
|
| `secrets_list` / `files_list` / `domains_list` / `dataplane_status` | Inspect (no secrets values) |
|
|
47
|
-
| `docs_list` / `docs_get` | Product docs |
|
|
48
|
-
| `suggest_cli` | Command to run: login, deploy,
|
|
70
|
+
| `docs_list` / `docs_get` | Product docs (`coderunner` returns the full type/auth/Dockerfile guide) |
|
|
71
|
+
| `suggest_cli` | Command to run: login, deploy, init_app, publish_app, … |
|
|
49
72
|
|
|
50
73
|
Never create `app_kind=coderunner`. Deploy with `gf deploy`.
|
|
51
74
|
|
|
75
|
+
**Coderunner how-to** is embedded: `docs_get` id `coderunner` (also
|
|
76
|
+
`coderunner-overview`). That page covers:
|
|
77
|
+
|
|
78
|
+
- Types: `function`, `job`, `schedule`, `service` (**also called Deployment**)
|
|
79
|
+
- **Authentication must be active** before creating a coderunner
|
|
80
|
+
- **Dockerfile is required** for `service` / Deployment
|
|
81
|
+
- Node `scripts.start` + listen on 8080
|
|
82
|
+
- Local development against live vault/files/secrets (`gf env` + `gf token`)
|
|
83
|
+
|
|
84
|
+
`workspace_context` includes a `coderunner_howto` summary so agents see this
|
|
85
|
+
without an extra fetch.
|
|
86
|
+
|
|
52
87
|
## Build (from this repo)
|
|
53
88
|
|
|
54
89
|
```bash
|
package/dist/index.js
CHANGED
|
@@ -296,17 +296,20 @@ var CELLS = {
|
|
|
296
296
|
production: {
|
|
297
297
|
apiUrl: "https://platform.groundfloor.cloud",
|
|
298
298
|
issuer: "https://auth.groundfloor.cloud/realms/groundfloor",
|
|
299
|
-
clientId: "groundfloor-cli"
|
|
299
|
+
clientId: "groundfloor-cli",
|
|
300
|
+
consoleUrl: "https://console.groundfloor.cloud"
|
|
300
301
|
},
|
|
301
302
|
stage: {
|
|
302
303
|
apiUrl: "https://platform.stage.groundfloor.cloud",
|
|
303
304
|
issuer: "https://auth.stage.groundfloor.cloud/realms/groundfloor_pico_stage-realm",
|
|
304
|
-
clientId: "groundfloor-cli"
|
|
305
|
+
clientId: "groundfloor-cli",
|
|
306
|
+
consoleUrl: "https://console.stage.groundfloor.cloud"
|
|
305
307
|
},
|
|
306
308
|
dev: {
|
|
307
309
|
apiUrl: "https://platform.dev.groundfloor.cloud",
|
|
308
310
|
issuer: "https://auth.dev.groundfloor.cloud/realms/groundfloor_dev",
|
|
309
|
-
clientId: "groundfloor-cli"
|
|
311
|
+
clientId: "groundfloor-cli",
|
|
312
|
+
consoleUrl: "https://console.dev.groundfloor.cloud"
|
|
310
313
|
}
|
|
311
314
|
};
|
|
312
315
|
function inferCell(apiUrl, issuer) {
|
|
@@ -377,6 +380,143 @@ async function resolveMcpConfig(overrides) {
|
|
|
377
380
|
return { apiUrl, workspaceId, token };
|
|
378
381
|
}
|
|
379
382
|
|
|
383
|
+
// src/coderunner-guide.ts
|
|
384
|
+
var CODERUNNER_GUIDE = `
|
|
385
|
+
# Coderunner workloads
|
|
386
|
+
|
|
387
|
+
Coderunner is Groundfloor's **apps runtime**. Deploy Node.js, Python, .NET, and
|
|
388
|
+
other workloads as **functions**, **jobs**, **schedules**, or **services**.
|
|
389
|
+
The Customer Portal, \`gf\` CLI, and this MCP all drive the same lifecycle.
|
|
390
|
+
|
|
391
|
+
Do **not** create an App to run code. \`POST \u2026/apps\` with \`app_kind=coderunner\`
|
|
392
|
+
is rejected. Optional Apps are Shell / product packaging only.
|
|
393
|
+
|
|
394
|
+
## Prerequisites (do these before create/deploy)
|
|
395
|
+
|
|
396
|
+
1. **Workspace Authentication is required** before creating a coderunner.
|
|
397
|
+
Portal \u2192 Administer \u2192 Authentication \u2192 set mode to \`groundfloor\` (or
|
|
398
|
+
\`external\` with an issuer) and wait until the realm is **active**.
|
|
399
|
+
Code Runner JWTs use the workspace site issuer. Mode \`none\` cannot mint
|
|
400
|
+
that token \u2014 create/deploy fails with "requires the workspace site issuer".
|
|
401
|
+
2. \`gf login\` (\`--stage\` / \`--dev\` as needed) and \`gf workspaces use <uuid>\`.
|
|
402
|
+
3. Dataplane for vault/files/secrets: \`gf dataplane provision\` if those APIs
|
|
403
|
+
are needed (local live data or the deployed workload).
|
|
404
|
+
|
|
405
|
+
## Workload types
|
|
406
|
+
|
|
407
|
+
Portal \`workload_type\` (CLI \`--workload-type\` / \`groundfloor.json\`
|
|
408
|
+
\`workloadType\`) maps to upstream \`deploymentType\`. **Service and Deployment
|
|
409
|
+
are the same type** \u2014 portal id \`service\`, UI often says Deployment,
|
|
410
|
+
upstream \`deploymentType=4\`.
|
|
411
|
+
|
|
412
|
+
| Portal id | Also called | Upstream | When to use | How it runs |
|
|
413
|
+
|-----------|-------------|----------|-------------|-------------|
|
|
414
|
+
| \`function\` | Function | 1 | Request/response HTTP handler (webhooks, APIs, agent invoke) | Scale-to-zero Knative. Invoke via Run or Deployment URL. |
|
|
415
|
+
| \`job\` | Background job | 2 | One-shot batch (import, report, backfill) | Run-to-completion. Deploy, then \`gf coderunner run\`. |
|
|
416
|
+
| \`schedule\` | Scheduled job | 3 | Cron (reminders, sync) | Same as job, plus cron. **No** public Deployment URL. |
|
|
417
|
+
| \`service\` | **Deployment** | 4 | Long-running HTTP process (web app, always-on API) | Stays up (replicas). Public Deployment URL. Custom domains when App-bound. |
|
|
418
|
+
|
|
419
|
+
Pick **one** type per coderunner. Changing type later means a new coderunner.
|
|
420
|
+
|
|
421
|
+
### Function
|
|
422
|
+
|
|
423
|
+
- ZIP at archive root (\`package.json\` / \`index.js\` or \`main.py\` not nested).
|
|
424
|
+
- Listen on \`process.env.PORT || 8080\` (health GET \`/\` or \`/health\`).
|
|
425
|
+
- **Node:** \`package.json\` **must** include \`"scripts": { "start": "node index.js" }\`.
|
|
426
|
+
The runtime image is \`CMD ["npm", "start"]\`. Missing \`start\` \u2192 crash loop,
|
|
427
|
+
probe \`127.0.0.1:8080\` connection refused, deployment **Failed (status 4)**.
|
|
428
|
+
- Python: process must bind 0.0.0.0:\${PORT:-8080}.
|
|
429
|
+
- After deploy: \`gf coderunner run -c <slug> --payload '{"hello":"world"}'\`.
|
|
430
|
+
|
|
431
|
+
### Job
|
|
432
|
+
|
|
433
|
+
- Same package rules as function. No need to serve forever; exit 0 on success.
|
|
434
|
+
- Deploy, then start a run (\`gf coderunner run\`). Check Process Log.
|
|
435
|
+
|
|
436
|
+
### Schedule
|
|
437
|
+
|
|
438
|
+
- Same as job, plus a cron expression at create/deploy (\`schedule\` /
|
|
439
|
+
\`CronExpression\`).
|
|
440
|
+
- No public invoke URL. Debug with Process Log, not curl.
|
|
441
|
+
|
|
442
|
+
### Service (Deployment)
|
|
443
|
+
|
|
444
|
+
- Long-running HTTP. **You must include a \`Dockerfile\` at the ZIP root.**
|
|
445
|
+
Kaniko builds with \`--dockerfile=Dockerfile\`. Language bootstrap does **not**
|
|
446
|
+
replace a missing Dockerfile for this type.
|
|
447
|
+
- Dockerfile must expose and listen on **8080** (or \`PORT\`).
|
|
448
|
+
- Node example:
|
|
449
|
+
|
|
450
|
+
\`\`\`dockerfile
|
|
451
|
+
FROM node:18-alpine
|
|
452
|
+
WORKDIR /app
|
|
453
|
+
COPY package*.json ./
|
|
454
|
+
RUN npm ci --omit=dev
|
|
455
|
+
COPY . .
|
|
456
|
+
EXPOSE 8080
|
|
457
|
+
ENV PORT=8080
|
|
458
|
+
CMD ["npm", "start"]
|
|
459
|
+
\`\`\`
|
|
460
|
+
|
|
461
|
+
- Still require Node \`"start"\` if CMD is \`npm start\`.
|
|
462
|
+
- Prefer curling the Deployment URL (\`/health\`) over \`\u2026/run\`.
|
|
463
|
+
|
|
464
|
+
## Latest deploy rules (all types)
|
|
465
|
+
|
|
466
|
+
- \`gf deploy\` from the project dir (or \`--path\` / \`--git\`). Creates the
|
|
467
|
+
coderunner if the slug is new; otherwise uploads a new version and deploys it.
|
|
468
|
+
- Status: upload/build \`1\u20134\` (3=Completed, 4=Failed). Deployment \`1\u20137\`
|
|
469
|
+
(3=Deployed, 4=Failed). A templated \`deployment_url\` with empty
|
|
470
|
+
\`externalEndpoint\` and status 4 means the container never became ready \u2014
|
|
471
|
+
read Process Log (\`runner_id\` = deployment id).
|
|
472
|
+
- Strip \`.env*\`, \`.git\`, \`node_modules\` from ZIPs. Put secrets in
|
|
473
|
+
\`gf secrets\` / deploy \`-e\`, never in the archive.
|
|
474
|
+
- Zip **contents** at root, not a wrapping folder.
|
|
475
|
+
- Optional \`groundfloor.json\`: \`name\`, \`runtime\`, \`workloadType\`,
|
|
476
|
+
\`cpu\`, \`memory\`, \`env\`.
|
|
477
|
+
|
|
478
|
+
## Local development with live workspace data
|
|
479
|
+
|
|
480
|
+
Run the process on your laptop; call the **same** Control Plane + Dataplane
|
|
481
|
+
the deployed coderunner uses. Do not copy production data into fixtures.
|
|
482
|
+
|
|
483
|
+
\`\`\`bash
|
|
484
|
+
gf login --stage # or --dev / production
|
|
485
|
+
gf workspaces use <uuid>
|
|
486
|
+
eval "$(gf env)" # GROUNDFLOOR_TOKEN, CONTROLPLANE_URL, GROUNDFLOOR_WORKSPACE_ID
|
|
487
|
+
gf dataplane status # provision if needed: gf dataplane provision
|
|
488
|
+
gf secrets ls
|
|
489
|
+
\`\`\`
|
|
490
|
+
|
|
491
|
+
Local HTTP (Node function/service):
|
|
492
|
+
|
|
493
|
+
\`\`\`bash
|
|
494
|
+
export PORT=8080
|
|
495
|
+
npm start # same entrypoint as production
|
|
496
|
+
# other terminal:
|
|
497
|
+
curl -sS -X POST http://127.0.0.1:8080/ -H 'Content-Type: application/json' \\
|
|
498
|
+
-d '{"hello":"local"}'
|
|
499
|
+
\`\`\`
|
|
500
|
+
|
|
501
|
+
Live vault / files / secrets from the laptop:
|
|
502
|
+
|
|
503
|
+
\`\`\`bash
|
|
504
|
+
curl -sS -H "Authorization: Bearer $(gf token)" \\
|
|
505
|
+
"$CONTROLPLANE_URL/v1/workspaces/$GROUNDFLOOR_WORKSPACE_ID/vault/collections"
|
|
506
|
+
\`\`\`
|
|
507
|
+
|
|
508
|
+
In app code, use \`CONTROLPLANE_URL\` + Bearer (\`gf token\` locally;
|
|
509
|
+
injected env / workspace secrets after \`gf deploy\`). Never put
|
|
510
|
+
\`DATAPLANE_SERVICE_API_KEY\` in a browser bundle.
|
|
511
|
+
|
|
512
|
+
When the handler looks right locally, \`gf deploy\` the same tree.
|
|
513
|
+
|
|
514
|
+
## Agent actions
|
|
515
|
+
|
|
516
|
+
Inspect: \`workspace_context\`, \`docs_get\` id \`coderunner\`, \`suggest_cli\`.
|
|
517
|
+
Act: \`gf deploy\`, \`gf coderunner run|status\`. MCP does not deploy.
|
|
518
|
+
`.trim();
|
|
519
|
+
|
|
380
520
|
// src/docs.ts
|
|
381
521
|
var DOCS_ORIGIN = "https://docs.groundfloor.cloud";
|
|
382
522
|
var DOC_CATALOG = [
|
|
@@ -384,22 +524,36 @@ var DOC_CATALOG = [
|
|
|
384
524
|
id: "agents",
|
|
385
525
|
title: "Deploy with agents",
|
|
386
526
|
path: "/docs/customer-portal/agents",
|
|
387
|
-
summary: "How agents should deploy Coderunner workloads with gf / MCP."
|
|
527
|
+
summary: "How agents should deploy Coderunner workloads and init/publish Shell apps with gf / MCP. Enable workspace Authentication before create. Service (Deployment) requires a Dockerfile."
|
|
388
528
|
},
|
|
389
529
|
{
|
|
390
530
|
id: "developers",
|
|
391
531
|
title: "Developers (gf CLI)",
|
|
392
532
|
path: "/docs/customer-portal/developers",
|
|
393
|
-
summary: "gf login, workspaces, deploy, secrets, files, apps."
|
|
533
|
+
summary: "gf login, workspaces, deploy, secrets, files, apps. Coderunner types: function, job, schedule, service (also called Deployment)."
|
|
394
534
|
},
|
|
395
535
|
{
|
|
396
536
|
id: "coderunner",
|
|
397
537
|
title: "Coderunner",
|
|
398
538
|
path: "/docs/customer-portal/coderunner",
|
|
399
|
-
summary: "
|
|
539
|
+
summary: "Workload types (function, job, schedule, service/Deployment), Dockerfile for services, Authentication before create, local live data, gf deploy.",
|
|
540
|
+
embedded: CODERUNNER_GUIDE
|
|
541
|
+
},
|
|
542
|
+
{
|
|
543
|
+
id: "coderunner-overview",
|
|
544
|
+
title: "Coderunner overview",
|
|
545
|
+
path: "/docs/integrations/coderunner/overview",
|
|
546
|
+
summary: "Architecture and lifecycle. Prefer docs_get id coderunner for type usage, Dockerfile, and auth prerequisites.",
|
|
547
|
+
embedded: CODERUNNER_GUIDE
|
|
400
548
|
},
|
|
401
549
|
{
|
|
402
550
|
id: "authentication",
|
|
551
|
+
title: "Workspace Authentication",
|
|
552
|
+
path: "/docs/customer-portal/authentication",
|
|
553
|
+
summary: "Workspace site auth (Groundfloor or external) must be active before creating a Coderunner. Separate from portal Members & Roles."
|
|
554
|
+
},
|
|
555
|
+
{
|
|
556
|
+
id: "api-authentication",
|
|
403
557
|
title: "API authentication",
|
|
404
558
|
path: "/docs/api/authentication",
|
|
405
559
|
summary: "Control Plane Bearer tokens and workspace identity."
|
|
@@ -418,7 +572,7 @@ function findDoc(query) {
|
|
|
418
572
|
const q = query.trim().toLowerCase();
|
|
419
573
|
if (!q) return DOC_CATALOG;
|
|
420
574
|
return DOC_CATALOG.filter((d) => {
|
|
421
|
-
const hay = `${d.id} ${d.title} ${d.summary} ${d.path}`.toLowerCase();
|
|
575
|
+
const hay = `${d.id} ${d.title} ${d.summary} ${d.path} ${d.embedded ?? ""}`.toLowerCase();
|
|
422
576
|
return q.split(/\s+/).every((part) => hay.includes(part));
|
|
423
577
|
});
|
|
424
578
|
}
|
|
@@ -429,6 +583,15 @@ function htmlToText(html) {
|
|
|
429
583
|
var MAX_CHARS = 12e3;
|
|
430
584
|
async function fetchDocPage(entry) {
|
|
431
585
|
const url = docUrl(entry);
|
|
586
|
+
if (entry.embedded?.trim()) {
|
|
587
|
+
return {
|
|
588
|
+
url,
|
|
589
|
+
title: entry.title,
|
|
590
|
+
text: entry.embedded.trim(),
|
|
591
|
+
truncated: false,
|
|
592
|
+
source: "embedded"
|
|
593
|
+
};
|
|
594
|
+
}
|
|
432
595
|
const res = await fetch(url, {
|
|
433
596
|
headers: { Accept: "text/html", "User-Agent": "groundfloor-mcp/0.1" },
|
|
434
597
|
redirect: "follow"
|
|
@@ -441,7 +604,13 @@ async function fetchDocPage(entry) {
|
|
|
441
604
|
const truncated = body.length > MAX_CHARS;
|
|
442
605
|
if (truncated) body = `${body.slice(0, MAX_CHARS)}
|
|
443
606
|
\u2026`;
|
|
444
|
-
return {
|
|
607
|
+
return {
|
|
608
|
+
url,
|
|
609
|
+
title: entry.title,
|
|
610
|
+
text: body,
|
|
611
|
+
truncated,
|
|
612
|
+
source: "docs.groundfloor.cloud"
|
|
613
|
+
};
|
|
445
614
|
}
|
|
446
615
|
|
|
447
616
|
// src/playbook.ts
|
|
@@ -464,7 +633,7 @@ function suggestCli(intent, args) {
|
|
|
464
633
|
case "deploy":
|
|
465
634
|
return {
|
|
466
635
|
command: name ? `gf deploy -n ${name}${ws}` : `gf deploy${ws}`,
|
|
467
|
-
why: "Package the current (or --path) folder and deploy as a Coderunner. Do not create an App for this.",
|
|
636
|
+
why: "Package the current (or --path) folder and deploy as a Coderunner. Workspace Authentication (groundfloor/external) must already be active. workloadType function|job|schedule|service (service = Deployment; requires a Dockerfile). Node needs package.json scripts.start. Do not create an App for this.",
|
|
468
637
|
docs: "https://docs.groundfloor.cloud/docs/customer-portal/coderunner"
|
|
469
638
|
};
|
|
470
639
|
case "run":
|
|
@@ -479,10 +648,18 @@ function suggestCli(intent, args) {
|
|
|
479
648
|
why: "Inspect build/deploy state.",
|
|
480
649
|
docs: "https://docs.groundfloor.cloud/docs/customer-portal/coderunner"
|
|
481
650
|
};
|
|
651
|
+
case "init_app": {
|
|
652
|
+
const slug = args?.slug?.trim();
|
|
653
|
+
return {
|
|
654
|
+
command: slug ? `gf apps init --slug ${slug}` : "gf apps init --slug <portal-slug>",
|
|
655
|
+
why: "Download the official Shell starter-kit and stamp APP_ID. Never scaffold a federated App.tsx from memory \u2014 BrowserRouter in App.tsx crashes the Shell.",
|
|
656
|
+
docs: "https://docs.groundfloor.cloud/docs/integrations/shell"
|
|
657
|
+
};
|
|
658
|
+
}
|
|
482
659
|
case "publish_app":
|
|
483
660
|
return {
|
|
484
|
-
command: "gf apps publish --path release.zip",
|
|
485
|
-
why: "Ship a Shell federated product App (not
|
|
661
|
+
command: args?.slug ? `gf apps init --slug ${args.slug} && cd ${args.slug} && npm install && npm run release && gf apps publish --path release.zip` : "gf apps init --slug <portal-slug> && cd <slug> && npm install && npm run release && gf apps publish --path release.zip",
|
|
662
|
+
why: "Ship a Shell federated product App. Init the starter-kit first; run npm run release (do not zip Vite dist/). Do not gf deploy and do not invent App.tsx.",
|
|
486
663
|
docs: "https://docs.groundfloor.cloud/docs/integrations/shell"
|
|
487
664
|
};
|
|
488
665
|
case "secrets":
|
|
@@ -500,7 +677,7 @@ function suggestCli(intent, args) {
|
|
|
500
677
|
default:
|
|
501
678
|
return {
|
|
502
679
|
command: "gf --help",
|
|
503
|
-
why: `Unknown intent "${intent}". Use login | switch_workspace | deploy | run | status | publish_app | secrets | dataplane.`,
|
|
680
|
+
why: `Unknown intent "${intent}". Use login | switch_workspace | deploy | run | status | init_app | publish_app | secrets | dataplane.`,
|
|
504
681
|
docs: "https://docs.groundfloor.cloud/docs/customer-portal/developers"
|
|
505
682
|
};
|
|
506
683
|
}
|
|
@@ -571,7 +748,7 @@ server.tool(
|
|
|
571
748
|
);
|
|
572
749
|
server.tool(
|
|
573
750
|
"workspace_context",
|
|
574
|
-
"Live context for the selected workspace: session, coderunners, apps, dataplane,
|
|
751
|
+
"Live context for the selected workspace: session, coderunners, apps, dataplane, suggested gf commands, and Coderunner type/auth/Dockerfile rules. Use docs_get id coderunner for the full how-to.",
|
|
575
752
|
{ workspace_id: wsId },
|
|
576
753
|
async ({ workspace_id }) => {
|
|
577
754
|
try {
|
|
@@ -602,6 +779,18 @@ server.tool(
|
|
|
602
779
|
status: app.status
|
|
603
780
|
})),
|
|
604
781
|
dataplane,
|
|
782
|
+
coderunner_howto: {
|
|
783
|
+
docs_get: "coderunner",
|
|
784
|
+
before_create: "Enable Administer \u2192 Authentication (mode groundfloor or external, realm active). Mode none cannot mint a Code Runner JWT.",
|
|
785
|
+
types: {
|
|
786
|
+
function: "HTTP handler on PORT/8080. Invoke with gf coderunner run or the Deployment URL. Node requires package.json scripts.start.",
|
|
787
|
+
job: "Run-to-completion worker. Deploy, then gf coderunner run.",
|
|
788
|
+
schedule: "Cron job. No public Deployment URL. Set schedule/cron at create or deploy.",
|
|
789
|
+
service: "Long-running Deployment (same type as service). Dockerfile at ZIP root is required. Listen on 8080."
|
|
790
|
+
},
|
|
791
|
+
node: 'Bootstrap image uses CMD ["npm","start"]. Missing scripts.start \u2192 deploy Failed (status 4), 8080 connection refused.',
|
|
792
|
+
local_live_data: 'eval "$(gf env)" then call Control Plane vault/files/secrets with Bearer $(gf token). Do not zip .env files.'
|
|
793
|
+
},
|
|
605
794
|
actions: {
|
|
606
795
|
deploy: suggestCli("deploy"),
|
|
607
796
|
switch_workspace: suggestCli("switch_workspace"),
|
|
@@ -610,7 +799,8 @@ server.tool(
|
|
|
610
799
|
docs: DOC_CATALOG.map((d) => ({
|
|
611
800
|
id: d.id,
|
|
612
801
|
title: d.title,
|
|
613
|
-
url: `https://docs.groundfloor.cloud${d.path}
|
|
802
|
+
url: `https://docs.groundfloor.cloud${d.path}`,
|
|
803
|
+
summary: d.summary
|
|
614
804
|
}))
|
|
615
805
|
});
|
|
616
806
|
} catch (e) {
|
|
@@ -808,9 +998,11 @@ server.tool(
|
|
|
808
998
|
);
|
|
809
999
|
server.tool(
|
|
810
1000
|
"docs_get",
|
|
811
|
-
"
|
|
1001
|
+
"How-to for Coderunner types, Dockerfile, Authentication, local live data, gf CLI, Shell. Pass id from docs_list (coderunner, coderunner-overview, agents, developers, authentication, api-authentication, shell). Prefer id coderunner before deploying.",
|
|
812
1002
|
{
|
|
813
|
-
id: z.string().min(1).describe(
|
|
1003
|
+
id: z.string().min(1).describe(
|
|
1004
|
+
"Catalog id, e.g. coderunner | coderunner-overview | agents | developers | authentication | api-authentication | shell"
|
|
1005
|
+
)
|
|
814
1006
|
},
|
|
815
1007
|
async ({ id }) => {
|
|
816
1008
|
try {
|
|
@@ -838,12 +1030,14 @@ server.tool(
|
|
|
838
1030
|
"deploy",
|
|
839
1031
|
"run",
|
|
840
1032
|
"status",
|
|
1033
|
+
"init_app",
|
|
841
1034
|
"publish_app",
|
|
842
1035
|
"secrets",
|
|
843
1036
|
"dataplane"
|
|
844
1037
|
]),
|
|
845
1038
|
workspace: z.string().optional(),
|
|
846
1039
|
name: z.string().optional().describe("Coderunner name/id for deploy/run/status"),
|
|
1040
|
+
slug: z.string().optional().describe("Portal app slug for init_app / publish_app"),
|
|
847
1041
|
cell: z.enum(["production", "stage", "dev"]).optional()
|
|
848
1042
|
},
|
|
849
1043
|
async (args) => {
|
|
@@ -852,7 +1046,8 @@ server.tool(
|
|
|
852
1046
|
workspace: args.workspace ?? "",
|
|
853
1047
|
name: args.name ?? "",
|
|
854
1048
|
coderunner: args.name ?? "",
|
|
855
|
-
cell: args.cell ?? ""
|
|
1049
|
+
cell: args.cell ?? "",
|
|
1050
|
+
slug: args.slug ?? ""
|
|
856
1051
|
})
|
|
857
1052
|
);
|
|
858
1053
|
}
|