@groundfloorcloud/mcp 0.2.1 → 0.2.3

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 (3) hide show
  1. package/README.md +1 -1
  2. package/dist/index.js +118 -21
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -81,7 +81,7 @@ Use the prefixed names: `GROUNDFLOOR_API_URL`, `GROUNDFLOOR_WORKSPACE_ID`, `GROU
81
81
  | `apps_list` / `apps_get` | Inspect product Apps |
82
82
  | `secrets_list` / `files_list` / `dataplane_status` | Inspect (no secrets values) |
83
83
  | `domains_list` | Custom domains of an App's Coderunner (`app_id` or `coderunner_id`). Domains exist on Apps, not standalone Coderunners |
84
- | `quota_get` / `billing_summary` | Plan quota and billing for the workspace's **account** (account id is not the workspace id; billing needs Owner or Billing admin) |
84
+ | `quota_get` / `billing_summary` | Plan quota and billing for the workspace's **account** (account id is not the workspace id; billing needs organization Owner, Admin or Billing admin) |
85
85
  | `docs_list` / `docs_get` | Product docs (`coderunner`, `coderunner-runtime`, `shell`, `design-standard`, `css-and-styling`, `databases`, `vault`, `feature-flags`, `authentication` are embedded; `access` and `m2m` are live pages, with an `offset` parameter to read past the 12,000-character page limit) |
86
86
  | `suggest_cli` | Command to run: login, deploy, create_app, init_app, publish_app, m2m_token, … |
87
87
 
package/dist/index.js CHANGED
@@ -516,8 +516,20 @@ the provider.
516
516
 
517
517
  ## Users and roles (Groundfloor mode)
518
518
 
519
- - **Invite user**: they set their own password (email needs Branding set up).
520
- - **Add user**: you set a password now; no email is sent.
519
+ - **Invite user**: they set their own password from an emailed invitation
520
+ (the link works for 72 hours).
521
+ - **Add user**: they can sign in straight away. Prefer **Generate a temporary
522
+ password** (API: \`POST /v1/workspaces/{id}/users/add\` with
523
+ \`generate_password: true\`): it is returned once in \`temporary_password\`
524
+ with \`sign_in_url\`, never stored or emailed, and must be changed at first
525
+ sign-in. They also get an email with their sign-in address and role (never
526
+ the password).
527
+ - Invite and add take an optional \`app_id\` so the email's sign-in link opens
528
+ that app.
529
+ - Inviting or adding someone who can already sign in (a password, another
530
+ credential or single sign-on) returns 409 and sends nothing. Use
531
+ \`POST \u2026/users/{user_id}/reset-password\` for them instead.
532
+ - App users never appear on the portal **Team** page.
521
533
  - Each user has a role: built-in \`viewer\`, \`user\`, \`admin\`, or a custom role
522
534
  created on the **Roles** tab. Roles here are unrelated to Portal team roles.
523
535
  - The role decides what the user reaches once granted on **Site access**
@@ -530,6 +542,65 @@ the provider.
530
542
  - SSO (OIDC or SAML) can be connected per workspace; role names in the
531
543
  provider's tokens must match the roles granted on Site access.
532
544
 
545
+ ## Sign-in email (invites, password resets, email verification)
546
+
547
+ - Sent by **Groundfloor email** by default in every workspace: a Groundfloor
548
+ no-reply address with the organization's name as sender. Nothing to set up;
549
+ do not tell the user to configure email before inviting.
550
+ - To use their own mail server, the user chooses **Your own email server**
551
+ under **Branding \u2192 Email sending** (host, port and from address required;
552
+ port 25, 465, 587 or 2525), then **Send test email** (goes to their own
553
+ verified address). API: \`PUT /v1/workspaces/{id}/auth\` with
554
+ \`mail: {mode: "custom", ...}\`; test with
555
+ \`POST /v1/workspaces/{id}/auth/mail/test\`.
556
+ - A failing custom server does not fall back to Groundfloor email; the send
557
+ fails. Changing host or port needs the password again.
558
+ - **Warning:** saving a \`mail\` block with no \`host\` (or
559
+ \`mode: "groundfloor"\`) switches back to Groundfloor email and deletes the
560
+ stored custom server settings and password. Only send \`mail\` when the user
561
+ means to change email settings.
562
+
563
+ ## When an invite email isn't sent
564
+
565
+ Never report an invite as delivered without checking. Invite, add, resend and
566
+ reset responses, and every user in \`GET /v1/workspaces/{id}/users\`, carry:
567
+
568
+ - \`email_sent\`: \`true\` sent, \`false\` not sent, \`null\` unknown.
569
+ - \`email_skipped_reason\`: \`smtp_not_configured\` (no email server set up for
570
+ the workspace's sign-in email), \`send_failed\` (the server refused or
571
+ failed), \`delivery_unconfirmed\` (timed out; it may still arrive),
572
+ \`not_requested\` (sent with \`send_email: false\`), or \`null\`.
573
+ \`keycloak_smtp_missing\` is retired and no longer returned.
574
+ - \`email_attempted_at\` (\`null\` = invited before delivery was recorded),
575
+ \`invite_pending\`, \`password_change_required\`,
576
+ \`temporary_password_set_at\`, \`invite_link_expires_at\`.
577
+
578
+ If \`email_sent\` is not \`true\` for a pending user, tell the user plainly
579
+ and offer the fallbacks. In the Portal they are on the user's row under
580
+ **App authentication \u2192 Users**; all need workspace \`administer\` (M2M and
581
+ app-user tokens get 403):
582
+
583
+ 1. **Resend** (\`POST \u2026/users/{user_id}/resend-invite\`, pending users only):
584
+ at most once per 60 s and 5 times per 24 h; re-inviting a pending user
585
+ counts against the same limit (429 with \`Retry-After\`). If the reason is
586
+ \`send_failed\` or \`smtp_not_configured\`, fix email first (Branding \u2192
587
+ Email sending, Send test email) or resending will fail the same way.
588
+ 2. **Temp password** (\`POST \u2026/users/{user_id}/temporary-password\`, pending
589
+ or still on an unused temporary password): returns \`temporary_password\`
590
+ and \`sign_in_url\` once; no email is sent; same user id and roles; must be
591
+ changed at first sign-in. 504 = it may or may not be set, retry.
592
+ 3. **Copy link** (\`POST \u2026/users/{user_id}/invite-link\`, pending and enabled
593
+ users only): returns a one-time \`url\` (the portal's \`/join\` page) and
594
+ \`expires_at\` (24 h), once. The user opens it and chooses their own
595
+ password. Each call cancels the previous link; \`DELETE\` cancels it;
596
+ at most 10 per user per hour. Anyone holding the link can set the
597
+ password.
598
+
599
+ Temporary passwords and invite links are credentials. Show them only to the
600
+ person who asked for them, tell them to share privately, and never write them
601
+ to files, commits, logs or chat with anyone else. Once a user has set their
602
+ own password, none of these apply (409): use reset-password.
603
+
533
604
  ## Multi-tenant (customer companies inside one workspace)
534
605
 
535
606
  Turn on **Multi-tenant** in Settings to get a Tenants tab: one tenant per
@@ -544,6 +615,15 @@ Switching to None or External keeps users, roles and settings (switch back and
544
615
  they return). To remove them, turn sign-in off first, then **Delete Groundfloor
545
616
  login**. Access grants and M2M tokens are kept.
546
617
 
618
+ ## What app users' tokens can call
619
+
620
+ App users' tokens work only on: app list and by-slug, Data Vault collection
621
+ list/schema and record query/count/create/update/delete (per collection
622
+ grants), Files list/upload/download/delete (per Files grants) and
623
+ \`GET \u2026/flags/runtime\`. Everything else returns 403 "This API is not
624
+ available to app end users", whatever their role, \`admin\` included. A user
625
+ with no role at all gets 403 too.
626
+
547
627
  ## In a Shell app
548
628
 
549
629
  The signed-in user's JWT comes from \`window.__GF_GET_ACCESS_TOKEN__()\`. See
@@ -798,6 +878,11 @@ CMD ["npm", "start"]
798
878
  \`externalEndpoint\` and status 4 means the container never became ready.
799
879
  \`gf deploy\` prints the last Process Log lines, ids, and a Portal link on
800
880
  failure. Fetch more with \`gf coderunner logs -c <id|slug>\`.
881
+ - \`coderunner_get_status\` (\`GET \u2026/coderunners/{id}/status\`) returns
882
+ \`deployment_status\` (same 1\u20137 codes) and \`deployment_status_message\` for
883
+ the current deployment. While it is 4 (Failed), an App address or custom
884
+ domain routed to it answers 503, and the Portal app page shows "Deployment
885
+ failed".
801
886
  - Strip \`.env*\`, \`.git\`, \`node_modules\` from ZIPs. Put secrets in
802
887
  \`gf secrets\` / deploy \`-e\`, never in the archive.
803
888
  - Zip **contents** at root, not a wrapping folder.
@@ -914,8 +999,9 @@ documented limit.
914
999
  Plan quota and usage are account-scoped, not workspace-scoped. The **account
915
1000
  id is not the workspace id**: read \`account_id\` from \`workspaces_list\`. If a
916
1001
  deploy is refused or you need to know what is in use, call \`quota_get\`.
917
- \`billing_summary\` shows spend, and only Owners and Billing admins can read it
918
- (others get 403).
1002
+ \`billing_summary\` shows spend, and only organization Owners, Admins and
1003
+ Billing admins can read it (others get 403). A Billing admin has no workspace
1004
+ access at all.
919
1005
 
920
1006
  ## Agent actions
921
1007
 
@@ -975,16 +1061,26 @@ deploy a dedicated PostgreSQL first.
975
1061
  ## Options
976
1062
 
977
1063
  - PostgreSQL (shared) \u2014 platform-managed, already there. Default for app data
978
- and Vault. No deploy step. This is NOT a workspace-owned resource: it does
979
- not appear on the customer Databases page, and there is nothing to scale,
980
- back up, or delete yourself \u2014 it's offered, not provisioned. Query via
981
- Control Plane vault: POST /v1/workspaces/{id}/vault/collections/{name}/query
1064
+ and Vault. No deploy step. The portal Databases page lists it first as
1065
+ "Shared PostgreSQL" (Default, connected as \`postgresql\`), but it is NOT a
1066
+ workspace-owned resource: no credentials, and nothing to scale, back up, or
1067
+ delete yourself \u2014 it's offered, not provisioned. Query via Control Plane
1068
+ vault: POST /v1/workspaces/{id}/vault/collections/{name}/query
982
1069
  - Dedicated PostgreSQL you deploy and own \u2014 portal Data \u2192 Databases, or
983
1070
  POST /v1/workspaces/{id}/managed-databases with engine postgres. Heavier
984
1071
  than the shared default: you own its scaling, backups, and lifecycle. Use it
985
1072
  when you want a database isolated to this workspace.
986
1073
  - A database they already run \u2014 through Dataplane if they wire it, or direct.
987
1074
 
1075
+ A dedicated PostgreSQL is usable through Vault only once Dataplane has it:
1076
+ \`GET /v1/workspaces/{id}/managed-databases\` returns \`dataplane_status\`
1077
+ (\`connected\` | \`not_connected\` | null while not up) and
1078
+ \`dataplane_connection_name\` (pass it as Vault \`connection\`). If it is
1079
+ \`not_connected\`, retry with
1080
+ \`POST \u2026/managed-databases/{managed_database_id}/dataplane/register\` (write; the
1081
+ portal's Retry button), or tell the user to. New dedicated databases get a
1082
+ daily backup schedule (30-day retention) where the cell has backup storage.
1083
+
988
1084
  PostgreSQL is the only engine offered today, shared or dedicated. Do not offer
989
1085
  other engines (ArangoDB, MongoDB, Redis, ClickHouse, Qdrant, \u2026) as available,
990
1086
  even if you see them mentioned elsewhere. Do not call Dataplane hosts from apps
@@ -1100,9 +1196,10 @@ with no role gets 403.
1100
1196
  ### Shell federated app (browser)
1101
1197
 
1102
1198
  - **Token**: the Shell end-user JWT, \`await window.__GF_GET_ACCESS_TOKEN__()\`.
1103
- - **Permission**: workspace \`read\`. Site users get it from a recognised site
1104
- role (member/admin); self-registered users with no role get 403 (same rule
1105
- as Vault). No per-flag Access grant exists or is needed.
1199
+ - **Permission**: any role from the workspace's App authentication (built-in
1200
+ or custom); a signed-in user with no role gets 403 (same rule as Vault).
1201
+ App users are not workspace members. No per-flag Access grant exists or is
1202
+ needed.
1106
1203
  - **Environment**: \`window.__GF_ENVIRONMENT_ID__\` \u2014 the environment the app is
1107
1204
  bound to, published by the Shell before your remote mounts. Unset in local
1108
1205
  Dev Shell \u2192 server default (dev); \`VITE_GF_ENVIRONMENT_ID\` pins one.
@@ -1406,7 +1503,7 @@ var DOC_CATALOG = [
1406
1503
  path: "/docs/deploy",
1407
1504
  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.",
1408
1505
  embedded: CODERUNNER_GUIDE,
1409
- lastUpdated: "2026-10-08"
1506
+ lastUpdated: "2026-10-14"
1410
1507
  },
1411
1508
  {
1412
1509
  id: "coderunner-runtime",
@@ -1420,9 +1517,9 @@ var DOC_CATALOG = [
1420
1517
  id: "authentication",
1421
1518
  title: "Workspace Authentication",
1422
1519
  path: "/docs/access/app-authentication",
1423
- summary: "App end users sign in only to the app via the workspace App Authentication realm; no Groundfloor console account or workspace membership. Modes none / Groundfloor / external, users and roles, SSO, multi-tenant. Optional; not required to create Apps or Coderunners. Separate from portal Team.",
1520
+ summary: "App end users sign in only to the app via the workspace App Authentication realm; no Groundfloor console account or workspace membership. Modes none / Groundfloor / external, users and roles, SSO, multi-tenant, sign-in email (Groundfloor email by default, or your own server). Invite delivery (email_sent, email_skipped_reason) and what to do when an invite isn't sent: resend, generated temporary password, one-time invite link; 409 for people who can already sign in. App users' tokens work only on the end-user routes. Optional; not required to create Apps or Coderunners. Separate from portal Team.",
1424
1521
  embedded: APP_AUTHENTICATION_GUIDE,
1425
- lastUpdated: "2026-10-12"
1522
+ lastUpdated: "2026-10-14"
1426
1523
  },
1427
1524
  {
1428
1525
  id: "access",
@@ -1470,9 +1567,9 @@ var DOC_CATALOG = [
1470
1567
  id: "databases",
1471
1568
  title: "Databases",
1472
1569
  path: "/docs/data/databases",
1473
- summary: "Dataplane is not a database. PostgreSQL (shared, platform-managed) is ready through Dataplane with no deploy step. A dedicated PostgreSQL you deploy and own is a separate, heavier path. PostgreSQL is the only engine offered.",
1570
+ summary: "Dataplane is not a database. PostgreSQL (shared, platform-managed) is ready through Dataplane with no deploy step. A dedicated PostgreSQL you deploy and own is a separate, heavier path; check its dataplane_status before using it in Vault. PostgreSQL is the only engine offered.",
1474
1571
  embedded: DATABASES_GUIDE,
1475
- lastUpdated: "2026-09-26"
1572
+ lastUpdated: "2026-10-14"
1476
1573
  },
1477
1574
  {
1478
1575
  id: "vault",
@@ -1488,7 +1585,7 @@ var DOC_CATALOG = [
1488
1585
  path: "/docs/configure/feature-flags",
1489
1586
  summary: "Built-in per-environment feature flags (toggles / config values) \u2014 use these, not a Vault collection. gf flags ls|set|compare|promote. Apps read GET \u2026/flags/runtime: Shell apps with the end-user JWT + window.__GF_ENVIRONMENT_ID__ (starter-kit useFlag), Coderunners with gf m2m token + GROUNDFLOOR_ENVIRONMENT_ID. Default environment is dev.",
1490
1587
  embedded: FLAGS_GUIDE,
1491
- lastUpdated: "2026-10-08"
1588
+ lastUpdated: "2026-10-14"
1492
1589
  },
1493
1590
  {
1494
1591
  id: "flags-api",
@@ -1496,7 +1593,7 @@ var DOC_CATALOG = [
1496
1593
  path: "/docs/api/flags",
1497
1594
  summary: "REST reference for flags: list/get/put/delete per environment_id (omitted \u2192 workspace default, dev), compare, promote, runtime read. Key format, value_type validation, auth per method (M2M read-only), error codes.",
1498
1595
  embedded: FLAGS_GUIDE,
1499
- lastUpdated: "2026-10-08"
1596
+ lastUpdated: "2026-10-14"
1500
1597
  },
1501
1598
  {
1502
1599
  id: "scheduled-jobs",
@@ -1504,7 +1601,7 @@ var DOC_CATALOG = [
1504
1601
  path: "/docs/deploy/schedules",
1505
1602
  summary: "workload_type=schedule plus cron. gf coderunner status shows type/schedule/last_job. Use Process Log, not a public URL.",
1506
1603
  embedded: CODERUNNER_GUIDE,
1507
- lastUpdated: "2026-10-08"
1604
+ lastUpdated: "2026-10-14"
1508
1605
  }
1509
1606
  ];
1510
1607
  function docUrl(entry) {
@@ -1799,7 +1896,7 @@ server.tool(
1799
1896
  default_environment_id: flags?.environment_id ?? null,
1800
1897
  default_environment_flags: flags ? flags.flags.map((f) => ({ key: f.key, value_type: f.value_type, value: f.value })) : null,
1801
1898
  manage: "gf flags ls|get|set|rm|compare|promote -e <env id or name>. Omitting -e uses the default environment (dev).",
1802
- shell_app: "Starter-kit src/lib/flags.ts: useFlag('key', fallback). Calls GET /v1/workspaces/{id}/flags/runtime?environment_id=window.__GF_ENVIRONMENT_ID__ with the Shell end-user JWT (needs a site role \u2192 workspace read).",
1899
+ shell_app: "Starter-kit src/lib/flags.ts: useFlag('key', fallback). Calls GET /v1/workspaces/{id}/flags/runtime?environment_id=window.__GF_ENVIRONMENT_ID__ with the Shell end-user JWT (needs any App authentication role; app users are not workspace members).",
1803
1900
  coderunner: "GET \u2026/flags/runtime?environment_id=$GROUNDFLOOR_ENVIRONMENT_ID with an M2M token (gf m2m token). M2M is read-only on flags; workload-identity tokens are rejected."
1804
1901
  },
1805
1902
  coderunner_howto: {
@@ -2210,7 +2307,7 @@ server.tool(
2210
2307
  );
2211
2308
  server.tool(
2212
2309
  "billing_summary",
2213
- "Compute-unit usage and billing estimate for the organization that owns the workspace (account-scoped, not workspace-scoped). Only Owners and Billing admins may read it; others get 403. The response notes whether it is an estimate.",
2310
+ "Compute-unit usage and billing estimate for the organization that owns the workspace (account-scoped, not workspace-scoped). Only organization Owners, Admins and Billing admins may read it; others get 403. The response notes whether it is an estimate.",
2214
2311
  {
2215
2312
  workspace_id: wsId,
2216
2313
  account_id: accountId,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@groundfloorcloud/mcp",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "Groundfloor MCP — inspect workspace state and docs; take actions with the gf CLI.",
5
5
  "type": "module",
6
6
  "bin": {