@bettercms-ai/mcp 0.56.4 → 0.57.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/dist/index.js CHANGED
@@ -2449,6 +2449,11 @@ var GIT_TEXT = {
2449
2449
  create_github_pull_request: "Open a pull request on the connected repository. `head` is the branch you pushed; `base` defaults to the build branch, so merging it is what ships the change. Use this instead of pushing straight to the build branch whenever a human should review first, or when that branch is protected. Returns the number and the url to hand the user.",
2450
2450
  list_github_pull_requests: "Pull requests on the connected repository: number, title, state, whether it merged, draft, head, base and url. `state` is 'open' (the default), 'closed' or 'all'. Poll it to find out whether the pull request you opened has landed."
2451
2451
  };
2452
+ var HOSTING_TEXT = {
2453
+ list_hosting_connections: "The Vercel, Netlify and Cloudflare accounts connected to this workspace (id, provider, accountLabel, status; never a token), plus `connectUrl`, the dashboard page where a person connects one. Call it before deploy_to_host. If the provider the user wants has no connection with status `ok`, give the user `connectUrl` to connect it in their browser and stop until they have: you never handle OAuth or a host token yourself.",
2454
+ deploy_to_host: "Deploy this project to the user's own Vercel or Netlify account through their connection. BetterCMS builds the site and the host serves that build, so there is no host CLI to run, no token to paste and no vercel.json rewrite to write; forms keep working because they post to the BetterCMS API. The first call creates the site on the host and makes it the project's host; a later call for the same provider redeploys that site (`redeployed: true`) instead of creating another. `connectionId` (from list_hosting_connections) defaults to the newest working one, `siteName` to the project's handle. A refusal carries a `code` and a `fixUrl` (not_connected, reconnect, pick_existing_site, grant_required, ADMIN_REQUIRED): each is fixed by the user at `fixUrl`, so relay it and stop. `deploymentQueued: false` means the project has no live build yet: deploy_project first, and that release reaches the host on its own. Never run the Vercel or Netlify CLI while a connection exists. Then poll get_host_deploy_status. Needs artifact:write, like deploy_project.",
2455
+ get_host_deploy_status: "The connected project's recent deployments to Vercel, Netlify or Cloudflare, newest first: state (queued|deploying|live|failed), providerUrl, error, sha and targetName. Poll it after deploy_to_host until the newest one is `live`, whose `providerUrl` is the live URL to hand the user, or `failed`, whose `error` you read back to them."
2456
+ };
2452
2457
  function ok(summary, data) {
2453
2458
  return {
2454
2459
  content: [
@@ -2511,7 +2516,10 @@ function refusalDetail(err) {
2511
2516
  const lines = [
2512
2517
  code ? `code: ${code}` : "",
2513
2518
  body.readiness !== void 0 ? `readiness: ${JSON.stringify(body.readiness)}` : "",
2514
- body.issues !== void 0 ? `issues: ${JSON.stringify(body.issues)}` : ""
2519
+ body.issues !== void 0 ? `issues: ${JSON.stringify(body.issues)}` : "",
2520
+ // The link a person follows to fix it (connect a host, create a Vercel project): an agent
2521
+ // that only sees the sentence has nothing to hand the user.
2522
+ typeof body.fixUrl === "string" ? `fixUrl: ${body.fixUrl}` : ""
2515
2523
  ].filter(Boolean);
2516
2524
  return lines.length ? `
2517
2525
  ${lines.join("\n")}` : "";
@@ -4149,6 +4157,34 @@ ${res.warnings.join("\n")}` : summary, res.data);
4149
4157
  "Get the connected project's deploy/build status: state (idle|queued|building|categorizing|failed), whether it's publishing, the live commit sha, when it went live, and any build error. `categorizing` means the bytes are live but the import's setup lanes (content, pages, bindings) are still running, so `publishing` is still true and the site is not ready to edit yet. Poll this after deploy_project until state is idle with your sha live. Also returns `canvas.lane` (the editor's live-preview lane for this site: `bridge` / `draft-route` / `none`) and `editorUrl`, the visual editor to hand the user.",
4150
4158
  z.object({}).shape,
4151
4159
  async (c) => ok("Deploy status.", await data(c, "GET", `/management/projects/deploy-status`))
4160
+ ),
4161
+ // ── Deploy to the user's own host (parity with remote /mcp) ──
4162
+ // A person connects Vercel or Netlify in the dashboard; nothing here touches OAuth or a host
4163
+ // token. deploy_to_host takes artifact:write like deploy_project. @see management/deploy-targets.ts
4164
+ def(
4165
+ "list_hosting_connections",
4166
+ "List hosting connections",
4167
+ HOSTING_TEXT.list_hosting_connections,
4168
+ z.object({}).shape,
4169
+ async (c) => ok("Hosting connections.", await data(c, "GET", `/management/hosting/connections`))
4170
+ ),
4171
+ def(
4172
+ "deploy_to_host",
4173
+ "Deploy to Vercel or Netlify",
4174
+ HOSTING_TEXT.deploy_to_host,
4175
+ z.object({
4176
+ provider: z.enum(["vercel", "netlify"]),
4177
+ connectionId: z.string().min(1).optional().describe("a connection id from list_hosting_connections; defaults to the newest working one"),
4178
+ siteName: z.string().min(1).max(63).optional().describe("lowercase letters, numbers and hyphens; defaults to the project's handle")
4179
+ }).shape,
4180
+ async (c, a) => ok("Host deploy.", await data(c, "POST", `/management/deploy-targets/provision`, { provider: a.provider, connectionId: a.connectionId, siteName: a.siteName }))
4181
+ ),
4182
+ def(
4183
+ "get_host_deploy_status",
4184
+ "Get host deploy status",
4185
+ HOSTING_TEXT.get_host_deploy_status,
4186
+ z.object({}).shape,
4187
+ async (c) => ok("Host deployments.", await data(c, "GET", `/management/hosting/external-deployments`))
4152
4188
  )
4153
4189
  ];
4154
4190
  }
@@ -5933,12 +5969,12 @@ Do not stop at the plan or at a partial receipt \u2014 finish the whole site, ne
5933
5969
  with no \`fix\` is still yours. Then rerun step 4 until \`paths.pending\` is EMPTY.
5934
5970
  6. \`npx @bettercms-ai/convert --verify-styles --base <commit before step 4>\`, restore what it lists, then
5935
5971
  \`submit_conversion_receipt { briefDigest, receipt }\` with its \`styleEdits\`: only \`complete: true\` ends it (else step 5).
5936
- 7. Deploy (push, or \`deploy_project\`) and poll \`get_deploy_status\` until the release is live.
5937
- 8. \`get_binding_report\` must read \`unmatched\` 0 and \`unaddressable\` under 2% of each route's
5938
- visible text. Fix what it names in the SOURCE, deploy, re-read (playbook section 11).
5939
- 9. \`set_binding_mode { declaredBindings: true }\`, deploy AGAIN and poll \u2014 the mode applies to the
5940
- NEXT release \u2014 then confirm \`get_binding_report\` reads mode "declared", unmatched 0, bound
5941
- above 0, \`coverage.pending\` empty. That report is your final answer to me.`;
5972
+ 7. Deploy the working tree (\`create_deploy_upload\` + \`deploy_from_upload\`); poll \`get_deploy_status\` until live. No git yet.
5973
+ 8. \`get_binding_report\`: \`unmatched\` 0, \`unaddressable\` under 2% per route; fix the SOURCE, deploy, re-read (playbook \xA711).
5974
+ 9. \`set_binding_mode { declaredBindings: true }\`, deploy AGAIN and poll, then confirm \`get_binding_report\`
5975
+ reads mode "declared", unmatched 0, bound above 0, \`coverage.pending\` empty. Send me that report.
5976
+ 10. Ask me whether to commit and push to my repository, commit only, or leave it uncommitted (unpushed, the
5977
+ next rebuild from my repo drops it). Touch git only as I answer.`;
5942
5978
  var SCHEMA_PROPOSAL_FLOW = `### Whole-project design (confirm-first) \u2192 \`create_component\` / \`create_page\` / \`create_content_model\`
5943
5979
  Design the WHOLE project from its brief or its code, and **confirm the shape with the user
5944
5980
  BEFORE creating anything**. Never silently guess.