@groundfloorcloud/mcp 0.1.15 → 0.1.16

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 (2) hide show
  1. package/dist/index.js +64 -61
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -446,14 +446,38 @@ async function resolveMcpConfig(overrides) {
446
446
 
447
447
  // src/coderunner-runtime.ts
448
448
  var CODERUNNER_RUNTIME_BODY = `
449
- When a ZIP has **no Dockerfile**, Coderunner injects a language bootstrap image.
450
- Your process must match that image \u2014 \`gf deploy\` checks the Node bits before
451
- upload. A custom Dockerfile (required for \`service\` / Deployment) replaces
452
- the bootstrap; the listen/bind rules still apply.
449
+ The contract depends on the workload type.
453
450
 
454
- ## Node (no Dockerfile)
451
+ | Type | Entrypoint (no Dockerfile) | Needs |
452
+ |---|---|---|
453
+ | \`function\`, \`job\`, \`schedule\` | Generated \`/app/main.js\` that does \`require('./handler')\` | Root \`handler.js\` exporting \`handler\` |
454
+ | \`service\` (Deployment) | Your Dockerfile \`CMD\` (Dockerfile required) | \`npm start\` / \`PORT\` / bind \`0.0.0.0\` if CMD is \`npm start\` |
455
455
 
456
- Bootstrap is effectively:
456
+ \`gf deploy\` checks the Node bits before upload.
457
+
458
+ ## Node: function, job, schedule
459
+
460
+ \`npm start\` is **not** run for these types. The platform's generated
461
+ \`/app/main.js\` loads your code with \`require('./handler')\`, so:
462
+
463
+ 1. Put a \`handler.js\` at the ZIP root (not nested) that exports \`handler\`.
464
+ \`gf deploy\` also accepts a \`package.json\` \`"main"\` that points at an
465
+ existing file, but \`./handler\` is the documented path; prefer \`handler.js\`.
466
+ 2. \`scripts.start\` is not required, and a server that listens on a port is
467
+ not needed.
468
+ 3. Missing \`handler.js\` \u2192 the new revision crash-loops
469
+ (\`Cannot find module './handler'\`, \`MODULE_NOT_FOUND\`) and the deployment
470
+ ends **Failed (status 4)**. Check \`gf coderunner logs -c <id>\`.
471
+
472
+ For the handler's arguments and, for functions, the HTTP event/return shape,
473
+ see the runtime docs (https://docs.groundfloor.cloud/docs/deploy). Do not guess
474
+ the argument order.
475
+
476
+ ## Node: service (or any Dockerfile that runs \`npm start\`)
477
+
478
+ A \`service\` **requires** a root Dockerfile; you own \`CMD\`. If it is
479
+ \`npm start\` (for any type), \`package.json\` needs \`"scripts": { "start": ... }\`,
480
+ and the process must follow the HTTP contract:
457
481
 
458
482
  \`\`\`dockerfile
459
483
  FROM node:18-alpine
@@ -464,8 +488,7 @@ ENV PORT=8080
464
488
  CMD ["npm", "start"]
465
489
  \`\`\`
466
490
 
467
- 1. \`package.json\` **must** define \`"scripts": { "start": "node <entrypoint>" }\`.
468
- Missing \`start\` \u2192 container crash loop, probe \`127.0.0.1:8080\` connection
491
+ 1. Missing \`start\` \u2192 container crash loop, probe \`127.0.0.1:8080\` connection
469
492
  refused, deployment **Failed (status 4)** after several minutes.
470
493
  2. Listen on \`Number(process.env.PORT || 8080)\`.
471
494
  3. Bind **\`0.0.0.0\`**, not \`127.0.0.1\`. Cluster traffic is not loopback.
@@ -477,29 +500,8 @@ server.listen(port, "0.0.0.0", () => {
477
500
  });
478
501
  \`\`\`
479
502
 
480
- Offer GET \`/\` or \`/health\` for the probe. Sample: \`samples/hello-fn/\`.
481
-
482
- ## Known issue: bootstrap has been reported to skip \`npm start\`
483
-
484
- Reported 2026-09-22 against a \`function\` deploy with no Dockerfile, **unresolved as of this
485
- writing**: instead of running \`npm start\` per the contract above, the platform's own
486
- \`/app/main.js\` ran \`require('./handler')\` \u2014 a file/module contract this document does not
487
- describe \u2014 even though \`scripts.start\` and the entrypoint were present and correct. Symptom in
488
- \`gf coderunner logs -c <id>\`: \`Cannot find module './handler'\` (\`MODULE_NOT_FOUND\`), repeated
489
- probe \`127.0.0.1:8080\` connection refused, deployment **Failed (status 4)**. Whether \`job\` and
490
- \`schedule\` share this bootstrap path and are equally affected has not been confirmed either way \u2014
491
- treat the workaround below as precautionary for those types too if you hit the same signature.
492
-
493
- **Workaround:** add your own root \`Dockerfile\` (e.g. \`CMD ["npm", "start"]\`) and keep your
494
- existing \`workload_type\` \u2014 a Dockerfile bypasses the injected bootstrap entirely regardless of
495
- type (see "Node (with Dockerfile)" below), so this sidesteps the bug without changing how the
496
- workload is invoked.
497
-
498
- ## Node (with Dockerfile)
499
-
500
- You own \`CMD\`. If it is \`npm start\`, you still need \`scripts.start\`.
501
- Listen on 8080 / \`PORT\` and bind \`0.0.0.0\`. \`service\` (Deployment)
502
- **requires** a root Dockerfile \u2014 bootstrap is not injected on that path.
503
+ Offer GET \`/\` or \`/health\` for the probe. A Dockerfile whose \`CMD\` is not
504
+ \`npm start\` replaces the generated bootstrap entirely, for any type.
503
505
 
504
506
  ## Python
505
507
 
@@ -508,16 +510,18 @@ Bind \`0.0.0.0\` and \`PORT\` (default 8080), for example
508
510
 
509
511
  ## Jobs and schedules
510
512
 
511
- Same package/start rules. The process may exit 0 when finished; it does not
512
- need a public URL. Schedules have **no** Deployment URL. Set cron with
513
+ Node: \`handler.js\` exporting \`handler\`, same as functions (no \`npm start\`).
514
+ They do not need a public URL. Schedules have **no** Deployment URL. Set cron with
513
515
  \`gf deploy --workload-type schedule --schedule "<cron>"\` or
514
516
  \`groundfloor.json\` \`"schedule"\`.
515
517
 
516
518
  ## What \`gf deploy\` checks
517
519
 
518
520
  - \`service\` without a root Dockerfile \u2192 fail immediately.
519
- - Node without a Dockerfile (or a Dockerfile that runs \`npm start\`) and no
520
- \`scripts.start\` \u2192 fail immediately with this contract.
521
+ - Node \`function\`/\`job\`/\`schedule\` without a Dockerfile and without a root
522
+ \`handler.js\` (or a \`package.json\` \`"main"\` that resolves to a file) \u2192 fail
523
+ immediately. \`scripts.start\` is not required.
524
+ - Node with a Dockerfile that runs \`npm start\` and no \`scripts.start\` \u2192 fail immediately.
521
525
  - Listen/bind are not parsed from source; match the sample or the probe fails
522
526
  at deploy time. Check Process Log / \`gf coderunner logs -c <id>\`.
523
527
  `.trim();
@@ -571,24 +575,24 @@ Pick **one** type per coderunner. Changing type later means a new coderunner.
571
575
 
572
576
  ### Function
573
577
 
574
- - ZIP at archive root (\`package.json\` / \`index.js\` or \`main.py\` not nested).
575
- - Listen on \`process.env.PORT || 8080\`, bind **\`0.0.0.0\`** (health GET \`/\` or \`/health\`).
576
- - **Node:** \`package.json\` **must** include \`"scripts": { "start": "node index.js" }\`.
577
- The runtime image is \`CMD ["npm", "start"]\`. Missing \`start\` \u2192 crash loop,
578
- probe \`127.0.0.1:8080\` connection refused, deployment **Failed (status 4)**.
578
+ - ZIP at archive root (\`handler.js\` / \`package.json\` or \`main.py\` not nested).
579
+ - **Node:** a root \`handler.js\` exporting \`handler\`. The platform runs a generated
580
+ \`/app/main.js\` that does \`require('./handler')\`; \`npm start\` is **not** run and
581
+ \`scripts.start\` is not required. Missing \`handler.js\` \u2192 crash loop
582
+ (\`Cannot find module './handler'\`), deployment **Failed (status 4)**.
583
+ \`gf deploy\` fails fast on this. Handler arguments and the HTTP event/return
584
+ shape: see the runtime docs (\`docs_get\` id \`coderunner-runtime\`, docs.groundfloor.cloud/docs/deploy).
585
+ - Node with your own Dockerfile (\`CMD ["npm","start"]\`) instead: listen on
586
+ \`process.env.PORT || 8080\`, bind **\`0.0.0.0\`** (health GET \`/\` or \`/health\`), and
587
+ define \`scripts.start\`.
579
588
  - Python: process must bind 0.0.0.0:\${PORT:-8080}.
580
589
  - After deploy: \`gf coderunner run -c <slug> --payload '{"hello":"world"}'\`.
581
- - \u26A0\uFE0F See "Known issue" in \`docs_get\` id \`coderunner-runtime\` if \`gf coderunner logs\` shows
582
- \`Cannot find module './handler'\` despite a correct \`scripts.start\` \u2014 add a Dockerfile as the
583
- workaround, no type change needed.
584
590
 
585
591
  ### Job
586
592
 
587
- - Same package rules as function. No need to serve forever; exit 0 on success.
593
+ - Node: same as function (root \`handler.js\` exporting \`handler\`; no \`npm start\`).
594
+ No need to serve forever; exit 0 on success.
588
595
  - Deploy, then start a run (\`gf coderunner run\`). Check Process Log.
589
- - \u26A0\uFE0F Not confirmed whether the no-Dockerfile bootstrap bug in \`docs_get\` id \`coderunner-runtime\`
590
- ("Known issue") also hits \`job\` \u2014 if a run never starts and logs show the same
591
- \`MODULE_NOT_FOUND: './handler'\`, apply the same Dockerfile workaround.
592
596
 
593
597
  ### Schedule
594
598
 
@@ -598,8 +602,7 @@ Pick **one** type per coderunner. Changing type later means a new coderunner.
598
602
  - GET/list/status expose top-level \`workload_type\` and \`schedule\`.
599
603
  \`gf coderunner status -c <slug>\` prints type, schedule, last_job.
600
604
  - No public invoke URL. Debug with \`gf coderunner logs\`, not curl.
601
- - \u26A0\uFE0F Same caveat as Job: unconfirmed whether the bootstrap "Known issue" affects scheduled runs;
602
- same Dockerfile workaround if you see the identical crash signature.
605
+ - Node: same handler contract as function (root \`handler.js\`).
603
606
 
604
607
  ### Service (Deployment)
605
608
 
@@ -620,7 +623,7 @@ ENV PORT=8080
620
623
  CMD ["npm", "start"]
621
624
  \`\`\`
622
625
 
623
- - Still require Node \`"start"\` if CMD is \`npm start\`.
626
+ - Services follow the \`npm start\` / \`PORT\` contract: Node needs \`scripts.start\` if CMD is \`npm start\`.
624
627
  - Prefer curling the Deployment URL (\`/health\`) over \`\u2026/run\`.
625
628
 
626
629
  ## Latest deploy rules (all types)
@@ -651,7 +654,7 @@ gf dataplane status # provision if needed: gf dataplane provision
651
654
  gf secrets ls
652
655
  \`\`\`
653
656
 
654
- Local HTTP (Node function/service):
657
+ Local HTTP (Node service, or a Dockerfile-based function):
655
658
 
656
659
  \`\`\`bash
657
660
  export PORT=8080
@@ -1144,17 +1147,17 @@ var DOC_CATALOG = [
1144
1147
  id: "coderunner",
1145
1148
  title: "Coderunner",
1146
1149
  path: "/docs/deploy",
1147
- summary: "Workload types (function, job, schedule, service/Deployment), runtime contract (scripts.start, 0.0.0.0:8080), Dockerfile for services, Coderunner identities for Vault, App authentication optional, local live data, gf deploy.",
1150
+ summary: "Workload types (function, job, schedule, service/Deployment), runtime contract (handler.js for function/job/schedule; npm start, PORT 8080 for service), Dockerfile for services, Coderunner identities for Vault, App authentication optional, local live data, gf deploy.",
1148
1151
  embedded: CODERUNNER_GUIDE,
1149
- lastUpdated: "2026-09-25"
1152
+ lastUpdated: "2026-10-02"
1150
1153
  },
1151
1154
  {
1152
1155
  id: "coderunner-runtime",
1153
1156
  title: "Coderunner runtime contract",
1154
1157
  path: "/docs/deploy",
1155
- summary: "What the platform expects your code to do: Node bootstrap (npm start, PORT/8080, bind 0.0.0.0), Python bind, service Dockerfile.",
1158
+ summary: "What the platform expects your code to do: Node handler.js for function/job/schedule, npm start + PORT/8080 + bind 0.0.0.0 for service/Dockerfile, Python bind.",
1156
1159
  embedded: CODERUNNER_RUNTIME_CONTRACT,
1157
- lastUpdated: "2026-09-23"
1160
+ lastUpdated: "2026-10-02"
1158
1161
  },
1159
1162
  {
1160
1163
  id: "coderunner-overview",
@@ -1162,7 +1165,7 @@ var DOC_CATALOG = [
1162
1165
  path: "/docs/deploy",
1163
1166
  summary: "Architecture and lifecycle. Prefer docs_get id coderunner for type usage, Dockerfile, and create prerequisites.",
1164
1167
  embedded: CODERUNNER_GUIDE,
1165
- lastUpdated: "2026-09-25"
1168
+ lastUpdated: "2026-10-02"
1166
1169
  },
1167
1170
  {
1168
1171
  id: "authentication",
@@ -1250,7 +1253,7 @@ var DOC_CATALOG = [
1250
1253
  path: "/docs/deploy/schedules",
1251
1254
  summary: "workload_type=schedule plus cron. gf coderunner status shows type/schedule/last_job. Use Process Log, not a public URL.",
1252
1255
  embedded: CODERUNNER_GUIDE,
1253
- lastUpdated: "2026-09-25"
1256
+ lastUpdated: "2026-10-02"
1254
1257
  }
1255
1258
  ];
1256
1259
  function docUrl(entry) {
@@ -1325,7 +1328,7 @@ function suggestCli(intent, args) {
1325
1328
  case "deploy":
1326
1329
  return {
1327
1330
  command: name ? `gf deploy -n ${name}${ws}` : `gf deploy${ws}`,
1328
- why: 'Package the current (or --path) folder and deploy as a Coderunner. App authentication is optional (end-user login only). workloadType function|job|schedule|service (service = Deployment; requires a Dockerfile). Schedules need --schedule "<cron>" or groundfloor.json schedule. Node bootstrap: scripts.start, listen PORT||8080, bind 0.0.0.0. Do not create an App for this.',
1331
+ why: 'Package the current (or --path) folder and deploy as a Coderunner. App authentication is optional (end-user login only). workloadType function|job|schedule|service (service = Deployment; requires a Dockerfile). Schedules need --schedule "<cron>" or groundfloor.json schedule. Node function/job/schedule: root handler.js exporting handler (no npm start). Node service/Dockerfile: scripts.start, listen PORT||8080, bind 0.0.0.0. Do not create an App for this.',
1329
1332
  docs: "https://docs.groundfloor.cloud/docs/deploy"
1330
1333
  };
1331
1334
  case "run":
@@ -1524,12 +1527,12 @@ server.tool(
1524
1527
  runtime_contract: "coderunner-runtime",
1525
1528
  before_create: "Team write can create Coderunners without App authentication. Site auth is optional (end-user login). Mode none uses Portal JWKS (GET /v1/public/jwks.json).",
1526
1529
  types: {
1527
- function: "HTTP handler on PORT/8080 bound to 0.0.0.0. Invoke with gf coderunner run or the Deployment URL. Node requires package.json scripts.start.",
1528
- job: "Run-to-completion worker. Deploy, then gf coderunner run.",
1530
+ function: "Request/response handler. Invoke with gf coderunner run or the Deployment URL. Node: root handler.js exporting handler (npm start is not run); see docs_get coderunner-runtime.",
1531
+ job: "Run-to-completion worker. Node: root handler.js exporting handler. Deploy, then gf coderunner run.",
1529
1532
  schedule: 'Cron job. No public Deployment URL. Set cron with gf deploy --workload-type schedule --schedule "<cron>" (or groundfloor.json schedule).',
1530
1533
  service: "Long-running Deployment (same type as service). Dockerfile at ZIP root is required. Listen on 8080 / 0.0.0.0."
1531
1534
  },
1532
- node: "No Dockerfile \u2192 platform injects node:18-alpine CMD npm start EXPOSE 8080. Require scripts.start; listen on PORT||8080; bind 0.0.0.0. gf deploy fails fast if scripts.start is missing.",
1535
+ node: "function/job/schedule without a Dockerfile run a generated /app/main.js that requires ./handler: ship a root handler.js exporting handler (scripts.start not needed). service/Dockerfile running npm start: scripts.start, listen PORT||8080, bind 0.0.0.0. gf deploy fails fast on either missing.",
1533
1536
  local_live_data: 'eval "$(gf env)". For files/secrets as a builder use Bearer $(gf token). For Vault/Files as the deployed workload, attach an M2M client and use Bearer $(gf m2m token). Never DATAPLANE_SERVICE_API_KEY. Do not zip .env files.'
1534
1537
  },
1535
1538
  shell_app_howto: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@groundfloorcloud/mcp",
3
- "version": "0.1.15",
3
+ "version": "0.1.16",
4
4
  "description": "Groundfloor MCP — inspect workspace state and docs; take actions with the gf CLI.",
5
5
  "type": "module",
6
6
  "bin": {