constructor-research-mcp 0.3.1 → 0.3.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.
@@ -1222,7 +1222,7 @@ export class DeploymentEngine {
1222
1222
  ? `${this.api.authHelp("The token expired or is invalid.")} Then call get_deployment with this deployment_id.`
1223
1223
  : op.status === "needs_upload"
1224
1224
  ? "Upload files with sync_files, then call get_deployment with files_uploaded=true."
1225
- : "Execution continues automatically in the MCP. Use get_deployment with wait_seconds=20 to wait for the result; do not orchestrate individual steps.",
1225
+ : "Execution continues automatically in the MCP. Keep calling get_deployment with wait_seconds=20 until it is finished, then tell the user the result; do not orchestrate individual steps.",
1226
1226
  };
1227
1227
  if (cache) {
1228
1228
  op.result = result;
package/dist/runtime.js CHANGED
@@ -220,7 +220,7 @@ export class DeploymentRuntime {
220
220
  ? "Inspect the uncertain mutation in Constructor before submitting a new operation."
221
221
  : terminal.has(op.status)
222
222
  ? undefined
223
- : `The MCP is executing this deployment. Keep working on other things and check later with get_deployment. If nothing else is left, wait with the shell command \`${waitCommand(this.engine.api.config, [op.id])}\` (run it in the background if your client wakes you when a background command ends); it prints the outcome when the deployment finishes. Without a shell, call get_deployment with wait_seconds=20.`,
223
+ : `Not finished yet; builds often take several minutes. Do not end your turn or answer the user until execution is finished: they asked for the result (the public_url, or what failed). Finish any other work of this request, then wait with the shell command \`${waitCommand(this.engine.api.config, [op.id])}\`; it prints the outcome when the deployment finishes. Run it in the foreground, or in the background only if your client wakes you when a background command ends. Without a shell, keep calling get_deployment with wait_seconds=20 until execution is finished.`,
224
224
  };
225
225
  }
226
226
  async wait(id, milliseconds) {
package/dist/server.js CHANGED
@@ -118,7 +118,7 @@ async function main() {
118
118
  : result;
119
119
  };
120
120
  const server = new McpServer({ name: "constructor-research", version: VERSION }, {
121
- instructions: `Sign-in: the MCP works with one Constructor, https://constructor.app unless the user signed in to another. When the user asks to sign in, or names their Constructor or gives a link from it (e.g. https://acme.constructor.app), call sign_in with url set to that link. Where to act: ask the user for the Constructor desk link (they open the desk in the browser and copy the address; it contains /projects/<project>/desks/<desk>) and pass it as desk_url. Do not pick a project or desk yourself; if the user has not said where to deploy or where files live, ask. Ask the user only before replacing, renaming or deleting files on a disk, once per request for the whole list (the tools return confirm_required); creating folders and uploading new files need no question. ${RULES} For a local app, pass build.local_path (the folder with the Dockerfile) and deploy_app uploads it first. Hardware: leave it out; the default is used. Set hardware minimums only when the app cannot run without a GPU or a lot of RAM. Use deploy_app/update_app once for the WHOLE application. The MCP builds, resolves service URLs, configures and starts services in the background. IDs are automatic. To wait, call get_deployment(wait_seconds=20) again as often as needed (a loop of such calls is fine); never perform the deployment steps yourself. On failure, tell the user the failed stage/service; failure.log_tail and get_logs show the last build or service log lines. Do not use browser or debugging tools. For source files: sync_files to the desk before building (the MCP checks each Dockerfile on the disk and reports warnings); after a needs_upload pause, sync and call get_deployment with files_uploaded=true. Started is not readiness.`,
121
+ instructions: `Sign-in: the MCP works with one Constructor, https://constructor.app unless the user signed in to another. When the user asks to sign in, or names their Constructor or gives a link from it (e.g. https://acme.constructor.app), call sign_in with url set to that link. Where to act: ask the user for the Constructor desk link (they open the desk in the browser and copy the address; it contains /projects/<project>/desks/<desk>) and pass it as desk_url. Do not pick a project or desk yourself; if the user has not said where to deploy or where files live, ask. Ask the user only before replacing, renaming or deleting files on a disk, once per request for the whole list (the tools return confirm_required); creating folders and uploading new files need no question. ${RULES} For a local app, pass build.local_path (the folder with the Dockerfile) and deploy_app uploads it first. Hardware: leave it out; the default is used. Set hardware minimums only when the app cannot run without a GPU or a lot of RAM. Use deploy_app/update_app once for the WHOLE application. The MCP builds, resolves service URLs, configures and starts services in the background. IDs are automatic. To wait, call get_deployment(wait_seconds=20) again as often as needed (a loop of such calls is fine); never perform the deployment steps yourself. When the user asks to deploy or build, wait until the deployment is finished before answering, then give the public URL or what failed. On failure, tell the user the failed stage/service; failure.log_tail and get_logs show the last build or service log lines. Do not use browser or debugging tools. For source files: sync_files to the desk before building (the MCP checks each Dockerfile on the disk and reports warnings); after a needs_upload pause, sync and call get_deployment with files_uploaded=true. Started is not readiness.`,
122
122
  });
123
123
  const register = (name, description, schema, fn, readOnly = false, budget = 20000, scope) => {
124
124
  if (scope && scope !== "deploy")
@@ -226,7 +226,7 @@ async function main() {
226
226
  register("update_app", "Update/add selected services in one request; preserve omitted settings. MCP handles builds, links and restarts in the background. Environment variables merge; supplied port/volume lists replace their lists. Resume a failed update using deployment_id and service overrides. The Dockerfile rules in deploy_app apply.", updateInput, checked((a) => runtime.update(a)), false, 60000, "deploy");
227
227
  register("start_app", "Start all or selected services as one operation. MCP handles all requests. Waits up to wait_seconds (default 20); remaining execution continues in the background. Started does not mean ready.", lifecycleInput, (a) => runtime.lifecycle("start", a), false, 20000, "project");
228
228
  register("stop_app", "Stop all or selected services as one operation. MCP handles all requests. Waits up to wait_seconds (default 20). Stopped means stop requests accepted, not verified teardown.", lifecycleInput, (a) => runtime.lifecycle("stop", a), false, 20000, "project");
229
- register("get_deployment", "With deployment_id, observe/wait for background execution; the MCP owns execution. Each call waits up to wait_seconds (max 20); to wait longer, call again, as often as needed (a loop of get_deployment calls is fine). Services carry status_changes and restarts_seen when the MCP saw the status change or a new container start. After sync_files (or manual upload) set files_uploaded=true; after cookie replacement checking the job resumes it. With no arguments, returns the map of all deployments: every deployment-enabled project with its applications and services (names, native statuses, public URLs, ports). With desk_url or project_id, returns that project's desks, images, hardware and applications; add application_id for one application. resume=false observes only. Never returns environment-variable values.", getInput, (a) => runtime.get(a), false, 20000, "deploy");
229
+ register("get_deployment", "With deployment_id, observe/wait for background execution; the MCP owns execution. Each call waits up to wait_seconds (max 20); to wait longer, call again, as often as needed (a loop of get_deployment calls is fine), until execution is finished; do not answer the user while it is still in the background. Services carry status_changes and restarts_seen when the MCP saw the status change or a new container start. After sync_files (or manual upload) set files_uploaded=true; after cookie replacement checking the job resumes it. With no arguments, returns the map of all deployments: every deployment-enabled project with its applications and services (names, native statuses, public URLs, ports). With desk_url or project_id, returns that project's desks, images, hardware and applications; add application_id for one application. resume=false observes only. Never returns environment-variable values.", getInput, (a) => runtime.get(a), false, 20000, "deploy");
230
230
  let signing;
231
231
  register("sign_in", "Signs the user in to their Constructor: https://constructor.app unless url names another one (any link from it, e.g. https://acme.constructor.app). Call it when the user asks to sign in, or when a tool returns needs_auth, after telling the user a sign-in window is about to open. It opens a separate Chrome window at the sign-in page; the user signs in there and the window closes by itself. There is one sign-in at a time: signing in to another Constructor replaces it, and the MCP works there afterwards. The session is kept for this harness only, and the MCP renews it automatically for up to 14 days. Waits up to wait_seconds; while the user is still signing in it returns sign_in_pending: call it again (no second window opens), then repeat the call that needed auth.", signInInput, async (a) => {
232
232
  const i = signInInput.parse(a);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "constructor-research-mcp",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "type": "module",
5
5
  "description": "Local deployment MCP for Constructor Research",
6
6
  "license": "MIT",