constructor-research-mcp 0.3.2 → 0.4.0-beta.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.
- package/INSTALL.md +24 -25
- package/README.md +44 -48
- package/dist/api.d.ts +11 -30
- package/dist/api.js +53 -130
- package/dist/config.d.ts +11 -22
- package/dist/config.js +15 -47
- package/dist/deployment.d.ts +2 -0
- package/dist/deployment.js +26 -13
- package/dist/desk.d.ts +23 -0
- package/dist/desk.js +52 -0
- package/dist/files.d.ts +6 -0
- package/dist/files.js +46 -1
- package/dist/key.d.ts +9 -0
- package/dist/key.js +35 -0
- package/dist/location.d.ts +3 -1
- package/dist/location.js +13 -3
- package/dist/logs.js +2 -2
- package/dist/runtime.js +4 -4
- package/dist/schemas.d.ts +0 -5
- package/dist/schemas.js +0 -18
- package/dist/server.js +64 -106
- package/dist/set-key.d.ts +2 -0
- package/dist/set-key.js +107 -0
- package/dist/store.d.ts +1 -1
- package/dist/store.js +1 -1
- package/dist/wait.js +3 -6
- package/examples/claude-hooks.json +1 -1
- package/examples/claude.mcp.json +1 -1
- package/examples/codex-hooks.json +1 -1
- package/examples/codex.toml +1 -1
- package/examples/opencode-plugin.js +1 -1
- package/examples/opencode-v2.json +1 -1
- package/examples/opencode.json +1 -1
- package/package.json +7 -6
package/INSTALL.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# Install the Constructor Research MCP
|
|
2
2
|
|
|
3
|
-
The MCP lets Claude Code, Codex or OpenCode deploy apps to Constructor Research: constructor.app, or your organisation's Constructor, such as acme.constructor.app. It runs on your machine as a local MCP server, installed from npm
|
|
3
|
+
The MCP lets Claude Code, Codex or OpenCode deploy apps to Constructor Research: constructor.app, or your organisation's Constructor, such as acme.constructor.app. It runs on your machine as a local MCP server, installed from npm, and works with your personal Constructor access key.
|
|
4
4
|
|
|
5
5
|
## What you need
|
|
6
6
|
|
|
7
7
|
- Node.js 22 or later ([nodejs.org](https://nodejs.org), or `nvm install 22`)
|
|
8
|
-
-
|
|
8
|
+
- a personal access key (`rk-…`) for your Constructor
|
|
9
9
|
- macOS, Windows or Linux
|
|
10
10
|
|
|
11
11
|
## 1. Add it to your tool
|
|
@@ -13,19 +13,19 @@ The MCP lets Claude Code, Codex or OpenCode deploy apps to Constructor Research:
|
|
|
13
13
|
**Claude Code**: run once:
|
|
14
14
|
|
|
15
15
|
```sh
|
|
16
|
-
claude mcp add --scope user constructor-research -- npx -y constructor-research-mcp@
|
|
16
|
+
claude mcp add --scope user constructor-research -- npx -y constructor-research-mcp@beta
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
On Windows (not WSL), use this instead:
|
|
20
20
|
|
|
21
21
|
```bat
|
|
22
|
-
claude mcp add --scope user constructor-research -- cmd /c npx -y constructor-research-mcp@
|
|
22
|
+
claude mcp add --scope user constructor-research -- cmd /c npx -y constructor-research-mcp@beta
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
**Codex**: run once:
|
|
26
26
|
|
|
27
27
|
```sh
|
|
28
|
-
codex mcp add constructor-research -- npx -y constructor-research-mcp@
|
|
28
|
+
codex mcp add constructor-research -- npx -y constructor-research-mcp@beta
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
The first start downloads the package and can exceed Codex's 10-second start limit. If Codex reports a timeout, restart it once, or add `startup_timeout_sec = 60` under `[mcp_servers.constructor-research]` in `~/.codex/config.toml`. The full entry, if you prefer to write it by hand:
|
|
@@ -33,7 +33,7 @@ The first start downloads the package and can exceed Codex's 10-second start lim
|
|
|
33
33
|
```toml
|
|
34
34
|
[mcp_servers.constructor-research]
|
|
35
35
|
command = "npx"
|
|
36
|
-
args = ["-y", "constructor-research-mcp@
|
|
36
|
+
args = ["-y", "constructor-research-mcp@beta"]
|
|
37
37
|
startup_timeout_sec = 60
|
|
38
38
|
tool_timeout_sec = 30
|
|
39
39
|
```
|
|
@@ -41,13 +41,13 @@ tool_timeout_sec = 30
|
|
|
41
41
|
**OpenCode**: run once; it adds the entry to your OpenCode config and keeps what is already there. Check your version with `opencode --version`. OpenCode 2.x:
|
|
42
42
|
|
|
43
43
|
```sh
|
|
44
|
-
opencode mcp add --global constructor-research -- npx -y constructor-research-mcp@
|
|
44
|
+
opencode mcp add --global constructor-research -- npx -y constructor-research-mcp@beta
|
|
45
45
|
```
|
|
46
46
|
|
|
47
47
|
Without `--global`, OpenCode 2.x adds it to the current folder's project config instead. OpenCode 1.x has no `--global` and writes to your user config when run outside a project:
|
|
48
48
|
|
|
49
49
|
```sh
|
|
50
|
-
opencode mcp add constructor-research -- npx -y constructor-research-mcp@
|
|
50
|
+
opencode mcp add constructor-research -- npx -y constructor-research-mcp@beta
|
|
51
51
|
```
|
|
52
52
|
|
|
53
53
|
Or add it by hand to `~/.config/opencode/opencode.json` (or a project's `opencode.json`). This is the 1.x layout; in 2.x the entry goes one level deeper, under `mcp.servers`, as in [examples/opencode-v2.json](examples/opencode-v2.json):
|
|
@@ -58,22 +58,25 @@ Or add it by hand to `~/.config/opencode/opencode.json` (or a project's `opencod
|
|
|
58
58
|
"mcp": {
|
|
59
59
|
"constructor-research": {
|
|
60
60
|
"type": "local",
|
|
61
|
-
"command": ["npx", "-y", "constructor-research-mcp@
|
|
61
|
+
"command": ["npx", "-y", "constructor-research-mcp@beta"]
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
-
Do not put
|
|
67
|
+
Do not put the key in these settings unless you have to; the next step saves it where every tool finds it.
|
|
68
68
|
|
|
69
|
-
## 2.
|
|
69
|
+
## 2. Save your access key
|
|
70
70
|
|
|
71
|
-
|
|
72
|
-
2. Ask the agent to sign in. If your Constructor is not constructor.app, give its address, for example "sign in to Constructor at https://acme.constructor.app". A desk link from it works too.
|
|
73
|
-
3. The agent says a sign-in window will open and calls `sign_in`. A separate browser window opens at your Constructor's sign-in page.
|
|
74
|
-
4. Sign in. The window closes by itself.
|
|
71
|
+
In a terminal, run this with your Constructor's address and paste the key when asked (it is not shown):
|
|
75
72
|
|
|
76
|
-
|
|
73
|
+
```sh
|
|
74
|
+
npx -y -p constructor-research-mcp@beta constructor-research-set-key https://acme.constructor.app
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
It checks the key with Constructor and saves it, with that address, to `~/.config/constructor-research/access-key.json` (readable only by you). Claude Code, Codex and OpenCode all use this one key, and the MCP works with that Constructor. To switch Constructor or replace a revoked key, run it again. Never paste the key into the chat.
|
|
78
|
+
|
|
79
|
+
Then restart the tool, or run `/mcp` in Claude Code, so it starts the MCP. The first start downloads it and can take a minute.
|
|
77
80
|
|
|
78
81
|
## 3. Optional: get told when a deployment finishes
|
|
79
82
|
|
|
@@ -85,7 +88,7 @@ Builds can take many minutes. These add-ons wake the agent when a deployment it
|
|
|
85
88
|
|
|
86
89
|
## Update
|
|
87
90
|
|
|
88
|
-
Restart the tool (or `/mcp` in Claude Code): `@
|
|
91
|
+
Restart the tool (or `/mcp` in Claude Code): `@beta` fetches the newest beta on start. Your key is kept.
|
|
89
92
|
|
|
90
93
|
## Troubleshooting
|
|
91
94
|
|
|
@@ -95,18 +98,14 @@ Restart the tool (or `/mcp` in Claude Code): `@latest` fetches the newest versio
|
|
|
95
98
|
which npx
|
|
96
99
|
```
|
|
97
100
|
|
|
98
|
-
|
|
101
|
+
**A tool returns `needs_key`.** No key is saved, or Constructor rejected it (revoked or expired). Save a new one with the command in step 2.
|
|
99
102
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
```sh
|
|
103
|
-
npx -y -p constructor-research-mcp constructor-research-set-token <file> --for claude-code
|
|
104
|
-
```
|
|
103
|
+
**`set-key` says the address answered an HTTP error.** That Constructor may not have the public API yet, or you are off the VPN it needs.
|
|
105
104
|
|
|
106
105
|
**Check the MCP on its own.** Run the MCP Inspector, then turn on the server's toggle and open Tools:
|
|
107
106
|
|
|
108
107
|
```sh
|
|
109
|
-
npx @modelcontextprotocol/inspector@2.11.0 -- npx -y constructor-research-mcp@
|
|
108
|
+
npx @modelcontextprotocol/inspector@2.11.0 -- npx -y constructor-research-mcp@beta
|
|
110
109
|
```
|
|
111
110
|
|
|
112
111
|
## Uninstall
|
|
@@ -117,7 +116,7 @@ Remove `constructor-research` from your tool's settings. In Claude Code:
|
|
|
117
116
|
claude mcp remove constructor-research --scope user
|
|
118
117
|
```
|
|
119
118
|
|
|
120
|
-
To remove your data too, delete the
|
|
119
|
+
To remove your data too, delete the saved key and deployment progress:
|
|
121
120
|
|
|
122
121
|
```sh
|
|
123
122
|
rm -rf ~/.config/constructor-research ~/.local/state/constructor-research-mcp
|
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Constructor Research MCP
|
|
2
2
|
|
|
3
|
+
> **Beta (0.4.0-beta):** works only with Constructor's public API and a personal access key (`rk-…`); there is no browser sign-in. The public API is not yet on every Constructor. Install with `@beta`; `@latest` is still 0.3.x with browser sign-in.
|
|
4
|
+
|
|
3
5
|
Local stdio MCP for Codex CLI, Claude Code and OpenCode. Submit the whole application once; the MCP builds images, connects services, configures them and starts them. The agent supplies missing configuration and reports the result.
|
|
4
6
|
|
|
5
7
|
## Install
|
|
@@ -9,76 +11,71 @@ You need Node.js 22+. Then add the MCP to your tool.
|
|
|
9
11
|
**Claude Code**
|
|
10
12
|
|
|
11
13
|
```sh
|
|
12
|
-
claude mcp add --scope user constructor-research -- npx -y constructor-research-mcp@
|
|
14
|
+
claude mcp add --scope user constructor-research -- npx -y constructor-research-mcp@beta
|
|
13
15
|
```
|
|
14
16
|
|
|
15
17
|
**Codex**
|
|
16
18
|
|
|
17
19
|
```sh
|
|
18
|
-
codex mcp add constructor-research -- npx -y constructor-research-mcp@
|
|
20
|
+
codex mcp add constructor-research -- npx -y constructor-research-mcp@beta
|
|
19
21
|
```
|
|
20
22
|
|
|
21
23
|
**OpenCode 2.x**
|
|
22
24
|
|
|
23
25
|
```sh
|
|
24
|
-
opencode mcp add --global constructor-research -- npx -y constructor-research-mcp@
|
|
26
|
+
opencode mcp add --global constructor-research -- npx -y constructor-research-mcp@beta
|
|
25
27
|
```
|
|
26
28
|
|
|
27
29
|
**OpenCode 1.x** (no `--global` there):
|
|
28
30
|
|
|
29
31
|
```sh
|
|
30
|
-
opencode mcp add constructor-research -- npx -y constructor-research-mcp@
|
|
32
|
+
opencode mcp add constructor-research -- npx -y constructor-research-mcp@beta
|
|
31
33
|
```
|
|
32
34
|
|
|
33
|
-
Then restart the tool and ask the agent anything about Constructor
|
|
35
|
+
Then save your personal access key (see below), restart the tool and ask the agent anything about Constructor. Windows notes, the optional wake-up hooks and troubleshooting are in [INSTALL.md](INSTALL.md). Restarting the tool picks up a new version.
|
|
34
36
|
|
|
35
|
-
##
|
|
37
|
+
## Access key and connection
|
|
36
38
|
|
|
37
|
-
|
|
39
|
+
The MCP uses only a personal access key (`rk-…`) from Constructor's public API; there is no browser sign-in. Every request carries it as `X-Research-AccessKey: Bearer rk-…`, to the account API (`/api/platform-account/v1`), the desk storage (WebDAV) and the logs alike. The key never goes through the chat: the user saves it in a terminal, where it is read hidden, checked against Constructor and saved:
|
|
38
40
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
```sh
|
|
42
|
+
npx -y -p constructor-research-mcp@beta constructor-research-set-key https://acme.constructor.app
|
|
43
|
+
```
|
|
42
44
|
|
|
43
|
-
|
|
45
|
+
It goes to `~/.config/constructor-research/access-key.json` (mode 600) together with the Constructor it belongs to, and the MCP works with that Constructor. All harnesses (Claude Code, Codex, OpenCode) and the wait command share this one file. Every request rereads it, so a new key needs no restart. A key is never sent to a Constructor other than the one it was saved for.
|
|
44
46
|
|
|
45
|
-
|
|
47
|
+
Instead of the file, `CONSTRUCTOR_ACCESS_KEY` (with `CONSTRUCTOR_BASE_URL`) can be set in the MCP settings; it takes precedence. The wait hooks do not see the MCP settings, so with this option they need the same variables in their own environment.
|
|
46
48
|
|
|
47
|
-
|
|
49
|
+
Without a key, or when Constructor rejects it (401: revoked, expired or for another Constructor), tools return `needs_key` with the command above; a deployment pauses as `needs_key` and resumes on the next check once a valid key is saved. A desk link from another Constructor returns `wrong_environment`.
|
|
48
50
|
|
|
49
|
-
|
|
51
|
+
Deployment must be switched on for the project. If it is off and the key may not switch it on (403), the operation fails at stage `prepare` with a message asking the user to switch it on in Constructor.
|
|
50
52
|
|
|
51
|
-
|
|
53
|
+
| Variable | Default |
|
|
54
|
+
| ----------------------------------- | ----------------------------------------------------------------------------------------------- |
|
|
55
|
+
| `CONSTRUCTOR_BASE_URL` | unset: the Constructor of the saved key, else `https://constructor.app`; set, it fixes the host |
|
|
56
|
+
| `CONSTRUCTOR_API_PATH` | `/api/platform-account/v1` |
|
|
57
|
+
| `CONSTRUCTOR_STORAGE_PATH` | `/api/platform-storage` |
|
|
58
|
+
| `CONSTRUCTOR_ACCESS_KEY` | unset: the key file is used |
|
|
59
|
+
| `CONSTRUCTOR_KEY_FILE` | `~/.config/constructor-research/access-key.json` |
|
|
60
|
+
| `CONSTRUCTOR_DESK_ROOT` | `~/project` (inside a desk only) |
|
|
61
|
+
| `CONSTRUCTOR_STATE_DIR` | `~/.local/state/constructor-research-mcp` |
|
|
62
|
+
| `CONSTRUCTOR_UPLOAD_SETTLE_SECONDS` | `30` |
|
|
63
|
+
| `CONSTRUCTOR_READINESS_SECONDS` | `60` |
|
|
52
64
|
|
|
53
|
-
|
|
54
|
-
npx -y -p constructor-research-mcp constructor-research-login --for claude-code
|
|
55
|
-
npx -y -p constructor-research-mcp constructor-research-login --url https://acme.constructor.app --for claude-code
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
On a machine without a screen (Linux without `DISPLAY`/`WAYLAND_DISPLAY`), `sign_in` says so; save a session from a copied cURL (DevTools → Network → Copy as cURL) instead:
|
|
59
|
-
|
|
60
|
-
```sh
|
|
61
|
-
npx -y -p constructor-research-mcp constructor-research-set-token capture.txt --for codex
|
|
62
|
-
```
|
|
65
|
+
HTTPS is required except on localhost.
|
|
63
66
|
|
|
64
|
-
|
|
67
|
+
## Inside a Constructor desk (VS Code)
|
|
65
68
|
|
|
66
|
-
|
|
69
|
+
When the MCP runs in VS Code inside a Constructor Research desk, it finds that desk from the environment Constructor sets there (`ROLOS_PROJECT_ID`/`RESEARCH_PROJECT_ID`, `ROLOS_DESK_ID`/`RESEARCH_DESK_ID`, `ROLOS_API_SERVER`/`RESEARCH_API_SERVER`) and works in it:
|
|
67
70
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
| `CONSTRUCTOR_STORAGE_PATH` | `/api/platform-storage` |
|
|
73
|
-
| `CONSTRUCTOR_COOKIE_FILE` | unset: `~/.config/constructor-research/sessions/<harness>.txt` |
|
|
74
|
-
| `CONSTRUCTOR_BROWSER` | first Chrome, Edge, Chromium or Brave found |
|
|
75
|
-
| `CONSTRUCTOR_STATE_DIR` | `~/.local/state/constructor-research-mcp` |
|
|
76
|
-
| `CONSTRUCTOR_UPLOAD_SETTLE_SECONDS` | `30` |
|
|
77
|
-
| `CONSTRUCTOR_READINESS_SECONDS` | `60` |
|
|
71
|
+
- the desk's project folder (`~/project`, or `CONSTRUCTOR_DESK_ROOT`) is its disk, so the agent creates and changes files there directly; nothing is uploaded, and `sync_files`, `list_files`, `create_folder`, `move_path` and `delete_path` answer `local_desk` for this desk;
|
|
72
|
+
- `build_image`, `deploy_app`, `update_app`, `start_app`, `stop_app` and `list_images` act on this desk and project without a desk link; a `desk_url` or other IDs still name another desk;
|
|
73
|
+
- `build.dockerfile` is the path inside the project folder (`/backend/Dockerfile`), or `build.local_path` names a folder inside it; Dockerfiles are checked from the local files;
|
|
74
|
+
- the MCP works with the desk's Constructor (`ROLOS_API_SERVER`) unless `CONSTRUCTOR_BASE_URL` is set.
|
|
78
75
|
|
|
79
|
-
|
|
76
|
+
`CONSTRUCTOR_LOCAL_DESK=0` turns this off.
|
|
80
77
|
|
|
81
|
-
##
|
|
78
|
+
## Thirteen tools
|
|
82
79
|
|
|
83
80
|
| Tool | Agent's task |
|
|
84
81
|
| ------------------------ | ----------------------------------------------------------------------------------- |
|
|
@@ -90,13 +87,12 @@ HTTPS is required except on localhost. API-key authentication is not implemented
|
|
|
90
87
|
| `build_image` | Build an image independently when needed. |
|
|
91
88
|
| `list_images` | List image IDs, Dockerfiles and native build statuses. |
|
|
92
89
|
| `list_files` | List a disk's files and folders; `recursive:true` walks subfolders. |
|
|
93
|
-
| `sign_in` | Open a sign-in window for the user when a tool returns `needs_auth`. |
|
|
94
90
|
| `create_folder` | Create a disk folder, including missing parents. |
|
|
95
91
|
| `sync_files` | Upload new and changed files; asks once before replacing existing files. |
|
|
96
92
|
| `move_path` | Rename or move files/folders in one batch, approved once; never overwrites. |
|
|
97
93
|
| `delete_path` | Delete files/folders in one batch; reports first, deletes only with `confirm:true`. |
|
|
98
94
|
|
|
99
|
-
No special clone/new-instance workflow is implemented. The
|
|
95
|
+
No special clone/new-instance workflow is implemented. The thirteen tools use the same standard MCP transport across harnesses.
|
|
100
96
|
|
|
101
97
|
## Where to act: the desk link
|
|
102
98
|
|
|
@@ -106,7 +102,7 @@ The agent does not choose a project or desk. It asks the user for the desk link:
|
|
|
106
102
|
https://constructor.app/research/projects/<project_id>/desks/<desk_id>/viewer/file
|
|
107
103
|
```
|
|
108
104
|
|
|
109
|
-
Every tool accepts it as `desk_url`, in place of `project_id`/`desk_id`. Anything after `/desks/<desk_id>` is ignored. The link's host must be the
|
|
105
|
+
Every tool accepts it as `desk_url`, in place of `project_id`/`desk_id`. Anything after `/desks/<desk_id>` is ignored. The link's host must be the Constructor the key belongs to; a link from another one returns `wrong_environment` (see the access key above). Explicit IDs, if also sent, must agree with the link. In `deploy_app`/`update_app`, builds without their own `desk_id` use the link's desk; `start_app`/`stop_app` and `get_deployment` take only the project from it.
|
|
110
106
|
|
|
111
107
|
## Normal deployment flow
|
|
112
108
|
|
|
@@ -187,7 +183,7 @@ Replace a service's `build` with `"image_id":"IMAGE_ID"` to skip building. `list
|
|
|
187
183
|
|
|
188
184
|
## Missing prerequisites
|
|
189
185
|
|
|
190
|
-
- **No
|
|
186
|
+
- **No or rejected key:** `needs_key` with the command to save one (see Access key). Save a valid key, then check the same deployment again.
|
|
191
187
|
- **No project/disk:** omit `project_id`, optionally supply `project_name`, and use build sources without disk IDs. MCP creates the project/disk and enables deployment tools.
|
|
192
188
|
- **Files absent:** `needs_upload` lists disks and Dockerfile paths. Upload with `sync_files` (or manually), then call `get_deployment` with `deployment_id` and `files_uploaded:true`.
|
|
193
189
|
|
|
@@ -234,11 +230,11 @@ Learned from live runs (28 Oct 2026):
|
|
|
234
230
|
|
|
235
231
|
## State and recovery
|
|
236
232
|
|
|
237
|
-
Progress and sanitized results are checkpointed. Configuration secrets remain in owner-only local checkpoint files (`0600`, directory `0700`); tool responses return environment-variable names, never values.
|
|
233
|
+
Progress and sanitized results are checkpointed. Configuration secrets remain in owner-only local checkpoint files (`0600`, directory `0700`); tool responses return environment-variable names, never values. The access key is not checkpointed. Do not commit credentials or state.
|
|
238
234
|
|
|
239
235
|
Checkpoints are bound to the API endpoint. A shared state directory coordinates local harnesses. `resume:false` on `get_deployment` observes without scheduling execution or confirming uploads; already running background work is not paused.
|
|
240
236
|
|
|
241
|
-
Terminal states: `built`, `started`, `stopped`, `failed`, `needs_reconciliation`, `superseded`. A new `update_app`, `start_app` or `stop_app` for an application ends that application's unfinished deployments as `superseded`, so an older one cannot apply its images after the newer one; its builds keep running on Constructor but are not used. The new result lists them in `replaced`, with the services they were changing that the new update leaves out. User-action pauses: `
|
|
237
|
+
Terminal states: `built`, `started`, `stopped`, `failed`, `needs_reconciliation`, `superseded`. A new `update_app`, `start_app` or `stop_app` for an application ends that application's unfinished deployments as `superseded`, so an older one cannot apply its images after the newer one; its builds keep running on Constructor but are not used. The new result lists them in `replaced`, with the services they were changing that the new update leaves out. User-action pauses: `needs_key`, `needs_upload`. Other statuses indicate background progress. An executor stops after one hour rather than retrying forever.
|
|
242
238
|
|
|
243
239
|
For `needs_reconciliation`, inspect the possible remote mutation before submitting a new operation. The server never blindly repeats an uncertain create. A `.lock` left by a process that no longer exists (a server killed or restarted mid-step) is removed automatically on the next operation; a lock held by a live process returns `busy`. Checkpoints remain available. No rollback or resource deletion is automated.
|
|
244
240
|
|
|
@@ -256,10 +252,10 @@ Constructor serves logs only live, as a stream: a build log while the build runs
|
|
|
256
252
|
|
|
257
253
|
## Waiting for long builds
|
|
258
254
|
|
|
259
|
-
Builds can run for many minutes. The MCP keeps executing in the background, but an agent that has ended its turn is not told when they finish. `dist/wait.js` (bin `constructor-research-wait`) blocks until the given deployments, or all in-progress ones when no ID is given, finish, and prints one line each: status, message, services with public URLs, next step. Exit codes: `0` finished, `2` needs the user (failed,
|
|
255
|
+
Builds can run for many minutes. The MCP keeps executing in the background, but an agent that has ended its turn is not told when they finish. `dist/wait.js` (bin `constructor-research-wait`) blocks until the given deployments, or all in-progress ones when no ID is given, finish, and prints one line each: status, message, services with public URLs, next step. Exit codes: `0` finished, `2` needs the user (failed, key, upload, volume confirmation), `3` still running at `--max-minutes` (default 60), `4` nothing in progress.
|
|
260
256
|
|
|
261
257
|
```sh
|
|
262
|
-
npx -y -p constructor-research-mcp constructor-research-wait <deployment_id>
|
|
258
|
+
npx -y -p constructor-research-mcp@beta constructor-research-wait <deployment_id>
|
|
263
259
|
```
|
|
264
260
|
|
|
265
261
|
It watches the checkpoints the MCP writes. For deployments named by ID, if no process has advanced one for a minute (the MCP was closed), it continues it itself, exactly as the MCP would on restart. Without IDs it only watches, since those deployments may belong to other sessions. While a deployment runs, `next_action` gives the agent the exact command, including the MCP's non-default `CONSTRUCTOR_*` settings; the wait command needs the same settings as the MCP.
|
|
@@ -287,7 +283,7 @@ Use the executable directly to keep stdout reserved for MCP. `structuredContent`
|
|
|
287
283
|
|
|
288
284
|
## Disk files
|
|
289
285
|
|
|
290
|
-
The tools use the disk's WebDAV storage (`/api/platform-storage/desks/{disk}/dav/project/`) with the same
|
|
286
|
+
The tools use the disk's WebDAV storage (`/api/platform-storage/desks/{disk}/dav/project/`) with the same key. `sync_files`:
|
|
291
287
|
|
|
292
288
|
- compares each local file with the disk by size, then by the server's SHA-256 checksum; only new and changed files are sent, and nothing is deleted;
|
|
293
289
|
- uploads new files and creates folders without asking; if existing files would be replaced, it uploads nothing and returns `confirm_required` with the whole plan, to be approved once and repeated with `confirm:true`; `dry_run:true` only previews;
|
package/dist/api.d.ts
CHANGED
|
@@ -6,8 +6,8 @@ export declare class ToolError extends Error {
|
|
|
6
6
|
constructor(code: string, message: string, status?: number | undefined, apiCode?: number | undefined);
|
|
7
7
|
}
|
|
8
8
|
export declare const segment: (s: string) => string;
|
|
9
|
-
/**
|
|
10
|
-
export declare function
|
|
9
|
+
/** A key as Constructor shows it, with or without the "Bearer " the header adds. */
|
|
10
|
+
export declare function cleanKey(raw: string | undefined): string | undefined;
|
|
11
11
|
export declare class PlatformApi {
|
|
12
12
|
readonly config: Config;
|
|
13
13
|
private readonly deadline;
|
|
@@ -15,35 +15,16 @@ export declare class PlatformApi {
|
|
|
15
15
|
/** End of the current call's time budget (epoch ms); Infinity outside one. */
|
|
16
16
|
deadlineMs(): number;
|
|
17
17
|
withBudget<T>(milliseconds: number, fn: () => Promise<T>): Promise<T>;
|
|
18
|
-
/** How
|
|
19
|
-
|
|
18
|
+
/** How the user supplies a key; the key itself never passes through the chat. */
|
|
19
|
+
keyHelp(what?: string): string;
|
|
20
20
|
/**
|
|
21
|
-
* Works with the Constructor the saved
|
|
22
|
-
*
|
|
21
|
+
* Works with the Constructor the saved key belongs to, unless CONSTRUCTOR_BASE_URL fixes it.
|
|
22
|
+
* Read before every tool call, so a key saved meanwhile is used without a restart.
|
|
23
23
|
*/
|
|
24
|
-
|
|
25
|
-
/** The
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
signingIn: boolean;
|
|
29
|
-
/**
|
|
30
|
-
* Time left on the saved credentials: the login session when it can be renewed
|
|
31
|
-
* (`max_slt`, the latest renewal the server allows), else the access token.
|
|
32
|
-
*/
|
|
33
|
-
authLeft(): Promise<{
|
|
34
|
-
minutes: number;
|
|
35
|
-
renewable: boolean;
|
|
36
|
-
} | undefined>;
|
|
37
|
-
private renewing?;
|
|
38
|
-
/** The Cookie header for a request: only the access token, renewed first when it runs low. */
|
|
39
|
-
private cookie;
|
|
40
|
-
/**
|
|
41
|
-
* Trades the refresh token for new tokens and saves them before anything else. A refresh
|
|
42
|
-
* token works once, so several MCP processes sharing the file renew under one lock, and
|
|
43
|
-
* a process that waited uses the tokens another one just saved.
|
|
44
|
-
*/
|
|
45
|
-
private renew;
|
|
46
|
-
private usable;
|
|
24
|
+
refresh(): Promise<void>;
|
|
25
|
+
/** The access-key header for a request. */
|
|
26
|
+
private auth;
|
|
27
|
+
private rejected;
|
|
47
28
|
/**
|
|
48
29
|
* WebDAV request to a disk's project folder; callers interpret statuses other than 401.
|
|
49
30
|
* The storage gateway answers 502/503/504 now and then under load; requests that are
|
|
@@ -55,7 +36,7 @@ export declare class PlatformApi {
|
|
|
55
36
|
}): Promise<Response>;
|
|
56
37
|
/**
|
|
57
38
|
* Opens a build-log stream. It stays open while the build runs; the caller reads the
|
|
58
|
-
* body and aborts through `signal`. 401 becomes
|
|
39
|
+
* body and aborts through `signal`. 401 becomes needs_key; other statuses are returned.
|
|
59
40
|
*/
|
|
60
41
|
stream(path: string, signal: AbortSignal): Promise<Response>;
|
|
61
42
|
/** Backoff before each storage retry; tests shorten it. */
|