constructor-research-mcp 0.3.2 → 0.4.0-beta.1
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 +34 -50
- package/dist/api.d.ts +11 -30
- package/dist/api.js +53 -130
- package/dist/config.d.ts +8 -22
- package/dist/config.js +9 -45
- package/dist/deployment.d.ts +2 -0
- package/dist/deployment.js +26 -13
- package/dist/files.js +1 -1
- package/dist/key.d.ts +9 -0
- package/dist/key.js +35 -0
- package/dist/location.js +2 -1
- 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 +9 -104
- 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/dist/login.js +0 -25
- package/dist/session.d.ts +0 -21
- package/dist/session.js +0 -108
- package/dist/set-token.d.ts +0 -2
- package/dist/set-token.js +0 -48
- package/dist/signin.d.ts +0 -19
- package/dist/signin.js +0 -209
- /package/dist/{login.d.ts → set-key.d.ts} +0 -0
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,59 @@ 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
|
|
34
|
-
|
|
35
|
-
## Authentication and connection
|
|
36
|
-
|
|
37
|
-
Each harness signs in once and keeps its own Constructor session; nothing is stored centrally and nothing goes in the MCP settings. When a tool returns `needs_auth`, the agent tells the user a sign-in window is about to open and calls `sign_in`:
|
|
38
|
-
|
|
39
|
-
1. The MCP opens a separate browser window (Chrome, Edge, Chromium or Brave, on macOS, Windows or Linux; `CONSTRUCTOR_BROWSER` names another executable) with a fresh temporary profile at the Constructor sign-in page.
|
|
40
|
-
2. The user signs in. The MCP reads the session cookies, closes the window itself and deletes the profile.
|
|
41
|
-
3. It saves `ap_access_token`, `ap_id_token` and `ap_refresh_token` to that harness's session file and answers `signed_in`. No token is ever returned or printed.
|
|
42
|
-
|
|
43
|
-
The MCP works with one Constructor at a time: the one the user signed in to, recorded as a `host=` line in the session file. Before the first sign-in it is `https://constructor.app`, or the host of a desk link the user gave. For another Constructor (for example `https://acme.constructor.app`), the agent passes any link from it as `sign_in`'s `url`; the new sign-in replaces the old one, and the MCP works there from then on. A desk link from a different Constructor than the signed-in one returns `wrong_environment`, which tells the agent to sign in there with that link.
|
|
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.
|
|
44
36
|
|
|
45
|
-
|
|
37
|
+
## Access key and connection
|
|
46
38
|
|
|
47
|
-
The
|
|
48
|
-
|
|
49
|
-
The access token lasts an hour. When it has under 10 minutes left, the next request first renews it: `GET /auth/session` with only the refresh token, which answers with new tokens that are saved at once. Renewal runs under `<session file>.lock`, so processes sharing a file renew once and the others use the saved tokens. Requests send only the access token, so the gateway never renews behind the MCP's back. The server allows renewal until the `max_slt` claim, 14 days after sign-in; from a day before that, every response carries `auth_warning` asking the agent to have the user sign in again. If the refresh token was already used elsewhere, it is dropped and, once the access token expires, `needs_auth` explains why. A session is never sent to a Constructor other than the one it was signed in to.
|
|
50
|
-
|
|
51
|
-
The same sign-in from a terminal (use `codex` or `opencode` in place of `claude-code`, or `--to <file>`; `--url` names a Constructor other than constructor.app):
|
|
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:
|
|
52
40
|
|
|
53
41
|
```sh
|
|
54
|
-
npx -y -p constructor-research-mcp constructor-research-
|
|
55
|
-
npx -y -p constructor-research-mcp constructor-research-login --url https://acme.constructor.app --for claude-code
|
|
42
|
+
npx -y -p constructor-research-mcp@beta constructor-research-set-key https://acme.constructor.app
|
|
56
43
|
```
|
|
57
44
|
|
|
58
|
-
|
|
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.
|
|
59
46
|
|
|
60
|
-
|
|
61
|
-
npx -y -p constructor-research-mcp constructor-research-set-token capture.txt --for codex
|
|
62
|
-
```
|
|
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.
|
|
63
48
|
|
|
64
|
-
|
|
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`.
|
|
65
50
|
|
|
66
|
-
|
|
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.
|
|
67
52
|
|
|
68
|
-
| Variable | Default
|
|
69
|
-
| ----------------------------------- |
|
|
70
|
-
| `CONSTRUCTOR_BASE_URL` | unset: the
|
|
71
|
-
| `CONSTRUCTOR_API_PATH` | `/api/platform-account`
|
|
72
|
-
| `CONSTRUCTOR_STORAGE_PATH` | `/api/platform-storage`
|
|
73
|
-
| `
|
|
74
|
-
| `
|
|
75
|
-
| `CONSTRUCTOR_STATE_DIR` | `~/.local/state/constructor-research-mcp`
|
|
76
|
-
| `CONSTRUCTOR_UPLOAD_SETTLE_SECONDS` | `30`
|
|
77
|
-
| `CONSTRUCTOR_READINESS_SECONDS` | `60`
|
|
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_STATE_DIR` | `~/.local/state/constructor-research-mcp` |
|
|
61
|
+
| `CONSTRUCTOR_UPLOAD_SETTLE_SECONDS` | `30` |
|
|
62
|
+
| `CONSTRUCTOR_READINESS_SECONDS` | `60` |
|
|
78
63
|
|
|
79
|
-
HTTPS is required except on localhost.
|
|
64
|
+
HTTPS is required except on localhost.
|
|
80
65
|
|
|
81
|
-
##
|
|
66
|
+
## Thirteen tools
|
|
82
67
|
|
|
83
68
|
| Tool | Agent's task |
|
|
84
69
|
| ------------------------ | ----------------------------------------------------------------------------------- |
|
|
@@ -90,13 +75,12 @@ HTTPS is required except on localhost. API-key authentication is not implemented
|
|
|
90
75
|
| `build_image` | Build an image independently when needed. |
|
|
91
76
|
| `list_images` | List image IDs, Dockerfiles and native build statuses. |
|
|
92
77
|
| `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
78
|
| `create_folder` | Create a disk folder, including missing parents. |
|
|
95
79
|
| `sync_files` | Upload new and changed files; asks once before replacing existing files. |
|
|
96
80
|
| `move_path` | Rename or move files/folders in one batch, approved once; never overwrites. |
|
|
97
81
|
| `delete_path` | Delete files/folders in one batch; reports first, deletes only with `confirm:true`. |
|
|
98
82
|
|
|
99
|
-
No special clone/new-instance workflow is implemented. The
|
|
83
|
+
No special clone/new-instance workflow is implemented. The thirteen tools use the same standard MCP transport across harnesses.
|
|
100
84
|
|
|
101
85
|
## Where to act: the desk link
|
|
102
86
|
|
|
@@ -106,7 +90,7 @@ The agent does not choose a project or desk. It asks the user for the desk link:
|
|
|
106
90
|
https://constructor.app/research/projects/<project_id>/desks/<desk_id>/viewer/file
|
|
107
91
|
```
|
|
108
92
|
|
|
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
|
|
93
|
+
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
94
|
|
|
111
95
|
## Normal deployment flow
|
|
112
96
|
|
|
@@ -187,7 +171,7 @@ Replace a service's `build` with `"image_id":"IMAGE_ID"` to skip building. `list
|
|
|
187
171
|
|
|
188
172
|
## Missing prerequisites
|
|
189
173
|
|
|
190
|
-
- **No
|
|
174
|
+
- **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
175
|
- **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
176
|
- **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
177
|
|
|
@@ -234,11 +218,11 @@ Learned from live runs (28 Oct 2026):
|
|
|
234
218
|
|
|
235
219
|
## State and recovery
|
|
236
220
|
|
|
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.
|
|
221
|
+
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
222
|
|
|
239
223
|
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
224
|
|
|
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: `
|
|
225
|
+
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
226
|
|
|
243
227
|
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
228
|
|
|
@@ -256,10 +240,10 @@ Constructor serves logs only live, as a stream: a build log while the build runs
|
|
|
256
240
|
|
|
257
241
|
## Waiting for long builds
|
|
258
242
|
|
|
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,
|
|
243
|
+
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
244
|
|
|
261
245
|
```sh
|
|
262
|
-
npx -y -p constructor-research-mcp constructor-research-wait <deployment_id>
|
|
246
|
+
npx -y -p constructor-research-mcp@beta constructor-research-wait <deployment_id>
|
|
263
247
|
```
|
|
264
248
|
|
|
265
249
|
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 +271,7 @@ Use the executable directly to keep stdout reserved for MCP. `structuredContent`
|
|
|
287
271
|
|
|
288
272
|
## Disk files
|
|
289
273
|
|
|
290
|
-
The tools use the disk's WebDAV storage (`/api/platform-storage/desks/{disk}/dav/project/`) with the same
|
|
274
|
+
The tools use the disk's WebDAV storage (`/api/platform-storage/desks/{disk}/dav/project/`) with the same key. `sync_files`:
|
|
291
275
|
|
|
292
276
|
- 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
277
|
- 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. */
|