@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.
- package/README.md +1 -1
- package/dist/index.js +118 -21
- 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
|
|
520
|
-
|
|
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
|
|
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.
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
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**:
|
|
1104
|
-
|
|
1105
|
-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
|
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,
|