impreza-mcp 0.47.0 → 0.48.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/README.md CHANGED
@@ -1,855 +1,911 @@
1
- # impreza-mcp
2
-
3
- [Model Context Protocol](https://modelcontextprotocol.io) server for
4
- [Impreza Host](https://imprezahost.com). Lets AI coding tools (Claude
5
- Code, Cursor, Codex CLI, Continue, Zed, ...) deploy customer-built
6
- apps to managed Impreza VPSes without leaving the chat.
7
-
8
- When you say "deploy this for me" to Claude with this MCP server
9
- loaded, Claude calls `impreza_deploy_custom` directly — packages your
10
- project, uploads it, builds + runs on your Impreza VPS, and reports
11
- back the URL.
12
-
13
- ## Deployment progress and agent restarts
14
-
15
- Compose review and deployment accept
16
- `context_id` for one retained upload containing local build contexts and runtime
17
- `env_file`, configs or secrets. The same context must be supplied at review and
18
- deployment. Runtime files require agent 0.6.11+ with `compose-source-files-v1`.
19
-
20
- Custom Node server/static deployments
21
- accept `node_package_manager`, such as `pnpm@10.26.1` or `yarn@4.9.2`, matching the
22
- project's exact `packageManager` and committed lockfile. Omit for npm. Supported
23
- versions are standalone pnpm 10–12 and Yarn 4 projects, without combining
24
- this field with `npm_workspace`. Inspection infers the pin and saved plans retain
25
- it. See the deployment documentation for supported inputs and limits.
26
-
27
- Read `last_operation.progress` from `impreza_list_deployments` for the last
28
- reported step and timestamp. Agent 0.6.6+ saves final results before sending them;
29
- after restart it resends the same receipt without repeating the deploy.
30
- Agent 0.6.7+ can verify a completed preparation checkpoint and restore previous
31
- configuration without replaying the deploy (`recovery=reconciling`). Wait for the
32
- terminal failure or confirmed cancellation before retrying.
33
- `recovery=required` means automatic reconciliation could not be verified; contact
34
- support. Busy builds, missing checkpoints and replacement uncertainty stay blocked. A long-running build can
35
- continue after the agent exits. Progress is not a live percentage or proof of
36
- current runtime health. Existing agents update explicitly before the next deploy.
37
- See [deployment progress](https://docs.imprezahost.com/deployment-progress.html).
38
-
39
- ## Cancel a deployment
40
-
41
- Use `impreza_cancel_deployment` with the deployment ID and exact
42
- `last_operation.command_id`. Requires manage permission. Queued cancellation
43
- is immediate; running preparation needs agent 0.6.5+. Agent 0.6.12+ can interrupt an owned build after the server administrator
44
- enables controlled builds on supported Ubuntu 24.04 amd64 hosts. Other preparation
45
- waits for its current step. Confirmation still requires verified cleanup and restored
46
- configuration. `requested` is not `cancelled`. Replacement/recovery cannot
47
- be cancelled. Cancelling a tracking Task remains separate.
48
- Read [the cancellation guide](https://docs.imprezahost.com/deployment-cancellation.html).
49
-
50
- ## Runtime health and deployment operations
51
-
52
- `impreza_list_deployments` returns `runtime` and `last_operation` separately.
53
- A failed build can leave the previous application healthy. Read runtime state,
54
- observation time and reason; old or missing readings remain unknown.
55
- Running without a confirmed healthcheck is not healthy. This requires agent
56
- 0.6.4+ for observations and does not verify external HTTP/DNS/TLS. Existing
57
- servers update explicitly. See [runtime health](https://docs.imprezahost.com/runtime-health.html).
58
-
59
- ## Saved project plans and safe retries
60
-
61
- `impreza_plan_project` also accepts
62
- `git_url` and an exact 40-character `git_commit` instead of `context_id`.
63
- Optional `git_username` and `git_token` are used only for the fetch. The server
64
- captures an immutable retained archive, accounts for its upload quota, and
65
- returns `source.origin` alongside the archive SHA256. Review those values before
66
- preparing/applying the saved configuration. Only public-network HTTPS on port
67
- 443 is supported; redirects and submodules are refused. Project code is not
68
- executed by inspection. These options require the corresponding control-plane
69
- capabilities; update the local MCP package before using them.
70
-
71
- Use `impreza_plan_project` with a retained `context_id` to inspect the archive
72
- inventory and selected configuration files. Choose `project_dir`,
73
- `dockerfile_path`, a Python `start_command` or `php_document_root` as needed.
74
- Review the findings and `analysis.deployment_options`.
75
-
76
- With MCP **0.32.0+**, call `impreza_prepare_project_deployment` with `plan_id`,
77
- zero-based `option_index`, app name, server and runtime settings. It validates
78
- and saves the effective configuration without creating an app, job or DNS
79
- record. Review the returned configuration, then call
80
- `impreza_apply_project_deployment` with only `execution_id` and
81
- `configuration_digest`. Later form/request changes cannot override that record.
82
-
83
- A repeat of the same saved deployment returns its original acceptance receipt,
84
- including after expiry or app removal. The receipt, app and queue job commit
85
- together. After an uncertain response, retry the same ID and digest instead of
86
- preparing another deployment. Acceptance means queued; inspect app status,
87
- logs and health. This does not restart a failed job or update an existing app.
88
-
89
- `impreza_list_prepared_deployments` lists the latest 20 saved configurations or
90
- retrieves one `execution_id`. Environment values are encrypted in the prepared
91
- record, omitted from review responses and cleared from that record on acceptance;
92
- the app then uses its normal environment storage. Reviews show variable names.
93
- Use at most 100 string values, with no system/routing variable overrides.
94
-
95
- At most 20 pending records per account, valid no longer than the source plan
96
- and for at most 24 hours. Source, rules, target availability/IP and effective
97
- settings are rechecked before first apply. There is no domain, port or capacity
98
- reservation, dependency pinning or build guarantee. DNS is external to the app
99
- transaction and can remain after an interrupted attempt. Expired pending records
100
- are removed on the account's next preparation; accepted receipts are retained.
101
-
102
- Source inspection remains available in MCP 0.31.0+. The older
103
- `impreza_deploy_project_plan` creates directly from an option and is not
104
- idempotent. Plan creation requires deploy scope; listing requires read scope;
105
- preparation/apply require deploy scope. These account-wide tools require
106
- credentials without resource restrictions. No agent update is needed solely for
107
- this flow; recipe requirements still apply. See the
108
- [project plan and review guide](https://docs.imprezahost.com/project-plans.html).
109
-
110
- ## Retained source uploads
111
-
112
- Use `impreza_upload_context` with `dir` and an optional `label` to upload an immutable
113
- source version without deploying. The response includes its `context_id`, SHA256,
114
- size and expiry. List or inspect versions with `impreza_list_contexts`.
115
-
116
- Create an app with `impreza_deploy_custom`, `mode: "dockerfile"` and `context_id`
117
- (or deploy a local `dir` directly). Rebuild it with `impreza_redeploy_deployment`
118
- and optionally another retained `context_id`. The app identity, domain, host port,
119
- volumes and build recipe stay fixed. The selected source can differ from the
120
- running release after failure or rollback; inspect deployment history.
121
-
122
- Sources in use remain available. Unreferenced versions expire seven days after
123
- upload or their last deployment request, not seven days after detachment. Default
124
- quotas are 10 unexpired/referenced archives, 300 MiB per account and 100 MiB per
125
- archive; referenced sources count. Delete an unused version with
126
- `impreza_delete_context`, `context_id` and `confirm: true` after customer confirmation.
127
- Metadata requires read scope, upload requires deploy, and deletion requires
128
- manage. Resource-confined credentials cannot manage account uploads.
129
-
130
- The packer excludes common dependency/VCS folders, .env and .env.* (except
131
- example/sample/template files), .npmrc and .pypirc. It does not scan arbitrary
132
- secrets or interpret .gitignore/.dockerignore; review what you upload. Portal
133
- archives are sent unchanged. Legacy REST uploads remain temporary unless they
134
- opt into `retain=true`. Older uploaded-source apps can migrate by selecting a
135
- fresh retained context on redeploy. These MCP tools require 0.22.0+; no agent
136
- update is needed solely for source retention. See the
137
- [source upload guide](https://docs.imprezahost.com/source-uploads.html).
138
-
139
- ## Node.js npm builds
140
-
141
- Deploy an independent npm HTTP application without a repository Dockerfile using
142
- `impreza_deploy_custom` with `mode: "dockerfile"`, `build_strategy: "node_npm"`,
143
- `git_url` (or local `dir`), and `target_port` (usually 3000).
144
- The API generates a Node 24 recipe: npm ci, optional build script, production
145
- pruning and npm start as a non-root user. The selected project folder must contain package.json, package-lock.json
146
- and a production start script. Docker Compose 2.17+ and BuildKit
147
- must be available on the server. Select npm workspaces explicitly with
148
- `npm_workspace`. Use `build_secrets` for named credentials and the `npmrc` secret
149
- for private npm installation; agent 0.6.11+ is required. The app must listen on 0.0.0.0 and the
150
- configured port. Keep runtime PORT consistent with that port.
151
-
152
- Git redeploys and previews reuse the recipe snapshot. Retained uploaded sources
153
- support reuse and source-version selection; older temporary uploads remain single-use. The recipe excludes .git, node_modules, .env,
154
- .env.* and .npmrc from the source copy; this does not scan arbitrary secrets.
155
- Keep credentials out of source code. The HTTP startup probe accepts responses
156
- below 500 at / and is not a functional application test.
157
-
158
- ## Public build variables
159
-
160
- Required healthy start: opt in with require_healthy_start=true, an explicit healthcheck_path and build_strategy=node_npm. In the portal, enable Require a healthy start. Agent 0.6.3 or newer must be reported in Servers; update it explicitly and wait for the next heartbeat. startup_timeout_seconds accepts an integer from 30 to 600, default 60. The budget starts after containers are created and includes the stable health observation; Git fetch, dependency/image builds and recovery have separate time limits. Every running service must report Docker healthy and at least one serving container must exist. HTTP redirects, authentication errors and timeouts do not pass the configured 2xx probe. When the first install fails, its containers are removed and persistent volumes are preserved; the failure includes diagnostic logs. A failed replacement recovers a verified healthy previous release when available. Recovery and manual rollback use the saved release startup policy, so a slow healthy release retains its original deadline. Failure recovery does not undo database writes or mutable data. The control plane refuses incompatible agents at creation, never dispatches the policy without startup-health-v1 support in the current poll, and accepts success only with a matching health confirmation. Previews inherit the policy; redeploy keeps the snapshot. Deployment reads expose startup_health. Choose a new deployment to change the saved policy. Omission or false preserves legacy behavior; a startup timeout requires the option enabled. The public option is for generated Node builds. This does not provide zero-downtime switching or continuous automatic rollback after startup. Local MCP input support requires 0.20.0+. Existing agents update only when the customer runs the updater. See https://docs.imprezahost.com/tutorials/agent-apps-panels.html#required-startup
161
-
162
- Node health checks: with build_strategy=node_npm, optionally set healthcheck_path (for example /health or /api/ready), or fill Health check path in the portal. The generated Docker health check sends HTTP GET to 127.0.0.1 on target_port inside the container and requires status 200-299; it does not follow redirects or send credentials. The route must work without login and should report the dependencies your app needs to serve requests. Use / or a path of at most 200 ASCII characters; segments start with a letter, digit, underscore or hyphen and may then include dots or tildes. A trailing slash is allowed. URLs, query strings, fragments, percent escapes, spaces, parent segments and repeated slashes are refused. Omit the field (leave it blank in the portal) to keep the legacy / probe accepting statuses below 500; explicitly setting / requires 2xx. Existing deployment snapshots remain unchanged. The saved healthcheck_path is returned by deployment reads, inherited by new previews and retained on redeploy; changing it requires a new deployment. Static sites keep their index.html probe; custom Dockerfiles define their own HEALTHCHECK. The probe runs every 5 seconds with a 2-second request timeout. With required startup disabled, agents 0.6.2 and later observe startup for up to 60 seconds: a failed replacement recovers a verified healthy previous release when one exists. Without that recovery target, a first install can still complete with a startup warning, so inspect health and logs before treating it as ready. This default policy does not provide continuous rollback, zero-downtime routing or external uptime checks. To enforce a startup deadline, enable required healthy startup with agent 0.6.3+. Local MCP inputs require 0.19.0+; healthcheck_path alone needs no agent update beyond 0.6.2.
163
-
164
- Public build settings: generated node_npm and node_npm_static recipes accept public_build_vars, an object of string values available only to npm run build (including its prebuild/postbuild scripts). For example, {"VITE_API_URL":"https://api.example.com"} lets Vite compile a public API URL into the site. Names must start with VITE_, NEXT_PUBLIC_ or PUBLIC_, contain only uppercase letters, digits and underscores, and be at most 128 characters. Limits: 20 entries, 4096 UTF-8 bytes per value and 16384 bytes for names plus values. Empty strings are preserved; NUL is refused. Values are literal data, without shell or variable expansion. The portal exposes Public build variables as KEY=value lines; do not add surrounding quotes, which would become part of the value. These values are public and may appear in bundles, image metadata and logs: never send passwords, tokens or secrets. They are not supplied to npm ci or automatically added to runtime variables. Runtime vars still configure the running container and do not rewrite compiled browser files. Settings are saved at creation, exposed on deployment reads, inherited by new previews and reused on redeploy. Preview runtime inheritance/overrides do not change this build snapshot; create a separate deployment for different public build values. Existing snapshots default to no public build values. Use build_secrets for supported build credentials with agent 0.6.11+; unsupported build settings require a custom Dockerfile. Local MCP requires 0.18.0+; no agent update is required beyond the existing build executor.
165
-
166
- See the [build configuration guide](https://docs.imprezahost.com/tutorials/agent-apps-panels.html#public-build-settings).
167
-
168
- ## Apps in project subfolders
169
-
170
- Deploy an independent npm app from a subfolder: set project_dir (default .) with node_npm or node_npm_static, or choose Project folder in the portal. For example, apps/site must contain its own package.json and matching package-lock.json; static_output_dir is relative to that folder. Only the selected folder is copied into /app for npm installation and builds. The repository/upload remains the Docker build context, so its root .dockerignore still applies. Paths allow up to 120 characters and five non-hidden segments; parent, node_modules and symlink components are refused. Missing folders or failed builds retain the previous healthy runtime. The project_dir value is returned by deployment reads, saved at creation and inherited by new previews; redeploy reuses the saved recipe. Existing snapshots default to .; changing the folder requires a new deployment. This supports independent apps in one repository, not shared workspaces or dependencies outside the folder; use a custom Dockerfile for those. The analyzer does not discover subfolders: supply the selected app metadata and review Project folder yourself. Local MCP requires 0.17.0+; no agent upgrade is required beyond the existing build executor.
171
-
172
- See the [project folder guide](https://docs.imprezahost.com/tutorials/agent-apps-panels.html#project-folder).
173
-
174
- ## Import a Compose stack
175
-
176
- Use `impreza_prepare_compose` with `compose_yaml`, then explicitly select
177
- `web_service` and the integer `target_port`. Review services, persistent
178
- volumes, required variables, changes and blockers before deploying with
179
- `impreza_deploy_custom`, `mode: "compose"`, the same YAML/service/port and
180
- `compose_review_id` set to the returned `analysis_id`.
181
-
182
- Supports self-contained public-image stacks with up to 12 services, private
183
- bridge networks, local named volumes and service dependencies. Original host
184
- port bindings are removed; only the selected HTTP service joins the proxy and
185
- receives a managed loopback port. Container and volume names become specific
186
- to the deployment. Declare CPU/memory limits per service in YAML.
187
-
188
- The review does not fetch images, execute code or reserve resources. Local build
189
- contexts and auxiliary files require the same retained context_id at review and
190
- deploy. Runtime env_file accepts literal assignments only, without interpolation
191
- or inherited bare keys. Aliases, profiles, host privileges and external resources
192
- are outside this import subset. Reference uppercase variables instead of
193
- embedding secrets. Runtime values must be single-line strings up to 4 KiB,
194
- without surrounding whitespace, quotes, backslashes, dollar signs or space
195
- followed by #. Variables supply explicit references, not every service's
196
- environment. Required values are checked at creation, editing and redeploy.
197
-
198
- The imported source is saved as a manifest. Redeploy reuses it and the named
199
- data; changing the source/topology requires a new deployment. Failure recovery
200
- uses the existing agent policy and does not undo database writes. Local MCP
201
- support for public-image stacks requires 0.21.0+. Retained build/runtime sources
202
- require MCP 0.34.0+ and agent 0.6.11+.
203
- See the [Compose import guide](https://docs.imprezahost.com/compose-import.html).
204
-
205
- ## Prepare project configuration
206
-
207
- Use `impreza_prepare_project` with `package_json`, `dockerfile`, and optional
208
- `dockerfile_path` before deploying. It returns framework hints, available build
209
- and start commands, explicit ports from the final Dockerfile stage, and findings
210
- to review. Each file is limited to 32 KiB. Review files for credentials before
211
- sending; never submit .env files or secrets.
212
-
213
- This is advisory analysis of supplied text. It does not fetch a repository,
214
- execute code, generate a Dockerfile or deploy resources. Git deploys use a Dockerfile by default; supported npm projects can opt into the Node recipe. The analysis ID identifies metadata, not an executable plan.
215
- Requires an API exposing /v1/platform/deployments/custom/prepare.
216
-
217
- ## Why this host and not a mainstream one
218
-
219
- Any provider can run your app. This one is built so an **agent can obtain and
220
- operate infrastructure that is not tied to your identity**, end to end, without
221
- you opening a browser:
222
-
223
- - **No KYC, and no email address, to open an account.** An account is a
224
- generated client ID plus a recovery token. No documents, no selfie, no phone
225
- number.
226
- - **Funded in cryptocurrency.** `impreza_topup` accepts BTC, XMR, USDT and TRX,
227
- and `impreza_order_vps` buys the server from that balance. The agent can go
228
- from "I need a server" to a running deployment without a card.
229
- - **Offshore and onshore jurisdictions side by side**, chosen per project
230
- rather than per account.
231
- - **Tor is a deployment target, not an add-on.** `impreza_add_onion` gives a
232
- deployment a `.onion` address in one call, so an agent can publish a hidden
233
- service the same way it publishes a normal site. `impreza_onion_auth_*`
234
- manage Tor v3 restricted discovery (client authorization): private keys
235
- never leave the customer's Tor client unless they ask the server to
236
- generate a keypair — and then the private key is shown once, never stored.
237
- - **No API key in your config.** The hosted connector authenticates over OAuth.
238
-
239
- If none of that matters for your project, a mainstream provider is a perfectly
240
- good choice and usually cheaper to start with. This exists for the projects
241
- where it does matter: research and journalism under pressure, censorship
242
- circumvention, security work, and anything that should not be one support
243
- ticket away from being linked to a legal name.
244
-
245
- ## Retained-release rollback
246
-
247
- The source tree adds `impreza_rollback_deployment`. Read a deployment's
248
- `release_history` through `impreza_api_call` at
249
- `/platform/deployments/{id}`, then choose a `rel_...` entry with
250
- `rollback_supported: true`.
251
-
252
- Explain the selected release and possible interruption to the customer before
253
- calling the tool with `deployment_id`, `target_version` and `confirm: true`.
254
- The hosted connector uses its two-call `confirm_token` flow instead.
255
- The operation requires `manage` scope and a compatible API and agent.
256
-
257
- A historical release may no longer be retained. The agent checks local images
258
- and unchanged ports, storage and routing before replacing containers. It saves
259
- the current healthy runtime and attempts recovery if the selected release fails
260
- startup. Database contents and mutable data are not reverted. A queued response
261
- does not confirm restoration; check deployment history for the result.
262
-
263
- Available in impreza-mcp 0.12.0. Requires a compatible API and agent.
264
-
265
- ## Static npm sites
266
-
267
- Static npm sites: choose build_strategy=node_npm_static with a Git/context source (mode=dockerfile), or Static site + npm in the portal. Requires an independent npm package in the selected project folder, matching package-lock.json and a build script producing index.html in the selected output folder. Node 24 installs dependencies and runs the build; unprivileged Nginx serves only the selected output folder with configurable SPA fallback. No start script is required. Default target_port is 8080. Compose 2.17+ and BuildKit required. No SSR or server functions. Explicit npm_workspace and build_secrets are supported with their documented source and agent requirements. Runtime variables (including VITE_* and PORT) do not rewrite static bundles or change the configured Nginx port. Use static_output_dir (default dist) to choose a relative output folder containing index.html, and static_spa (boolean, default true) to choose SPA fallback or 404 for unknown routes. The portal exposes both fields. Paths are limited to 120 characters and five segments, without hidden, parent or node_modules segments; symlinks in the output or its parent path are refused. These settings are chosen at creation, stored in the recipe snapshot, exposed as static_options and carried to new previews. Redeploy reuses the saved recipe; changing these settings on existing deployments requires creating a new deployment. Existing snapshots keep their original recipe. Local MCP option inputs require 0.16.0+. Use public_build_vars for supported public settings; other build-time configuration requires a custom Dockerfile. Source .env/.env.*/.npmrc/.git/node_modules are excluded; review all generated files because the output folder is public. Missing index.html and symlink output fail the build. Existing preview/redeploy snapshots preserve the strategy. Local MCP requires 0.15.0+; no agent upgrade is needed beyond the existing build executor. The analyzer returns static_npm_recipe and conditional deployment_options; metadata is not proof of a static, working build.
268
-
269
- ## Status
270
-
271
- **Package version: 0.47.0.** The tool catalog covers app deployment plus account +
272
- crypto balance, catalog + ordering, domains/DNS + registration, invoices, VPS
273
- lifecycle with snapshots and backups, dedicated / bare-metal servers, plan
274
- upgrades, and Titan / Google Workspace mailboxes — with a setup wizard that
275
- generates ready-to-paste config snippets for 5 AI tools.
276
-
277
- On top of that, everything an app needs after it is running: backup and
278
- restore into the customer's **own** S3 bucket, a timer on an app with its
279
- output kept, outbound webhooks so you stop polling, reading the app's own
280
- files, and running the app's own command line.
281
-
282
- The local (`npx`) server and the hosted OAuth connector expose the **same tool
283
- catalog — 196 tools on both sides**. Declared, one-direction gaps remain:
284
- `impreza_get_log_request` stays hosted-only (only the control plane resolves a
285
- bare `request_id`; locally, call `impreza_tail_logs` again on the application —
286
- requests dedupe); `impreza_list_approvals`, `impreza_get_approval` and
287
- `impreza_get_credential_policy` are hosted-first (locally, the same reads are
288
- REST calls through `impreza_api_call`); and `impreza_upload_context` stays
289
- local-only (binary tarball streaming does not fit the hosted transport).
290
-
291
- ### New in 0.11.0
292
-
293
- **Run the app's own command line.** WP-CLI for WordPress, `occ` for
294
- Nextcloud, `gitea admin` for Gitea, and the database client for a dump —
295
- `impreza_app_cli` to run, `impreza_get_cli_run` to collect the output. Call
296
- `impreza_get_cli_run` with no `run_id` first: it names the command lines the
297
- app has, says what each is for, and gives one example that works.
298
-
299
- - **No docker socket, and that is measured rather than claimed.** The command
300
- runs in a separate container built from the app's own image, joined to the
301
- app's own network, with its data mounted — the shape the official CLI
302
- images are designed for. `cap_drop: ALL`, and no new privilege on the
303
- machine.
304
- - **Arguments are a list, never a string.** Each element becomes one `argv`
305
- entry through `execve`, so nothing is split, globbed or substituted:
306
- quoting is not your problem, and a `$` or a `;` inside a value is just
307
- that. Verified against a live site — `option update blogname
308
- 'dollars $HOME and a ; semicolon'` reads back exactly as sent.
309
- - **Destructive, and treated as such.** A command line can do anything the
310
- app itself can, so it needs the `manage` scope and is confirmation-gated.
311
- Arguments are free rather than allowlisted: that is the same ceiling
312
- `uninstall` with `purge_data` already sits at, and a list of `wp`
313
- subcommands would age badly while protecting nothing the confirmation gate
314
- does not.
315
- - **The CLI version follows the app.** Where the command line is the app's
316
- own image it is taken from that deployment, so a catalog bump carries it —
317
- running `occ` from an older Nextcloud against a newer database is how a
318
- maintenance command corrupts an install.
319
-
320
- Custom deployments have no command line here: it is your own image and the
321
- platform cannot know what it ships. Use a scheduled task of kind `command`
322
- for those.
323
-
324
- ### New in 0.10.0
325
-
326
- **Look inside the app's own files.** `impreza_get_logs` reads stdout, which
327
- cannot answer the question a deploy that came up wrong actually raises: did
328
- that variable reach the config file? Two tools now do —
329
- `impreza_inspect_app` to ask and `impreza_get_app_read` to collect the answer.
330
-
331
- - **Four actions, and no fifth:** `list` a directory, `read` a file (capped at
332
- 256 KB), `tail` its last lines, `grep` under a path with an extended regular
333
- expression. There is no command string in the interface, and therefore no
334
- shell.
335
- - **Read-only by construction.** A one-shot container mounts the app's storage
336
- read-only — the same mechanism the backup already uses — with no docker
337
- socket and no write capability. So it also works on an app that is `failed`
338
- and will not start, which is when it is wanted most.
339
- - **Only the app's own storage:** `data`, or one of the named volumes the app's
340
- manifest declares (a WordPress exposes `data` and `wp_db`, so its database
341
- files are readable too). Call `impreza_get_app_read` with no `read_id` to
342
- see the list for a given app.
343
- - **What comes back is untrusted and often secret** — an app's config file is
344
- where its database password lives. It reaches you and nothing else: the
345
- field is on our request log's deny list, and the record is deleted within a
346
- day.
347
-
348
- ### Since 0.6.1
349
-
350
- Three releases the npm page never described, each one a whole capability:
351
-
352
- - **0.7.0 — backup and restore** of a deployment's data into the account's own
353
- Impreza S3 bucket, with a per-chunk SHA-256 manifest that sits beside the
354
- data so the copy stays verifiable with the customer's own credentials and no
355
- call to us. Plus a schedule (daily by default, keeping 3), and a restore
356
- that can land in a *different* app, which is how an app moves between
357
- servers.
358
- - **0.8.0 — scheduled tasks:** a timer on an app with the output kept, for the
359
- apps that need one to behave correctly (Nextcloud's cron, WordPress's
360
- `wp-cron` on a site with no visitors).
361
- - **0.9.0 — outbound webhooks:** subscribe to deploy, backup and VPS events
362
- and stop polling, with HMAC-signed delivery and a delivery log.
363
-
364
- ### New in 0.6.1
365
-
366
- **`tools/list` now reflects what your account actually owns.** About a third of
367
- the tools only make sense if you have the machine behind them — VPS power
368
- controls with no VPS can only ever answer "not found" — so those are left out
369
- of the listing until you own one. Typical accounts see around 70 tools instead
370
- of 97, which is roughly six thousand fewer tokens of context spent before you
371
- ask anything.
372
-
373
- Three things worth knowing about how it behaves:
374
-
375
- - **The purchase path is never filtered.** An account that owns nothing is the
376
- one that needs to buy something, so ordering, top-up, invoices and the
377
- catalogue are always listed.
378
- - **Buying something grows the list mid-session.** The server sends
379
- `notifications/tools/list_changed` on the same response as the order, so a
380
- client that honours it picks up the new tools without reconnecting.
381
- - **It fails open.** If this server cannot reach the API to ask, it lists
382
- everything rather than guess.
383
-
384
- Hiding a tool is not an authorization boundary — the API still refuses anything
385
- your account does not own. This only stops the listing from carrying tools that
386
- could never work for you.
387
-
388
- ### New in 0.6.0
389
-
390
- Four things that only make sense on a host built for anonymity:
391
-
392
- - **Dark previews** — push a branch, get a preview on its own ephemeral Tor
393
- `.onion`. Every other platform's preview URL puts your branch name into
394
- public DNS and into a permanent Certificate Transparency log; branch names
395
- carry ticket ids, customer names and unshipped features. This one creates
396
- neither record, and destroys its keys when the branch is deleted or the TTL
397
- runs out. `impreza_configure_previews`, `impreza_list_previews`,
398
- `impreza_retire_preview`.
399
- - **Agent sub-credentials** — mint a narrower credential from the one you hold
400
- and hand it to a subtask: one deployment, one hour, no spending. A child can
401
- never exceed its parent on any axis, and revoking a credential revokes
402
- everything it minted, however deep. `impreza_mint_subcredential`,
403
- `impreza_list_credentials`, `impreza_revoke_credential`,
404
- `impreza_agent_activity`.
405
- - **A privacy report you can check** — `impreza_privacy_report` returns every
406
- field we store about your account, what it is for, how long it survives and
407
- who else sees it, and then measures our own retention against the oldest
408
- record that actually survived. Counts and date ranges, never contents.
409
- - **Ask before you guess** — search our docs, validate a deployment manifest
410
- before deploying it (including a privacy lint for third-party CDNs, public
411
- DNS resolvers and leaked secrets), or run a diagnosis when something is
412
- wrong. `impreza_search_docs`, `impreza_validate_manifest`, `impreza_doctor`.
413
-
414
- Plus the Tasks extension, so long operations report completion instead of
415
- leaving you to poll, and three MCP Apps panels — a payment card, a server card
416
- and a deploy wizard — that render inside clients which support them.
417
-
418
- The table below is a **selection**, not the full list — it covers the tools
419
- most people reach for first. Your client's own tool listing is authoritative,
420
- and `impreza_api_search` finds anything not named here.
421
-
422
- | Tool | Wraps |
423
- |------|-------|
424
- | **Apps & deployments** | |
425
- | `impreza_list_servers` | `GET /v1/platform/servers` |
426
- | `impreza_list_apps` | `GET /v1/platform/apps` |
427
- | `impreza_list_deployments` | `GET /v1/platform/deployments` + `/custom` (merged) |
428
- | `impreza_upload_context` | `POST /v1/platform/deployments/custom/contexts?retain=true` |
429
- | `impreza_list_contexts` | `GET /v1/platform/deployments/custom/contexts[/{context_id}]` |
430
- | `impreza_delete_context` | `DELETE /v1/platform/deployments/custom/contexts/{context_id}` |
431
- | `impreza_deploy_custom` | `POST /v1/platform/deployments/custom` (3 modes) |
432
- | `impreza_deploy_catalog_app` | `POST /v1/platform/deployments` |
433
- | `impreza_uninstall_deployment` | `POST .../uninstall` |
434
- | `impreza_get_logs` | `POST .../logs` (sync tail, last N lines) |
435
- | `impreza_restart_deployment` | `POST .../restart` |
436
- | `impreza_redeploy_deployment` | `POST .../custom/{id}/redeploy` (in-place rebuild, same domain) |
437
- | `impreza_add_onion` | `POST .../onion/add` |
438
- | `impreza_set_onion_profile` | `POST .../onion/profile` (`standard` / `hardened` / `max` hardening tiers) |
439
- | `impreza_export_onion_key` | `POST .../onion/export` (sealed to your X25519 key; plaintext never transits) |
440
- | `impreza_fetch_onion_key_export` | `GET .../onion/export/{command_id}` (read-once — the blob is burned) |
441
- | `impreza_rotate_onion_key` | `POST .../onion/rotate` (new .onion; the old address dies) |
442
- | `impreza_onion_auth_list` | `GET .../onion/clients` |
443
- | `impreza_onion_auth_add` | `POST .../onion/clients` (`pubkey`, or `generate:true` → `private_key` shown once) |
444
- | `impreza_onion_auth_revoke` | `DELETE .../onion/clients/{name}` |
445
- | `impreza_change_domain` | `POST .../domain` |
446
- | `impreza_git_webhook_status` | `GET .../custom/{id}/git-webhook` |
447
- | `impreza_git_webhook_connect` | `POST .../custom/{id}/git-webhook/connect` |
448
- | `impreza_git_webhook_disconnect` | `POST .../custom/{id}/git-webhook/disconnect` |
449
- | **Account & balance** | |
450
- | `impreza_account_info` | `GET /v1/account` |
451
- | `impreza_list_services` | `GET /v1/account/services` |
452
- | `impreza_topup` | `POST /v1/account/topup` — top up in BTC / XMR / USDT / TRX |
453
- | `impreza_topup_status` | `GET /v1/account/topup/{invoice_id}` |
454
- | `impreza_topup_payment` | `GET /v1/account/topup/{invoice_id}/payment` — crypto address + amount to pay |
455
- | **Catalog & ordering** | |
456
- | `impreza_list_products` | `GET /v1/products` — products + pricing; the VPS is listed at its smallest size (`configurable: true`) |
457
- | `impreza_vps_offer` | `GET /v1/products/vps` — VPS locations, operating systems, CPU / memory / disk ranges and prices; with a whole configuration, `GET /v1/products/vps/quote` — its exact price |
458
- | `impreza_order_vps` | `POST /v1/orders` — a VPS by location, OS and size (or a fixed plan by `product_id`); paid from balance; born deployable (`@agent`); 202 + poll `impreza_list_servers` |
459
- | **Domains & DNS** | |
460
- | `impreza_domain_check` | `GET /v1/domains/check` |
461
- | `impreza_domain_details` | `GET /v1/domains/{domain}` |
462
- | `impreza_list_dns` | `GET /v1/domains/{domain}/dns` |
463
- | `impreza_add_dns_record` | `POST /v1/domains/{domain}/dns` |
464
- | `impreza_update_dns_record` | `PUT /v1/domains/{domain}/dns` |
465
- | `impreza_delete_dns_record` | `DELETE /v1/domains/{domain}/dns` |
466
- | `impreza_set_nameservers` | `PUT /v1/domains/{domain}/nameservers` |
467
- | **VPS lifecycle** (Proxmox) | |
468
- | `impreza_vps_status` | `GET /v1/vps/proxmox/{id}/status` |
469
- | `impreza_vps_power` | `POST /v1/vps/proxmox/{id}/{start\|shutdown\|reboot\|stop}` |
470
- | `impreza_vps_list_backups` | `GET /v1/vps/proxmox/{id}/backups` |
471
- | `impreza_vps_create_backup` | `POST /v1/vps/proxmox/{id}/backups` |
472
- | `impreza_vps_list_templates` | `GET /v1/vps/proxmox/{id}/templates` |
473
- | `impreza_vps_reinstall` | `POST /v1/vps/proxmox/{id}/reinstall` — destructive (wipes) |
474
- | `impreza_vps_resize` | `POST /v1/services/{id}/resize` — more vCPU, memory or disk at the pro-rated price (quote first with `GET /v1/services/{id}/resize/quote`); `max_amount` pins it |
475
-
476
- ## Install + setup
477
-
478
- ### Prerequisites
479
-
480
- - Node ≥ 20
481
- - An Impreza Host account with an API key + secret
482
- (clientarea → API Keys; the IP of the machine running this MCP
483
- server must be whitelisted under the key)
484
-
485
- ### One-shot via `npx`
486
-
487
- No global install needed — `npx impreza-mcp` works.
488
-
489
- ### Or install globally
490
-
491
- ```sh
492
- npm install -g impreza-mcp
493
- ```
494
-
495
- ### Get a ready-to-paste config snippet
496
-
497
- The fastest path: ask the binary itself.
498
-
499
- ```sh
500
- npx impreza-mcp setup --tool claude-code
501
- # also: cursor | continue | zed | codex-cli
502
- ```
503
-
504
- The wizard prints the JSON block to drop into your AI tool's MCP
505
- config + the exact file path + the post-config step (usually "fully
506
- quit + re-open the AI tool"). It does NOT write to disk — paste it
507
- yourself so you don't accidentally clobber an existing config with
508
- other MCP servers.
509
-
510
- ### Or wire it in manually
511
-
512
- **Claude Code** — add to `~/Library/Application Support/Claude/claude_desktop_config.json`
513
- (macOS) or `%APPDATA%/Claude/claude_desktop_config.json` (Windows):
514
-
515
- ```json
516
- {
517
- "mcpServers": {
518
- "impreza": {
519
- "command": "npx",
520
- "args": ["-y", "impreza-mcp"],
521
- "env": {
522
- "IMPREZA_API_KEY": "imp_...",
523
- "IMPREZA_API_SECRET": "..."
524
- }
525
- }
526
- }
527
- }
528
- ```
529
-
530
- Restart Claude Code. The tools appear under the MCP icon.
531
-
532
- **Cursor** — add to `~/.cursor/mcp.json` (same shape as above).
533
-
534
- **Continue** — add to `~/.continue/config.json`:
535
-
536
- ```json
537
- {
538
- "experimental": {
539
- "modelContextProtocolServers": [
540
- {
541
- "transport": {
542
- "type": "stdio",
543
- "command": "npx",
544
- "args": ["-y", "impreza-mcp"],
545
- "env": {
546
- "IMPREZA_API_KEY": "imp_...",
547
- "IMPREZA_API_SECRET": "..."
548
- }
549
- }
550
- }
551
- ]
552
- }
553
- }
554
- ```
555
-
556
- **Zed** — add to your settings:
557
-
558
- ```json
559
- {
560
- "context_servers": {
561
- "impreza": {
562
- "command": {
563
- "path": "npx",
564
- "args": ["-y", "impreza-mcp"],
565
- "env": {
566
- "IMPREZA_API_KEY": "imp_...",
567
- "IMPREZA_API_SECRET": "..."
568
- }
569
- }
570
- }
571
- }
572
- }
573
- ```
574
-
575
- ## Usage in chat
576
-
577
- After setup, talk to your AI naturally:
578
-
579
- > *"List my Impreza servers."* → calls `impreza_list_servers`
580
- >
581
- > *"Deploy this directory to my Impreza VPS, expose via .onion."* →
582
- > packages the cwd as a Dockerfile-mode custom deploy, uploads, deploys
583
- > with `onion=true`, reports the .onion address.
584
- >
585
- > *"What apps are running on my agent?"* → calls
586
- > `impreza_list_deployments` filtered to the right server.
587
-
588
- ## Auth + security
589
-
590
- `IMPREZA_API_KEY` + `IMPREZA_API_SECRET` live in the AI tool's MCP
591
- config env — not in any file on disk owned by `impreza-mcp` itself.
592
- The MCP server holds the secret only in memory and only attaches it
593
- as HTTP request headers.
594
-
595
- The IP of the machine running this MCP server (almost always your
596
- laptop) must be on the API key's whitelist. Manage the whitelist in
597
- your Impreza clientarea.
598
-
599
- ## Using over Tor
600
-
601
- The MCP server can route every API call through a local Tor daemon, so
602
- API requests use the configured proxy. Your network provider can still observe
603
- your connection to Tor; this option does not hide that you are using Tor.
604
-
605
- 1. Install and start Tor (the `tor` daemon, or Tor Browser — both
606
- commonly expose a SOCKS5 listener on `127.0.0.1:9050` for the daemon
607
- or `127.0.0.1:9150` for Tor Browser; check your local configuration).
608
- 2. Add `IMPREZA_PROXY` to the MCP config env:
609
-
610
- ```json
611
- "env": {
612
- "IMPREZA_API_KEY": "imp_...",
613
- "IMPREZA_API_SECRET": "...",
614
- "IMPREZA_PROXY": "socks5://127.0.0.1:9050"
615
- }
616
- ```
617
-
618
- Every API request then exits through Tor, and the API hostname is
619
- resolved by Tor itself (remote DNS) — nothing is resolved locally, so
620
- no DNS leak. The transport fails closed: if the proxy is unreachable
621
- or refuses the connection, the request fails — it never silently falls
622
- back to a direct clearnet connection.
623
-
624
- Optionally point `IMPREZA_BASE_URL` at the API's `.onion` mirror —
625
- `http://` is accepted only for v3 `.onion` hosts, since Tor authenticates and
626
- encrypts onion connections. Clearnet hosts require `https://`. An onion URL
627
- also requires an explicit `IMPREZA_PROXY`; the client refuses direct DNS and
628
- connections even when the onion URL uses HTTPS. Proxy requests refuse redirects,
629
- use a bounded request deadline and accept response bodies up to 16 MiB.
630
-
631
- One account-side adjustment: Tor exit IPs rotate constantly, so a
632
- fixed-IP whitelist on the API key cannot work. Set the key's IP factor
633
- to `tofu` or `keyonly` in the clientarea.
634
-
635
- ## PHP deployments
636
-
637
- Use `impreza_prepare_project` with `composer_json` and optionally `php_document_root` to review a PHP app. Deploy with `impreza_deploy_custom`, `mode: "dockerfile"` and `build_strategy: "php_composer"`, using Git, a local directory or a retained upload. The PHP 8.4/Apache recipe installs production dependencies from `composer.json` and a matching `composer.lock`, without Composer scripts or plugins, and checks actual platform requirements. Choose `project_dir` for the application and `php_document_root` for its public subfolder containing `index.php` (default `public`). Apache runs as a non-root user on `target_port` (default 8080, minimum 1024); it serves public files and sends missing paths to `index.php`.
638
-
639
- Health checks require HTTP 2xx without redirects, at `/` or your `healthcheck_path`. Optional `require_healthy_start` needs an explicit path and agent 0.6.3+, with a 30–600 second startup budget. Previews and redeploys keep the saved recipe. Custom repositories, private dependency credentials, installation plugins, extra extensions, `.htaccess` rules, frontend builds and application setup/migrations require a custom Dockerfile. `start_command` and public build variables are not PHP options. Analysis is advisory and does not inspect the lockfile or repository. See the [PHP deployment guide](https://docs.imprezahost.com/tutorials/agent-apps-panels.html#php-build).
640
-
641
- ## Python deployments
642
-
643
- Use `impreza_prepare_project` with `requirements_txt` and an explicit `start_command` to review a Python app. Deploy with `impreza_deploy_custom`, `mode: "dockerfile"` and `build_strategy: "python_pip"`, using Git, a local directory or an uploaded context. The Python 3.13 recipe installs a flat `requirements.txt` from PyPI and runs as a non-root user; choose `project_dir` for an independent application folder. Start a production server on `0.0.0.0` at `target_port` (default 8000), for example `exec gunicorn --bind 0.0.0.0:$PORT app:app`, with Flask and gunicorn declared in requirements. `PORT` and `HOST` are runtime variables. Keep credentials out of the saved command.
644
-
645
- The default Python health probe requires HTTP 2xx on `/`; choose `healthcheck_path` for another route. Optional `require_healthy_start` needs an explicit path and agent 0.6.3+, with a 30–600 second startup budget. Previews and redeploys retain the saved recipe. Dependency options, includes, URLs, local projects, private build credentials, system packages and other package managers require a custom Dockerfile. Public build variables remain npm-only. Analysis is advisory; builds resolve actual dependencies on the server. See the [Python deployment guide](https://docs.imprezahost.com/tutorials/agent-apps-panels.html#python-build).
646
-
647
- ## Build
648
-
649
- ```sh
650
- npm install
651
- npm run build
652
- # dist/server.js is the entry point
653
- ```
654
-
655
- ## Supervised preparation
656
-
657
- These legacy worker rules remain in effect unless the administrator enables agent 0.6.12+ [controlled builds](https://docs.imprezahost.com/deployment-cancellation.html#controlled-builds), which add verified executor stop and recovery for new builds.
658
-
659
- Agent 0.6.8+: supported Linux/systemd deploys run image pull and build in a separate supervised process. If the agent restarts, it waits for the exact worker receipt without repeating that work. Only a durable successful receipt allows the existing preparation reconciliation: revalidate operation/phase and unchanged containers, restore previous configuration, and close as failed or confirm a previously requested cancellation. recovery=reconciling can include waiting for the original worker. Missing/invalid receipts, worker failure or timeout, host reboot before a receipt, legacy unsupervised work, replacement uncertainty, data ownership and onion preparation still require review. A process or service disappearing is never proof of completion. The customer must wait for the final result before retrying; no automatic deploy retry, immediate build termination, data rollback or runtime-health guarantee is added.
660
-
661
- ## License
662
-
663
- MIT — see `LICENSE`.
664
-
665
-
666
- ## Supervised replacement
667
-
668
- Agent 0.6.9+: new supported Linux/systemd deploys keep the authorized container replacement, startup checks, lifecycle hooks, routes and normal startup recovery in one supervised worker. If the agent restarts, recovery=reconciling with step=reconciling_replacement waits for that original worker. Its verified durable final receipt is delivered without repeating containers or hooks, including a failed deployment whose previous release was restored. Missing or invalid receipts, worker loss or timeout, host reboot before completion, legacy unsupervised operations, data ownership changes and onion provisioning still require support; keep the private journal and do not retry to unblock the queue. This does not add automatic deployment retries, database rollback or zero-downtime traffic switching. Update the agent explicitly before the next deploy.
669
-
670
- Python deployments may select python_package_manager=uv@0.12.15 with python_pip, pyproject.toml and uv.lock. Installation is locked, production-only and non-editable on Python 3.13; public PyPI sources only. Custom uv workspaces/indexes require a Dockerfile. Use MCP 0.34.0+ and a control plane supporting this recipe.
671
-
672
-
673
- ## PostgreSQL application connections
674
-
675
- `impreza_prepare_service_binding` reviews a dedicated PostgreSQL connection for an image application in the same project environment and server. `impreza_prepare_service_binding_removal` reviews removal or a pending-cleanup retry with the exact `deployment_id` and `binding_id`. Read the saved plan with `impreza_get_service_binding_plan`; apply only after explicit confirmation using `impreza_apply_service_binding_plan`, the exact digest and `confirm: true`. Removal retains database data and disables the dedicated login only after a healthy replacement without the connection. Acceptance means queued, not verified completion. Requires agent 0.6.13+ and a compatible control plane.
676
-
677
- `impreza_prepare_service_binding_rotation` reviews a credential rotation for an existing connection with `deployment_id`, `binding_id` and `mode` (`rotate` or `abandon`). Rotating replaces the dedicated login with a distinct new one and disables the previous login only after a healthy replacement with the rotated `DATABASE_URL`; the database and its data are always retained. A failed startup keeps the previous application serving with the current credential and requires a newly reviewed retry; if the previous login could not be confirmed disabled, the rotation stays pending cleanup and a new `rotate` review retries it. `abandon` discards the unused candidate credential and keeps the current one; it is refused once only cleanup remains. Apply the returned review with `impreza_apply_service_binding_plan` as above; preparation queues nothing and returns no credential. Rotation requires an agent announcing `postgres-service-binding-rotation-v1`: older agents refuse the dispatch and the failed job directs the customer to update the agent explicitly, preserving its identity, configuration and applications. Rotation requires a v2-protocol connection; legacy first-protocol connections are not adopted.
678
-
679
- ## Public HTTPS diagnostics
680
-
681
- `impreza_probe_deployment` takes `deployment_id` and checks the saved public hostname through the control plane. It reports public DNS resolution, TLS verification and the HTTPS HEAD status, without following redirects or sending application credentials. It does not read response bodies or verify dependencies. One attempt per account every 30 seconds; no agent update is required.
682
-
683
- ## Image promotion and environments
684
-
685
- `impreza_prepare_image_promotion`, `impreza_get_image_promotion` and `impreza_apply_image_promotion` review an exact registry digest for an existing destination configuration. Apply requires the returned review digest and explicit confirmation. Destination variables and data remain local to that application.
686
-
687
- Project/environment tools organize existing applications with explicit component associations. They do not copy variables, create network connections or deploy workloads. See the [project environments guide](https://docs.imprezahost.com/project-environments.html).
688
-
689
- ### Reviewed deployment workflows
690
-
691
- Version 0.38.0 adds environment configuration comparison, prepare/read/apply traffic
692
- switches and explicit branch previews with optional password protection. Compare
693
- returns variable names, never values. Traffic switches require a reviewed digest
694
- and confirmation, keep the source running, and require operator reconciliation if
695
- recovery cannot be verified. Protected preview credentials are shown once.
696
- Traffic switches and protected previews require agent 0.6.16 or newer. Existing
697
- servers update only at the customer's request. Assisted database restore is a REST
698
- workflow. See [project environments](https://docs.imprezahost.com/project-environments.html)
699
- and [deployment safety](https://docs.imprezahost.com/deployment-safety.html).
700
-
701
- ### Basic Cloud VPS management
702
-
703
- Basic Cloud VPS supports status and allocated resources through `impreza_api_call`,
704
- and boot, graceful shutdown and reboot through `impreza_cloud_power`. Use the WHMCS
705
- service ID from `impreza_list_services`. Advanced Cloud infrastructure tools are
706
- no longer advertised; retired calls return `FEATURE_NOT_AVAILABLE`. Contact
707
- Impreza support for other infrastructure changes. Ordering and cancellation keep
708
- their normal account workflows. Application management through an enrolled agent
709
- is separate.
710
-
711
-
712
- ## Configuration, metrics and recovery (0.39.0)
713
-
714
- Review application configuration with export/prepare/get/apply tools; inspect
715
- per-app metrics and alert rules; download backup parts and review/apply a
716
- PostgreSQL restore into a new database. Applying a review requires its digest
717
- and explicit confirmation; acceptance is queued work, not verified completion.
718
- The custom deploy and preparation tools also support `static_files` and
719
- `go_build`. Metrics and MariaDB bindings require agent 0.6.17 or newer.
720
- See [configuration, metrics and recovery](https://docs.imprezahost.com/customer-workflows.html)
721
- for permissions, examples and limits. No automatic server update occurs.
722
-
723
- ### Isolated runtime through Tor (0.42.0)
724
-
725
- Custom image and source deployments can opt in with `tor_egress: true` through
726
- `impreza_deploy_custom` and saved deployment preparation. This option needs an
727
- agent advertising `tor-egress-v1`, Docker Engine 28+, and a SOCKS5h-capable
728
- application. The runtime has no direct outbound fallback. Source downloads,
729
- image pulls and builds retain the server's normal network connection. Catalog
730
- installs, imported manifests and external service bindings are unsupported.
731
- See the [Tor runtime guide](https://docs.imprezahost.com/onion-services.html#runtime-egress)
732
- for availability and verification. This option is separate from using Tor to
733
- connect the MCP client itself and from publishing an inbound onion address.
734
-
735
- ## Account overview, playbooks and safer operations (0.47.0)
736
-
737
- Twelve new tools and five prompts:
738
-
739
- - **Account overview:** `impreza_get_account_overview` situates an assistant on
740
- the account in one read-only call: servers, apps and environments, domains,
741
- open alerts, recent deployment failures and the suggested next actions. A
742
- credential confined to some resources sees every section filtered to them.
743
- - **Playbooks as prompts:** `prompts/list` offers five guided procedures:
744
- `impreza_publish_git`, `impreza_change_domain`,
745
- `impreza_diagnose_deployment`, `impreza_restore_backup` and
746
- `impreza_update_agent`. They grant no authority; every step still goes
747
- through the tools and their confirmations.
748
- - **Pause and resume a server's agent:** `impreza_pause_agent` stops new
749
- command dispatch and suspends credentials confined to that server;
750
- `impreza_resume_agent` brings them back. Work already dispatched may finish.
751
- Both need an unrestricted credential with manage scope and `confirm: true`.
752
- - **Host plans with human approval:** `impreza_host_permissions`,
753
- `impreza_prepare_host_plan`, `impreza_get_host_plan` and
754
- `impreza_apply_host_plan` prepare a VPS reinstall that a person approves in
755
- the dashboard (exact server, template, digest and deadline) before it runs. An
756
- AI cannot approve its own plan.
757
- - **Zero-downtime redeploys:** `impreza_get_zero_downtime` explains whether an
758
- app qualifies and every reason why not; `impreza_set_zero_downtime` turns it
759
- on for a custom app and sets the readiness check. Needs agent 0.6.27 or later.
760
- - **Reads:** `impreza_get_shield` (Shield policy and the last 24 hours of WAF
761
- findings, no visitor identity), `impreza_privileged_audit` (the admission
762
- audit of privileged operations on the account) and
763
- `impreza_get_host_inventory` (allowlisted host facts; it needs agent 0.6.28,
764
- not yet released, and says so).
765
- - **Structured output:** read tools declare an `outputSchema` and return
766
- `structuredContent`; one-time secrets stay in the text and never in the
767
- structured result.
768
-
769
- ## Local and hosted parity (0.46.0)
770
-
771
- The local package now carries the 16 tools that only the hosted connector had:
772
-
773
- - projects and environments: `impreza_rename_project`, `impreza_delete_project`,
774
- `impreza_rename_environment` and `impreza_delete_environment`;
775
- - variable groups: `impreza_get_variable_group` and `impreza_set_variable_group`;
776
- - configuration promotion: `impreza_prepare_config_promotion`,
777
- `impreza_get_config_promotion` and `impreza_apply_config_promotion`;
778
- - ordered environment deploys: `impreza_deploy_environment`,
779
- `impreza_get_environment_deploy` and `impreza_list_environment_deploys`;
780
- - agent updates: `impreza_get_update_policy`, `impreza_set_update_policy` and
781
- `impreza_request_agent_update`;
782
- - Shield: `impreza_set_shield`.
783
-
784
- Tool annotations (read-only, destructive, idempotent) now match the hosted
785
- connector. A destructive tool called with `confirm` missing or false is refused
786
- before any request is sent.
787
-
788
- ## Point-in-time PostgreSQL recovery (0.45.0)
789
-
790
- Six tools cover status, configuration, a recovery drill, and prepare/get/apply
791
- of a reviewed UTC recovery point: `impreza_get_pitr`, `impreza_configure_pitr`,
792
- `impreza_drill_pitr`, `impreza_prepare_pitr_restore`,
793
- `impreza_get_pitr_restore`, and `impreza_apply_pitr_restore`. Status uses read
794
- scope; changes use deploy scope. The hosted connector requires a credential
795
- without resource confinement because physical PostgreSQL recovery can cover
796
- several bindings on a provider.
797
-
798
- WAL and base backups consume the account's storage. After six consecutive
799
- failures, automatic work pauses until the cause is repaired and configuration
800
- is saved again. Disabling stops protection but retains stored objects. A
801
- restore requires the review digest and `confirm: true`, creates a new database,
802
- and never redirects the live application. Poll the review until its receipt
803
- says `verified` or `failed`; acceptance alone is not a successful recovery.
804
-
805
- ## Scheduled tasks (0.45.0)
806
-
807
- `impreza_create_task` creates a scheduled task on an app and `impreza_update_task`
808
- changes one that exists (any field you leave out keeps its current value, so
809
- `enabled=false` pauses a task without losing its schedule or history), as on the
810
- hosted connector. They replace `impreza_schedule_task`, which is gone: update
811
- any client or prompt that still calls it. `impreza_list_tasks`,
812
- `impreza_run_task` and `impreza_delete_task` are unchanged.
813
-
814
- ## VPS resize (0.44.0)
815
-
816
- `impreza_vps_resize` gives a configurable VPS more vCPUs, memory or disk. Price it
817
- first with `impreza_api_call` on `/services/{id}/resize/quote`, passing the new
818
- sizes as `query`: it returns the pro-rated amount due today (the billing
819
- system's own figure), what the VPS renews at and whether the balance covers it.
820
- Then call `impreza_vps_resize` with the same sizes and `max_amount` set to that
821
- `due_today`, so a price that moved in between is refused rather than charged.
822
- Sizes only go up. The disk is enlarged at once; the new vCPU count and memory
823
- take effect when the VPS is restarted with `impreza_vps_power` action=reboot (a
824
- reboot from inside the server keeps the old ones). See
825
- [Resize a VPS](https://docs.imprezahost.com/order-vps.html#resize).
826
-
827
- ## Configurable VPS (0.43.0)
828
-
829
- The VPS is one configurable product: choose the location, operating system,
830
- vCPUs, memory and SSD disk. `impreza_vps_offer` lists every choice with its
831
- price per unit for each billing cycle, in the account currency; given a whole
832
- configuration (`billing_cycle`, `location`, `os`, `cpu_cores`, `memory_gb`,
833
- `disk_gb`) it returns the exact price, whether the balance covers it and
834
- whether that location has room right now. `impreza_order_vps` orders that
835
- configuration with `product_id` left out; fixed plans such as Tor Hosting are
836
- still ordered by `product_id`. The price charged is the price quoted. See
837
- [Order a VPS](https://docs.imprezahost.com/order-vps.html).
838
-
839
- ## Private onion previews and retained identities (0.42.0)
840
-
841
- Preview creation supports `private: true`; optionally supply one or more `onion_clients`.
842
- Supplied reviewers use a name and X25519 public key. Without supplied clients, a reviewer keypair is generated and the private key is shown once. This mode requires agent
843
- 0.6.20 with `onion-private-preview-v1`; reviewer authorization is installed
844
- before the first onion publication. Repeated deploys preserve later revocations.
845
- Do not combine this option with password-protected HTTPS previews.
846
-
847
- `impreza_purge_onion_key` requires the exact old onion address and explicit
848
- confirmation. Queued work is not proof of deletion: inspect its completed
849
- result. Active addresses are refused. Purge removes retained copies on that
850
- server; exports and backups elsewhere remain. Releasing a reservation for an
851
- uninstalled application does not delete key material.
852
-
853
- See the [onion guide](https://docs.imprezahost.com/onion-services.html)
854
- for permissions, customer update steps and supported limitations.
855
-
1
+ # impreza-mcp
2
+
3
+ [Model Context Protocol](https://modelcontextprotocol.io) server for
4
+ [Impreza Host](https://imprezahost.com). Lets AI coding tools (Claude
5
+ Code, Cursor, Codex CLI, Continue, Zed, ...) deploy customer-built
6
+ apps to managed Impreza VPSes without leaving the chat.
7
+
8
+ When you say "deploy this for me" to Claude with this MCP server
9
+ loaded, Claude calls `impreza_deploy_custom` directly — packages your
10
+ project, uploads it, builds + runs on your Impreza VPS, and reports
11
+ back the URL.
12
+
13
+ ## Pair the local CLI
14
+
15
+ Generate a one-time code in clientarea under **Impreza API → Connect an AI assistant**, choosing the permissions the assistant needs. Run `npx -y impreza-mcp login --code <code-from-clientarea>` on the machine running the local MCP server. Codes expire after 10 minutes and can be used once.
16
+
17
+ The CLI exchanges the code at `POST /v1/mcp/pair` without sending any existing API credentials. It saves the returned key, secret, scopes and expiry in `~/.impreza/credentials.json`; the code and secret are never printed. The directory uses mode `0700` and the file `0600` on POSIX. Windows uses a protected ACL granting access only to your account. The server reads this file automatically when neither credential environment variable is set. Explicit `IMPREZA_API_KEY` and `IMPREZA_API_SECRET` take precedence together; partial environment credentials never use a saved counterpart.
18
+
19
+ Set `IMPREZA_BASE_URL` before pairing for a different API endpoint. HTTPS is required; a v3 onion endpoint requires `IMPREZA_PROXY` with an explicit SOCKS5 proxy and never falls back to a direct connection. The endpoint and proxy are saved with the credential. A different API URL refuses the saved credential. Pairing never follows redirects or retries a code automatically.
20
+
21
+ An existing credential file is never overwritten. Revoke an old paired key in clientarea before removing its file and pairing again. If an exchange or disk write fails, the code may already have been consumed: check and revoke the new key in clientarea before generating another code. Restart the AI client after pairing.
22
+
23
+ ## Deployment progress and agent restarts
24
+
25
+ Compose review and deployment accept
26
+ `context_id` for one retained upload containing local build contexts and runtime
27
+ `env_file`, configs or secrets. The same context must be supplied at review and
28
+ deployment. Runtime files require agent 0.6.11+ with `compose-source-files-v1`.
29
+
30
+ Custom Node server/static deployments
31
+ accept `node_package_manager`, such as `pnpm@10.26.1` or `yarn@4.9.2`, matching the
32
+ project's exact `packageManager` and committed lockfile. Omit for npm. Supported
33
+ versions are standalone pnpm 10–12 and Yarn 4 projects, without combining
34
+ this field with `npm_workspace`. Inspection infers the pin and saved plans retain
35
+ it. See the deployment documentation for supported inputs and limits.
36
+
37
+ Read `last_operation.progress` from `impreza_list_deployments` for the last
38
+ reported step and timestamp. Agent 0.6.6+ saves final results before sending them;
39
+ after restart it resends the same receipt without repeating the deploy.
40
+ Agent 0.6.7+ can verify a completed preparation checkpoint and restore previous
41
+ configuration without replaying the deploy (`recovery=reconciling`). Wait for the
42
+ terminal failure or confirmed cancellation before retrying.
43
+ `recovery=required` means automatic reconciliation could not be verified; contact
44
+ support. Busy builds, missing checkpoints and replacement uncertainty stay blocked. A long-running build can
45
+ continue after the agent exits. Progress is not a live percentage or proof of
46
+ current runtime health. Existing agents update explicitly before the next deploy.
47
+ See [deployment progress](https://docs.imprezahost.com/deployment-progress.html).
48
+
49
+ ## Cancel a deployment
50
+
51
+ Use `impreza_cancel_deployment` with the deployment ID and exact
52
+ `last_operation.command_id`. Requires manage permission. Queued cancellation
53
+ is immediate; running preparation needs agent 0.6.5+. Agent 0.6.12+ can interrupt an owned build after the server administrator
54
+ enables controlled builds on supported Ubuntu 24.04 amd64 hosts. Other preparation
55
+ waits for its current step. Confirmation still requires verified cleanup and restored
56
+ configuration. `requested` is not `cancelled`. Replacement/recovery cannot
57
+ be cancelled. Cancelling a tracking Task remains separate.
58
+ Read [the cancellation guide](https://docs.imprezahost.com/deployment-cancellation.html).
59
+
60
+ ## Runtime health and deployment operations
61
+
62
+ `impreza_list_deployments` returns `runtime` and `last_operation` separately.
63
+ A failed build can leave the previous application healthy. Read runtime state,
64
+ observation time and reason; old or missing readings remain unknown.
65
+ Running without a confirmed healthcheck is not healthy. This requires agent
66
+ 0.6.4+ for observations and does not verify external HTTP/DNS/TLS. Existing
67
+ servers update explicitly. See [runtime health](https://docs.imprezahost.com/runtime-health.html).
68
+
69
+ ## Saved project plans and safe retries
70
+
71
+ `impreza_plan_project` also accepts
72
+ `git_url` and an exact 40-character `git_commit` instead of `context_id`.
73
+ Optional `git_username` and `git_token` are used only for the fetch. The server
74
+ captures an immutable retained archive, accounts for its upload quota, and
75
+ returns `source.origin` alongside the archive SHA256. Review those values before
76
+ preparing/applying the saved configuration. Only public-network HTTPS on port
77
+ 443 is supported; redirects and submodules are refused. Project code is not
78
+ executed by inspection. These options require the corresponding control-plane
79
+ capabilities; update the local MCP package before using them.
80
+
81
+ Use `impreza_plan_project` with a retained `context_id` to inspect the archive
82
+ inventory and selected configuration files. Choose `project_dir`,
83
+ `dockerfile_path`, a Python `start_command` or `php_document_root` as needed.
84
+ Review the findings and `analysis.deployment_options`.
85
+
86
+ With MCP **0.32.0+**, call `impreza_prepare_project_deployment` with `plan_id`,
87
+ zero-based `option_index`, app name, server and runtime settings. It validates
88
+ and saves the effective configuration without creating an app, job or DNS
89
+ record. Review the returned configuration, then call
90
+ `impreza_apply_project_deployment` with only `execution_id` and
91
+ `configuration_digest`. Later form/request changes cannot override that record.
92
+
93
+ A repeat of the same saved deployment returns its original acceptance receipt,
94
+ including after expiry or app removal. The receipt, app and queue job commit
95
+ together. After an uncertain response, retry the same ID and digest instead of
96
+ preparing another deployment. Acceptance means queued; inspect app status,
97
+ logs and health. This does not restart a failed job or update an existing app.
98
+
99
+ `impreza_list_prepared_deployments` lists the latest 20 saved configurations or
100
+ retrieves one `execution_id`. Environment values are encrypted in the prepared
101
+ record, omitted from review responses and cleared from that record on acceptance;
102
+ the app then uses its normal environment storage. Reviews show variable names.
103
+ Use at most 100 string values, with no system/routing variable overrides.
104
+
105
+ At most 20 pending records per account, valid no longer than the source plan
106
+ and for at most 24 hours. Source, rules, target availability/IP and effective
107
+ settings are rechecked before first apply. There is no domain, port or capacity
108
+ reservation, dependency pinning or build guarantee. DNS is external to the app
109
+ transaction and can remain after an interrupted attempt. Expired pending records
110
+ are removed on the account's next preparation; accepted receipts are retained.
111
+
112
+ Source inspection remains available in MCP 0.31.0+. The older
113
+ `impreza_deploy_project_plan` creates directly from an option and is not
114
+ idempotent. Plan creation requires deploy scope; listing requires read scope;
115
+ preparation/apply require deploy scope. These account-wide tools require
116
+ credentials without resource restrictions. No agent update is needed solely for
117
+ this flow; recipe requirements still apply. See the
118
+ [project plan and review guide](https://docs.imprezahost.com/project-plans.html).
119
+
120
+ ## Retained source uploads
121
+
122
+ Use `impreza_upload_context` with `dir` and an optional `label` to upload an immutable
123
+ source version without deploying. The response includes its `context_id`, SHA256,
124
+ size and expiry. List or inspect versions with `impreza_list_contexts`.
125
+
126
+ Create an app with `impreza_deploy_custom`, `mode: "dockerfile"` and `context_id`
127
+ (or deploy a local `dir` directly). Rebuild it with `impreza_redeploy_deployment`
128
+ and optionally another retained `context_id`. The app identity, domain, host port,
129
+ volumes and build recipe stay fixed. The selected source can differ from the
130
+ running release after failure or rollback; inspect deployment history.
131
+
132
+ Sources in use remain available. Unreferenced versions expire seven days after
133
+ upload or their last deployment request, not seven days after detachment. Default
134
+ quotas are 10 unexpired/referenced archives, 300 MiB per account and 100 MiB per
135
+ archive; referenced sources count. Delete an unused version with
136
+ `impreza_delete_context`, `context_id` and `confirm: true` after customer confirmation.
137
+ Metadata requires read scope, upload requires deploy, and deletion requires
138
+ manage. Resource-confined credentials cannot manage account uploads.
139
+
140
+ The packer excludes common dependency/VCS folders, .env and .env.* (except
141
+ example/sample/template files), .npmrc and .pypirc. It does not scan arbitrary
142
+ secrets or interpret .gitignore/.dockerignore; review what you upload. Portal
143
+ archives are sent unchanged. Legacy REST uploads remain temporary unless they
144
+ opt into `retain=true`. Older uploaded-source apps can migrate by selecting a
145
+ fresh retained context on redeploy. These MCP tools require 0.22.0+; no agent
146
+ update is needed solely for source retention. See the
147
+ [source upload guide](https://docs.imprezahost.com/source-uploads.html).
148
+
149
+ ## Node.js npm builds
150
+
151
+ Deploy an independent npm HTTP application without a repository Dockerfile using
152
+ `impreza_deploy_custom` with `mode: "dockerfile"`, `build_strategy: "node_npm"`,
153
+ `git_url` (or local `dir`), and `target_port` (usually 3000).
154
+ The API generates a Node 24 recipe: npm ci, optional build script, production
155
+ pruning and npm start as a non-root user. The selected project folder must contain package.json, package-lock.json
156
+ and a production start script. Docker Compose 2.17+ and BuildKit
157
+ must be available on the server. Select npm workspaces explicitly with
158
+ `npm_workspace`. Use `build_secrets` for named credentials and the `npmrc` secret
159
+ for private npm installation; agent 0.6.11+ is required. The app must listen on 0.0.0.0 and the
160
+ configured port. Keep runtime PORT consistent with that port.
161
+
162
+ Git redeploys and previews reuse the recipe snapshot. Retained uploaded sources
163
+ support reuse and source-version selection; older temporary uploads remain single-use. The recipe excludes .git, node_modules, .env,
164
+ .env.* and .npmrc from the source copy; this does not scan arbitrary secrets.
165
+ Keep credentials out of source code. The HTTP startup probe accepts responses
166
+ below 500 at / and is not a functional application test.
167
+
168
+ ## Public build variables
169
+
170
+ Required healthy start: opt in with require_healthy_start=true, an explicit healthcheck_path and build_strategy=node_npm. In the portal, enable Require a healthy start. Agent 0.6.3 or newer must be reported in Servers; update it explicitly and wait for the next heartbeat. startup_timeout_seconds accepts an integer from 30 to 600, default 60. The budget starts after containers are created and includes the stable health observation; Git fetch, dependency/image builds and recovery have separate time limits. Every running service must report Docker healthy and at least one serving container must exist. HTTP redirects, authentication errors and timeouts do not pass the configured 2xx probe. When the first install fails, its containers are removed and persistent volumes are preserved; the failure includes diagnostic logs. A failed replacement recovers a verified healthy previous release when available. Recovery and manual rollback use the saved release startup policy, so a slow healthy release retains its original deadline. Failure recovery does not undo database writes or mutable data. The control plane refuses incompatible agents at creation, never dispatches the policy without startup-health-v1 support in the current poll, and accepts success only with a matching health confirmation. Previews inherit the policy; redeploy keeps the snapshot. Deployment reads expose startup_health. Choose a new deployment to change the saved policy. Omission or false preserves legacy behavior; a startup timeout requires the option enabled. The public option is for generated Node builds. This does not provide zero-downtime switching or continuous automatic rollback after startup. Local MCP input support requires 0.20.0+. Existing agents update only when the customer runs the updater. See https://docs.imprezahost.com/tutorials/agent-apps-panels.html#required-startup
171
+
172
+ Node health checks: with build_strategy=node_npm, optionally set healthcheck_path (for example /health or /api/ready), or fill Health check path in the portal. The generated Docker health check sends HTTP GET to 127.0.0.1 on target_port inside the container and requires status 200-299; it does not follow redirects or send credentials. The route must work without login and should report the dependencies your app needs to serve requests. Use / or a path of at most 200 ASCII characters; segments start with a letter, digit, underscore or hyphen and may then include dots or tildes. A trailing slash is allowed. URLs, query strings, fragments, percent escapes, spaces, parent segments and repeated slashes are refused. Omit the field (leave it blank in the portal) to keep the legacy / probe accepting statuses below 500; explicitly setting / requires 2xx. Existing deployment snapshots remain unchanged. The saved healthcheck_path is returned by deployment reads, inherited by new previews and retained on redeploy; changing it requires a new deployment. Static sites keep their index.html probe; custom Dockerfiles define their own HEALTHCHECK. The probe runs every 5 seconds with a 2-second request timeout. With required startup disabled, agents 0.6.2 and later observe startup for up to 60 seconds: a failed replacement recovers a verified healthy previous release when one exists. Without that recovery target, a first install can still complete with a startup warning, so inspect health and logs before treating it as ready. This default policy does not provide continuous rollback, zero-downtime routing or external uptime checks. To enforce a startup deadline, enable required healthy startup with agent 0.6.3+. Local MCP inputs require 0.19.0+; healthcheck_path alone needs no agent update beyond 0.6.2.
173
+
174
+ Public build settings: generated node_npm and node_npm_static recipes accept public_build_vars, an object of string values available only to npm run build (including its prebuild/postbuild scripts). For example, {"VITE_API_URL":"https://api.example.com"} lets Vite compile a public API URL into the site. Names must start with VITE_, NEXT_PUBLIC_ or PUBLIC_, contain only uppercase letters, digits and underscores, and be at most 128 characters. Limits: 20 entries, 4096 UTF-8 bytes per value and 16384 bytes for names plus values. Empty strings are preserved; NUL is refused. Values are literal data, without shell or variable expansion. The portal exposes Public build variables as KEY=value lines; do not add surrounding quotes, which would become part of the value. These values are public and may appear in bundles, image metadata and logs: never send passwords, tokens or secrets. They are not supplied to npm ci or automatically added to runtime variables. Runtime vars still configure the running container and do not rewrite compiled browser files. Settings are saved at creation, exposed on deployment reads, inherited by new previews and reused on redeploy. Preview runtime inheritance/overrides do not change this build snapshot; create a separate deployment for different public build values. Existing snapshots default to no public build values. Use build_secrets for supported build credentials with agent 0.6.11+; unsupported build settings require a custom Dockerfile. Local MCP requires 0.18.0+; no agent update is required beyond the existing build executor.
175
+
176
+ See the [build configuration guide](https://docs.imprezahost.com/tutorials/agent-apps-panels.html#public-build-settings).
177
+
178
+ ## Apps in project subfolders
179
+
180
+ Deploy an independent npm app from a subfolder: set project_dir (default .) with node_npm or node_npm_static, or choose Project folder in the portal. For example, apps/site must contain its own package.json and matching package-lock.json; static_output_dir is relative to that folder. Only the selected folder is copied into /app for npm installation and builds. The repository/upload remains the Docker build context, so its root .dockerignore still applies. Paths allow up to 120 characters and five non-hidden segments; parent, node_modules and symlink components are refused. Missing folders or failed builds retain the previous healthy runtime. The project_dir value is returned by deployment reads, saved at creation and inherited by new previews; redeploy reuses the saved recipe. Existing snapshots default to .; changing the folder requires a new deployment. This supports independent apps in one repository, not shared workspaces or dependencies outside the folder; use a custom Dockerfile for those. The analyzer does not discover subfolders: supply the selected app metadata and review Project folder yourself. Local MCP requires 0.17.0+; no agent upgrade is required beyond the existing build executor.
181
+
182
+ See the [project folder guide](https://docs.imprezahost.com/tutorials/agent-apps-panels.html#project-folder).
183
+
184
+ ## Import a Compose stack
185
+
186
+ Use `impreza_prepare_compose` with `compose_yaml`, then explicitly select
187
+ `web_service` and the integer `target_port`. Review services, persistent
188
+ volumes, required variables, changes and blockers before deploying with
189
+ `impreza_deploy_custom`, `mode: "compose"`, the same YAML/service/port and
190
+ `compose_review_id` set to the returned `analysis_id`.
191
+
192
+ Supports self-contained public-image stacks with up to 12 services, private
193
+ bridge networks, local named volumes and service dependencies. Original host
194
+ port bindings are removed; only the selected HTTP service joins the proxy and
195
+ receives a managed loopback port. Container and volume names become specific
196
+ to the deployment. Declare CPU/memory limits per service in YAML.
197
+
198
+ The review does not fetch images, execute code or reserve resources. Local build
199
+ contexts and auxiliary files require the same retained context_id at review and
200
+ deploy. Runtime env_file accepts literal assignments only, without interpolation
201
+ or inherited bare keys. Aliases, profiles, host privileges and external resources
202
+ are outside this import subset. Reference uppercase variables instead of
203
+ embedding secrets. Runtime values must be single-line strings up to 4 KiB,
204
+ without surrounding whitespace, quotes, backslashes, dollar signs or space
205
+ followed by #. Variables supply explicit references, not every service's
206
+ environment. Required values are checked at creation, editing and redeploy.
207
+
208
+ The imported source is saved as a manifest. Redeploy reuses it and the named
209
+ data; changing the source/topology requires a new deployment. Failure recovery
210
+ uses the existing agent policy and does not undo database writes. Local MCP
211
+ support for public-image stacks requires 0.21.0+. Retained build/runtime sources
212
+ require MCP 0.34.0+ and agent 0.6.11+.
213
+ See the [Compose import guide](https://docs.imprezahost.com/compose-import.html).
214
+
215
+ ## Prepare project configuration
216
+
217
+ Use `impreza_prepare_project` with `package_json`, `dockerfile`, and optional
218
+ `dockerfile_path` before deploying. It returns framework hints, available build
219
+ and start commands, explicit ports from the final Dockerfile stage, and findings
220
+ to review. Each file is limited to 32 KiB. Review files for credentials before
221
+ sending; never submit .env files or secrets.
222
+
223
+ This is advisory analysis of supplied text. It does not fetch a repository,
224
+ execute code, generate a Dockerfile or deploy resources. Git deploys use a Dockerfile by default; supported npm projects can opt into the Node recipe. The analysis ID identifies metadata, not an executable plan.
225
+ Requires an API exposing /v1/platform/deployments/custom/prepare.
226
+
227
+ ## Why this host and not a mainstream one
228
+
229
+ Any provider can run your app. This one is built so an **agent can obtain and
230
+ operate infrastructure that is not tied to your identity**, end to end, without
231
+ you opening a browser:
232
+
233
+ - **No KYC, and no email address, to open an account.** An account is a
234
+ generated client ID plus a recovery token. No documents, no selfie, no phone
235
+ number.
236
+ - **Funded in cryptocurrency.** `impreza_topup` accepts BTC, XMR, USDT and TRX,
237
+ and `impreza_order_vps` buys the server from that balance. The agent can go
238
+ from "I need a server" to a running deployment without a card.
239
+ - **Offshore and onshore jurisdictions side by side**, chosen per project
240
+ rather than per account.
241
+ - **Tor is a deployment target, not an add-on.** `impreza_add_onion` gives a
242
+ deployment a `.onion` address in one call, so an agent can publish a hidden
243
+ service the same way it publishes a normal site. `impreza_onion_auth_*`
244
+ manage Tor v3 restricted discovery (client authorization): private keys
245
+ never leave the customer's Tor client unless they ask the server to
246
+ generate a keypair — and then the private key is shown once, never stored.
247
+ - **No API key in your config.** The hosted connector authenticates over OAuth.
248
+
249
+ If none of that matters for your project, a mainstream provider is a perfectly
250
+ good choice and usually cheaper to start with. This exists for the projects
251
+ where it does matter: research and journalism under pressure, censorship
252
+ circumvention, security work, and anything that should not be one support
253
+ ticket away from being linked to a legal name.
254
+
255
+ ## Retained-release rollback
256
+
257
+ The source tree adds `impreza_rollback_deployment`. Read a deployment's
258
+ `release_history` through `impreza_api_call` at
259
+ `/platform/deployments/{id}`, then choose a `rel_...` entry with
260
+ `rollback_supported: true`.
261
+
262
+ Explain the selected release and possible interruption to the customer before
263
+ calling the tool with `deployment_id`, `target_version` and `confirm: true`.
264
+ The hosted connector uses its two-call `confirm_token` flow instead.
265
+ The operation requires `manage` scope and a compatible API and agent.
266
+
267
+ A historical release may no longer be retained. The agent checks local images
268
+ and unchanged ports, storage and routing before replacing containers. It saves
269
+ the current healthy runtime and attempts recovery if the selected release fails
270
+ startup. Database contents and mutable data are not reverted. A queued response
271
+ does not confirm restoration; check deployment history for the result.
272
+
273
+ Available in impreza-mcp 0.12.0. Requires a compatible API and agent.
274
+
275
+ ## Static npm sites
276
+
277
+ Static npm sites: choose build_strategy=node_npm_static with a Git/context source (mode=dockerfile), or Static site + npm in the portal. Requires an independent npm package in the selected project folder, matching package-lock.json and a build script producing index.html in the selected output folder. Node 24 installs dependencies and runs the build; unprivileged Nginx serves only the selected output folder with configurable SPA fallback. No start script is required. Default target_port is 8080. Compose 2.17+ and BuildKit required. No SSR or server functions. Explicit npm_workspace and build_secrets are supported with their documented source and agent requirements. Runtime variables (including VITE_* and PORT) do not rewrite static bundles or change the configured Nginx port. Use static_output_dir (default dist) to choose a relative output folder containing index.html, and static_spa (boolean, default true) to choose SPA fallback or 404 for unknown routes. The portal exposes both fields. Paths are limited to 120 characters and five segments, without hidden, parent or node_modules segments; symlinks in the output or its parent path are refused. These settings are chosen at creation, stored in the recipe snapshot, exposed as static_options and carried to new previews. Redeploy reuses the saved recipe; changing these settings on existing deployments requires creating a new deployment. Existing snapshots keep their original recipe. Local MCP option inputs require 0.16.0+. Use public_build_vars for supported public settings; other build-time configuration requires a custom Dockerfile. Source .env/.env.*/.npmrc/.git/node_modules are excluded; review all generated files because the output folder is public. Missing index.html and symlink output fail the build. Existing preview/redeploy snapshots preserve the strategy. Local MCP requires 0.15.0+; no agent upgrade is needed beyond the existing build executor. The analyzer returns static_npm_recipe and conditional deployment_options; metadata is not proof of a static, working build.
278
+
279
+ ## Status
280
+
281
+ **Package version: 0.48.1.** The tool catalog covers app deployment plus account +
282
+ crypto balance, catalog + ordering, domains/DNS + registration, invoices, VPS
283
+ lifecycle with snapshots and backups, dedicated / bare-metal servers, plan
284
+ upgrades, and Titan / Google Workspace mailboxes — with a setup wizard that
285
+ generates ready-to-paste config snippets for 5 AI tools.
286
+
287
+ On top of that, everything an app needs after it is running: backup and
288
+ restore into the customer's **own** S3 bucket, a timer on an app with its
289
+ output kept, outbound webhooks so you stop polling, reading the app's own
290
+ files, and running the app's own command line.
291
+
292
+ The local (`npx`) server and the hosted OAuth connector expose the **same tool
293
+ catalog — 212 tools in the local package**. Declared, one-direction gaps remain:
294
+ `impreza_get_log_request` stays hosted-only (only the control plane resolves a
295
+ bare `request_id`; locally, call `impreza_tail_logs` again on the application —
296
+ requests dedupe); `impreza_list_approvals`, `impreza_get_approval` and
297
+ `impreza_get_credential_policy` are hosted-first (locally, the same reads are
298
+ REST calls through `impreza_api_call`); and `impreza_upload_context` stays
299
+ local-only (binary tarball streaming does not fit the hosted transport).
300
+
301
+ ### New in 0.11.0
302
+
303
+ **Run the app's own command line.** WP-CLI for WordPress, `occ` for
304
+ Nextcloud, `gitea admin` for Gitea, and the database client for a dump —
305
+ `impreza_app_cli` to run, `impreza_get_cli_run` to collect the output. Call
306
+ `impreza_get_cli_run` with no `run_id` first: it names the command lines the
307
+ app has, says what each is for, and gives one example that works.
308
+
309
+ - **No docker socket, and that is measured rather than claimed.** The command
310
+ runs in a separate container built from the app's own image, joined to the
311
+ app's own network, with its data mounted — the shape the official CLI
312
+ images are designed for. `cap_drop: ALL`, and no new privilege on the
313
+ machine.
314
+ - **Arguments are a list, never a string.** Each element becomes one `argv`
315
+ entry through `execve`, so nothing is split, globbed or substituted:
316
+ quoting is not your problem, and a `$` or a `;` inside a value is just
317
+ that. Verified against a live site — `option update blogname
318
+ 'dollars $HOME and a ; semicolon'` reads back exactly as sent.
319
+ - **Destructive, and treated as such.** A command line can do anything the
320
+ app itself can, so it needs the `manage` scope and is confirmation-gated.
321
+ Arguments are free rather than allowlisted: that is the same ceiling
322
+ `uninstall` with `purge_data` already sits at, and a list of `wp`
323
+ subcommands would age badly while protecting nothing the confirmation gate
324
+ does not.
325
+ - **The CLI version follows the app.** Where the command line is the app's
326
+ own image it is taken from that deployment, so a catalog bump carries it —
327
+ running `occ` from an older Nextcloud against a newer database is how a
328
+ maintenance command corrupts an install.
329
+
330
+ Custom deployments have no command line here: it is your own image and the
331
+ platform cannot know what it ships. Use a scheduled task of kind `command`
332
+ for those.
333
+
334
+ ### New in 0.10.0
335
+
336
+ **Look inside the app's own files.** `impreza_get_logs` reads stdout, which
337
+ cannot answer the question a deploy that came up wrong actually raises: did
338
+ that variable reach the config file? Two tools now do —
339
+ `impreza_inspect_app` to ask and `impreza_get_app_read` to collect the answer.
340
+
341
+ - **Four actions, and no fifth:** `list` a directory, `read` a file (capped at
342
+ 256 KB), `tail` its last lines, `grep` under a path with an extended regular
343
+ expression. There is no command string in the interface, and therefore no
344
+ shell.
345
+ - **Read-only by construction.** A one-shot container mounts the app's storage
346
+ read-only — the same mechanism the backup already uses — with no docker
347
+ socket and no write capability. So it also works on an app that is `failed`
348
+ and will not start, which is when it is wanted most.
349
+ - **Only the app's own storage:** `data`, or one of the named volumes the app's
350
+ manifest declares (a WordPress exposes `data` and `wp_db`, so its database
351
+ files are readable too). Call `impreza_get_app_read` with no `read_id` to
352
+ see the list for a given app.
353
+ - **What comes back is untrusted and often secret** — an app's config file is
354
+ where its database password lives. It reaches you and nothing else: the
355
+ field is on our request log's deny list, and the record is deleted within a
356
+ day.
357
+
358
+ ### Since 0.6.1
359
+
360
+ Three releases the npm page never described, each one a whole capability:
361
+
362
+ - **0.7.0 — backup and restore** of a deployment's data into the account's own
363
+ Impreza S3 bucket, with a per-chunk SHA-256 manifest that sits beside the
364
+ data so the copy stays verifiable with the customer's own credentials and no
365
+ call to us. Plus a schedule (daily by default, keeping 3), and a restore
366
+ that can land in a *different* app, which is how an app moves between
367
+ servers.
368
+ - **0.8.0 — scheduled tasks:** a timer on an app with the output kept, for the
369
+ apps that need one to behave correctly (Nextcloud's cron, WordPress's
370
+ `wp-cron` on a site with no visitors).
371
+ - **0.9.0 — outbound webhooks:** subscribe to deploy, backup and VPS events
372
+ and stop polling, with HMAC-signed delivery and a delivery log.
373
+
374
+ ### New in 0.6.1
375
+
376
+ **`tools/list` now reflects what your account actually owns.** About a third of
377
+ the tools only make sense if you have the machine behind them — VPS power
378
+ controls with no VPS can only ever answer "not found" — so those are left out
379
+ of the listing until you own one. Typical accounts see around 70 tools instead
380
+ of 97, which is roughly six thousand fewer tokens of context spent before you
381
+ ask anything.
382
+
383
+ Three things worth knowing about how it behaves:
384
+
385
+ - **The purchase path is never filtered.** An account that owns nothing is the
386
+ one that needs to buy something, so ordering, top-up, invoices and the
387
+ catalogue are always listed.
388
+ - **Buying something grows the list mid-session.** The server sends
389
+ `notifications/tools/list_changed` on the same response as the order, so a
390
+ client that honours it picks up the new tools without reconnecting.
391
+ - **It fails open.** If this server cannot reach the API to ask, it lists
392
+ everything rather than guess.
393
+
394
+ Hiding a tool is not an authorization boundary — the API still refuses anything
395
+ your account does not own. This only stops the listing from carrying tools that
396
+ could never work for you.
397
+
398
+ ### New in 0.6.0
399
+
400
+ Four things that only make sense on a host built for anonymity:
401
+
402
+ - **Dark previews** — push a branch, get a preview on its own ephemeral Tor
403
+ `.onion`. Every other platform's preview URL puts your branch name into
404
+ public DNS and into a permanent Certificate Transparency log; branch names
405
+ carry ticket ids, customer names and unshipped features. This one creates
406
+ neither record, and destroys its keys when the branch is deleted or the TTL
407
+ runs out. `impreza_configure_previews`, `impreza_list_previews`,
408
+ `impreza_retire_preview`.
409
+ - **Agent sub-credentials** — mint a narrower credential from the one you hold
410
+ and hand it to a subtask: one deployment, one hour, no spending. A child can
411
+ never exceed its parent on any axis, and revoking a credential revokes
412
+ everything it minted, however deep. `impreza_mint_subcredential`,
413
+ `impreza_list_credentials`, `impreza_revoke_credential`,
414
+ `impreza_agent_activity`.
415
+ - **A privacy report you can check** — `impreza_privacy_report` returns every
416
+ field we store about your account, what it is for, how long it survives and
417
+ who else sees it, and then measures our own retention against the oldest
418
+ record that actually survived. Counts and date ranges, never contents.
419
+ - **Ask before you guess** — search our docs, validate a deployment manifest
420
+ before deploying it (including a privacy lint for third-party CDNs, public
421
+ DNS resolvers and leaked secrets), or run a diagnosis when something is
422
+ wrong. `impreza_search_docs`, `impreza_validate_manifest`, `impreza_doctor`.
423
+
424
+ Plus the Tasks extension, so long operations report completion instead of
425
+ leaving you to poll, and three MCP Apps panels — a payment card, a server card
426
+ and a deploy wizard — that render inside clients which support them.
427
+
428
+ The table below is a **selection**, not the full list — it covers the tools
429
+ most people reach for first. Your client's own tool listing is authoritative,
430
+ and `impreza_api_search` finds anything not named here.
431
+
432
+ | Tool | Wraps |
433
+ |------|-------|
434
+ | **Apps & deployments** | |
435
+ | `impreza_list_servers` | `GET /v1/platform/servers` |
436
+ | `impreza_list_apps` | `GET /v1/platform/apps` |
437
+ | `impreza_list_deployments` | `GET /v1/platform/deployments` + `/custom` (merged) |
438
+ | `impreza_upload_context` | `POST /v1/platform/deployments/custom/contexts?retain=true` |
439
+ | `impreza_list_contexts` | `GET /v1/platform/deployments/custom/contexts[/{context_id}]` |
440
+ | `impreza_delete_context` | `DELETE /v1/platform/deployments/custom/contexts/{context_id}` |
441
+ | `impreza_deploy_custom` | `POST /v1/platform/deployments/custom` (3 modes) |
442
+ | `impreza_deploy_catalog_app` | `POST /v1/platform/deployments` |
443
+ | `impreza_uninstall_deployment` | `POST .../uninstall` |
444
+ | `impreza_get_logs` | `POST .../logs` (sync tail, last N lines) |
445
+ | `impreza_restart_deployment` | `POST .../restart` |
446
+ | `impreza_redeploy_deployment` | `POST .../custom/{id}/redeploy` (in-place rebuild, same domain) |
447
+ | `impreza_add_onion` | `POST .../onion/add` |
448
+ | `impreza_set_onion_profile` | `POST .../onion/profile` (`standard` / `hardened` / `max` hardening tiers) |
449
+ | `impreza_export_onion_key` | `POST .../onion/export` (sealed to your X25519 key; plaintext never transits) |
450
+ | `impreza_fetch_onion_key_export` | `GET .../onion/export/{command_id}` (read-once — the blob is burned) |
451
+ | `impreza_rotate_onion_key` | `POST .../onion/rotate` (new .onion; the old address dies) |
452
+ | `impreza_onion_auth_list` | `GET .../onion/clients` |
453
+ | `impreza_onion_auth_add` | `POST .../onion/clients` (`pubkey`, or `generate:true` → `private_key` shown once) |
454
+ | `impreza_onion_auth_revoke` | `DELETE .../onion/clients/{name}` |
455
+ | `impreza_change_domain` | `POST .../domain` |
456
+ | `impreza_git_webhook_status` | `GET .../custom/{id}/git-webhook` |
457
+ | `impreza_git_webhook_connect` | `POST .../custom/{id}/git-webhook/connect` |
458
+ | `impreza_git_webhook_disconnect` | `POST .../custom/{id}/git-webhook/disconnect` |
459
+ | **Account & balance** | |
460
+ | `impreza_account_info` | `GET /v1/account` |
461
+ | `impreza_list_services` | `GET /v1/account/services` |
462
+ | `impreza_topup` | `POST /v1/account/topup` — top up in BTC / XMR / USDT / TRX |
463
+ | `impreza_topup_status` | `GET /v1/account/topup/{invoice_id}` |
464
+ | `impreza_topup_payment` | `GET /v1/account/topup/{invoice_id}/payment` — crypto address + amount to pay |
465
+ | **Catalog & ordering** | |
466
+ | `impreza_list_products` | `GET /v1/products` — products + pricing; the VPS is listed at its smallest size (`configurable: true`) |
467
+ | `impreza_vps_offer` | `GET /v1/products/vps` — VPS locations, operating systems, CPU / memory / disk ranges and prices; with a whole configuration, `GET /v1/products/vps/quote` — its exact price |
468
+ | `impreza_order_vps` | `POST /v1/orders` — a VPS by location, OS and size (or a fixed plan by `product_id`); paid from balance; born deployable (`@agent`); 202 + poll `impreza_list_servers` |
469
+ | **Domains & DNS** | |
470
+ | `impreza_domain_check` | `GET /v1/domains/check` |
471
+ | `impreza_domain_details` | `GET /v1/domains/{domain}` |
472
+ | `impreza_list_dns` | `GET /v1/domains/{domain}/dns` |
473
+ | `impreza_add_dns_record` | `POST /v1/domains/{domain}/dns` |
474
+ | `impreza_update_dns_record` | `PUT /v1/domains/{domain}/dns` |
475
+ | `impreza_delete_dns_record` | `DELETE /v1/domains/{domain}/dns` |
476
+ | `impreza_set_nameservers` | `PUT /v1/domains/{domain}/nameservers` |
477
+ | **VPS lifecycle** (Proxmox) | |
478
+ | `impreza_vps_status` | `GET /v1/vps/proxmox/{id}/status` |
479
+ | `impreza_vps_power` | `POST /v1/vps/proxmox/{id}/{start\|shutdown\|reboot\|stop}` |
480
+ | `impreza_vps_list_backups` | `GET /v1/vps/proxmox/{id}/backups` |
481
+ | `impreza_vps_create_backup` | `POST /v1/vps/proxmox/{id}/backups` |
482
+ | `impreza_vps_list_templates` | `GET /v1/vps/proxmox/{id}/templates` |
483
+ | `impreza_vps_reinstall` | `POST /v1/vps/proxmox/{id}/reinstall` — destructive (wipes) |
484
+ | `impreza_vps_resize` | `POST /v1/services/{id}/resize` — more vCPU, memory or disk at the pro-rated price (quote first with `GET /v1/services/{id}/resize/quote`); `max_amount` pins it |
485
+
486
+ ## Install + setup
487
+
488
+ ### Prerequisites
489
+
490
+ - Node ≥ 20
491
+ - An Impreza Host account with an API key + secret
492
+ (clientarea → API Keys; the IP of the machine running this MCP
493
+ server must be whitelisted under the key)
494
+
495
+ ### One-shot via `npx`
496
+
497
+ No global install needed — `npx impreza-mcp` works.
498
+
499
+ ### Or install globally
500
+
501
+ ```sh
502
+ npm install -g impreza-mcp
503
+ ```
504
+
505
+ ### Get a ready-to-paste config snippet
506
+
507
+ The fastest path: ask the binary itself.
508
+
509
+ ```sh
510
+ npx impreza-mcp setup --tool claude-code
511
+ # also: cursor | continue | zed | codex-cli
512
+ ```
513
+
514
+ The wizard prints the JSON block to drop into your AI tool's MCP
515
+ config + the exact file path + the post-config step (usually "fully
516
+ quit + re-open the AI tool"). It does NOT write to disk — paste it
517
+ yourself so you don't accidentally clobber an existing config with
518
+ other MCP servers.
519
+
520
+ ### Or wire it in manually
521
+
522
+ **Claude Code** — add to `~/Library/Application Support/Claude/claude_desktop_config.json`
523
+ (macOS) or `%APPDATA%/Claude/claude_desktop_config.json` (Windows):
524
+
525
+ ```json
526
+ {
527
+ "mcpServers": {
528
+ "impreza": {
529
+ "command": "npx",
530
+ "args": ["-y", "impreza-mcp"],
531
+ "env": {
532
+ "IMPREZA_API_KEY": "imp_...",
533
+ "IMPREZA_API_SECRET": "..."
534
+ }
535
+ }
536
+ }
537
+ }
538
+ ```
539
+
540
+ Restart Claude Code. The tools appear under the MCP icon.
541
+
542
+ **Cursor** — add to `~/.cursor/mcp.json` (same shape as above).
543
+
544
+ **Continue** — add to `~/.continue/config.json`:
545
+
546
+ ```json
547
+ {
548
+ "experimental": {
549
+ "modelContextProtocolServers": [
550
+ {
551
+ "transport": {
552
+ "type": "stdio",
553
+ "command": "npx",
554
+ "args": ["-y", "impreza-mcp"],
555
+ "env": {
556
+ "IMPREZA_API_KEY": "imp_...",
557
+ "IMPREZA_API_SECRET": "..."
558
+ }
559
+ }
560
+ }
561
+ ]
562
+ }
563
+ }
564
+ ```
565
+
566
+ **Zed** — add to your settings:
567
+
568
+ ```json
569
+ {
570
+ "context_servers": {
571
+ "impreza": {
572
+ "command": {
573
+ "path": "npx",
574
+ "args": ["-y", "impreza-mcp"],
575
+ "env": {
576
+ "IMPREZA_API_KEY": "imp_...",
577
+ "IMPREZA_API_SECRET": "..."
578
+ }
579
+ }
580
+ }
581
+ }
582
+ }
583
+ ```
584
+
585
+ ## Usage in chat
586
+
587
+ After setup, talk to your AI naturally:
588
+
589
+ > *"List my Impreza servers."* → calls `impreza_list_servers`
590
+ >
591
+ > *"Deploy this directory to my Impreza VPS, expose via .onion."* →
592
+ > packages the cwd as a Dockerfile-mode custom deploy, uploads, deploys
593
+ > with `onion=true`, reports the .onion address.
594
+ >
595
+ > *"What apps are running on my agent?"* → calls
596
+ > `impreza_list_deployments` filtered to the right server.
597
+
598
+ ## Auth + security
599
+
600
+ `IMPREZA_API_KEY` + `IMPREZA_API_SECRET` live in the AI tool's MCP
601
+ config env — not in any file on disk owned by `impreza-mcp` itself.
602
+ The MCP server holds the secret only in memory and only attaches it
603
+ as HTTP request headers.
604
+
605
+ The IP of the machine running this MCP server (almost always your
606
+ laptop) must be on the API key's whitelist. Manage the whitelist in
607
+ your Impreza clientarea.
608
+
609
+ ## Using over Tor
610
+
611
+ The MCP server can route every API call through a local Tor daemon, so
612
+ API requests use the configured proxy. Your network provider can still observe
613
+ your connection to Tor; this option does not hide that you are using Tor.
614
+
615
+ 1. Install and start Tor (the `tor` daemon, or Tor Browser — both
616
+ commonly expose a SOCKS5 listener on `127.0.0.1:9050` for the daemon
617
+ or `127.0.0.1:9150` for Tor Browser; check your local configuration).
618
+ 2. Add `IMPREZA_PROXY` to the MCP config env:
619
+
620
+ ```json
621
+ "env": {
622
+ "IMPREZA_API_KEY": "imp_...",
623
+ "IMPREZA_API_SECRET": "...",
624
+ "IMPREZA_PROXY": "socks5://127.0.0.1:9050"
625
+ }
626
+ ```
627
+
628
+ Every API request then exits through Tor, and the API hostname is
629
+ resolved by Tor itself (remote DNS) — nothing is resolved locally, so
630
+ no DNS leak. The transport fails closed: if the proxy is unreachable
631
+ or refuses the connection, the request fails — it never silently falls
632
+ back to a direct clearnet connection.
633
+
634
+ Optionally point `IMPREZA_BASE_URL` at the API's `.onion` mirror —
635
+ `http://` is accepted only for v3 `.onion` hosts, since Tor authenticates and
636
+ encrypts onion connections. Clearnet hosts require `https://`. An onion URL
637
+ also requires an explicit `IMPREZA_PROXY`; the client refuses direct DNS and
638
+ connections even when the onion URL uses HTTPS. Proxy requests refuse redirects,
639
+ use a bounded request deadline and accept response bodies up to 16 MiB.
640
+
641
+ One account-side adjustment: Tor exit IPs rotate constantly, so a
642
+ fixed-IP whitelist on the API key cannot work. Set the key's IP factor
643
+ to `tofu` or `keyonly` in the clientarea.
644
+
645
+ ## PHP deployments
646
+
647
+ Use `impreza_prepare_project` with `composer_json` and optionally `php_document_root` to review a PHP app. Deploy with `impreza_deploy_custom`, `mode: "dockerfile"` and `build_strategy: "php_composer"`, using Git, a local directory or a retained upload. The PHP 8.4/Apache recipe installs production dependencies from `composer.json` and a matching `composer.lock`, without Composer scripts or plugins, and checks actual platform requirements. Choose `project_dir` for the application and `php_document_root` for its public subfolder containing `index.php` (default `public`). Apache runs as a non-root user on `target_port` (default 8080, minimum 1024); it serves public files and sends missing paths to `index.php`.
648
+
649
+ Health checks require HTTP 2xx without redirects, at `/` or your `healthcheck_path`. Optional `require_healthy_start` needs an explicit path and agent 0.6.3+, with a 30–600 second startup budget. Previews and redeploys keep the saved recipe. Custom repositories, private dependency credentials, installation plugins, extra extensions, `.htaccess` rules, frontend builds and application setup/migrations require a custom Dockerfile. `start_command` and public build variables are not PHP options. Analysis is advisory and does not inspect the lockfile or repository. See the [PHP deployment guide](https://docs.imprezahost.com/tutorials/agent-apps-panels.html#php-build).
650
+
651
+ ## Python deployments
652
+
653
+ Use `impreza_prepare_project` with `requirements_txt` and an explicit `start_command` to review a Python app. Deploy with `impreza_deploy_custom`, `mode: "dockerfile"` and `build_strategy: "python_pip"`, using Git, a local directory or an uploaded context. The Python 3.13 recipe installs a flat `requirements.txt` from PyPI and runs as a non-root user; choose `project_dir` for an independent application folder. Start a production server on `0.0.0.0` at `target_port` (default 8000), for example `exec gunicorn --bind 0.0.0.0:$PORT app:app`, with Flask and gunicorn declared in requirements. `PORT` and `HOST` are runtime variables. Keep credentials out of the saved command.
654
+
655
+ The default Python health probe requires HTTP 2xx on `/`; choose `healthcheck_path` for another route. Optional `require_healthy_start` needs an explicit path and agent 0.6.3+, with a 30–600 second startup budget. Previews and redeploys retain the saved recipe. Dependency options, includes, URLs, local projects, private build credentials, system packages and other package managers require a custom Dockerfile. Public build variables remain npm-only. Analysis is advisory; builds resolve actual dependencies on the server. See the [Python deployment guide](https://docs.imprezahost.com/tutorials/agent-apps-panels.html#python-build).
656
+
657
+ ## Build
658
+
659
+ ```sh
660
+ npm install
661
+ npm run build
662
+ # dist/server.js is the entry point
663
+ ```
664
+
665
+ ## Supervised preparation
666
+
667
+ These legacy worker rules remain in effect unless the administrator enables agent 0.6.12+ [controlled builds](https://docs.imprezahost.com/deployment-cancellation.html#controlled-builds), which add verified executor stop and recovery for new builds.
668
+
669
+ Agent 0.6.8+: supported Linux/systemd deploys run image pull and build in a separate supervised process. If the agent restarts, it waits for the exact worker receipt without repeating that work. Only a durable successful receipt allows the existing preparation reconciliation: revalidate operation/phase and unchanged containers, restore previous configuration, and close as failed or confirm a previously requested cancellation. recovery=reconciling can include waiting for the original worker. Missing/invalid receipts, worker failure or timeout, host reboot before a receipt, legacy unsupervised work, replacement uncertainty, data ownership and onion preparation still require review. A process or service disappearing is never proof of completion. The customer must wait for the final result before retrying; no automatic deploy retry, immediate build termination, data rollback or runtime-health guarantee is added.
670
+
671
+ ## License
672
+
673
+ MIT — see `LICENSE`.
674
+
675
+
676
+ ## Supervised replacement
677
+
678
+ Agent 0.6.9+: new supported Linux/systemd deploys keep the authorized container replacement, startup checks, lifecycle hooks, routes and normal startup recovery in one supervised worker. If the agent restarts, recovery=reconciling with step=reconciling_replacement waits for that original worker. Its verified durable final receipt is delivered without repeating containers or hooks, including a failed deployment whose previous release was restored. Missing or invalid receipts, worker loss or timeout, host reboot before completion, legacy unsupervised operations, data ownership changes and onion provisioning still require support; keep the private journal and do not retry to unblock the queue. This does not add automatic deployment retries, database rollback or zero-downtime traffic switching. Update the agent explicitly before the next deploy.
679
+
680
+ Python deployments may select python_package_manager=uv@0.12.15 with python_pip, pyproject.toml and uv.lock. Installation is locked, production-only and non-editable on Python 3.13; public PyPI sources only. Custom uv workspaces/indexes require a Dockerfile. Use MCP 0.34.0+ and a control plane supporting this recipe.
681
+
682
+
683
+ ## PostgreSQL application connections
684
+
685
+ `impreza_prepare_service_binding` reviews a dedicated PostgreSQL connection for an image application in the same project environment and server. `impreza_prepare_service_binding_removal` reviews removal or a pending-cleanup retry with the exact `deployment_id` and `binding_id`. Read the saved plan with `impreza_get_service_binding_plan`; apply only after explicit confirmation using `impreza_apply_service_binding_plan`, the exact digest and `confirm: true`. Removal retains database data and disables the dedicated login only after a healthy replacement without the connection. Acceptance means queued, not verified completion. Requires agent 0.6.13+ and a compatible control plane.
686
+
687
+ `impreza_prepare_service_binding_rotation` reviews a credential rotation for an existing connection with `deployment_id`, `binding_id` and `mode` (`rotate` or `abandon`). Rotating replaces the dedicated login with a distinct new one and disables the previous login only after a healthy replacement with the rotated `DATABASE_URL`; the database and its data are always retained. A failed startup keeps the previous application serving with the current credential and requires a newly reviewed retry; if the previous login could not be confirmed disabled, the rotation stays pending cleanup and a new `rotate` review retries it. `abandon` discards the unused candidate credential and keeps the current one; it is refused once only cleanup remains. Apply the returned review with `impreza_apply_service_binding_plan` as above; preparation queues nothing and returns no credential. Rotation requires an agent announcing `postgres-service-binding-rotation-v1`: older agents refuse the dispatch and the failed job directs the customer to update the agent explicitly, preserving its identity, configuration and applications. Rotation requires a v2-protocol connection; legacy first-protocol connections are not adopted.
688
+
689
+ ## Public HTTPS diagnostics
690
+
691
+ `impreza_probe_deployment` takes `deployment_id` and checks the saved public hostname through the control plane. It reports public DNS resolution, TLS verification and the HTTPS HEAD status, without following redirects or sending application credentials. It does not read response bodies or verify dependencies. One attempt per account every 30 seconds; no agent update is required.
692
+
693
+ ## Image promotion and environments
694
+
695
+ `impreza_prepare_image_promotion`, `impreza_get_image_promotion` and `impreza_apply_image_promotion` review an exact registry digest for an existing destination configuration. Apply requires the returned review digest and explicit confirmation. Destination variables and data remain local to that application.
696
+
697
+ Project/environment tools organize existing applications with explicit component associations. They do not copy variables, create network connections or deploy workloads. See the [project environments guide](https://docs.imprezahost.com/project-environments.html).
698
+
699
+ ### Reviewed deployment workflows
700
+
701
+ Version 0.38.0 adds environment configuration comparison, prepare/read/apply traffic
702
+ switches and explicit branch previews with optional password protection. Compare
703
+ returns variable names, never values. Traffic switches require a reviewed digest
704
+ and confirmation, keep the source running, and require operator reconciliation if
705
+ recovery cannot be verified. Protected preview credentials are shown once.
706
+ Traffic switches and protected previews require agent 0.6.16 or newer. Existing
707
+ servers update only at the customer's request. Assisted database restore is a REST
708
+ workflow. See [project environments](https://docs.imprezahost.com/project-environments.html)
709
+ and [deployment safety](https://docs.imprezahost.com/deployment-safety.html).
710
+
711
+ ### Basic Cloud VPS management
712
+
713
+ Basic Cloud VPS supports status and allocated resources through `impreza_api_call`,
714
+ and boot, graceful shutdown and reboot through `impreza_cloud_power`. Use the WHMCS
715
+ service ID from `impreza_list_services`. Advanced Cloud infrastructure tools are
716
+ no longer advertised; retired calls return `FEATURE_NOT_AVAILABLE`. Contact
717
+ Impreza support for other infrastructure changes. Ordering and cancellation keep
718
+ their normal account workflows. Application management through an enrolled agent
719
+ is separate.
720
+
721
+
722
+ ## Configuration, metrics and recovery (0.39.0)
723
+
724
+ Review application configuration with export/prepare/get/apply tools; inspect
725
+ per-app metrics and alert rules; download backup parts and review/apply a
726
+ PostgreSQL restore into a new database. Applying a review requires its digest
727
+ and explicit confirmation; acceptance is queued work, not verified completion.
728
+ The custom deploy and preparation tools also support `static_files` and
729
+ `go_build`. Metrics and MariaDB bindings require agent 0.6.17 or newer.
730
+ See [configuration, metrics and recovery](https://docs.imprezahost.com/customer-workflows.html)
731
+ for permissions, examples and limits. No automatic server update occurs.
732
+
733
+ ### Isolated runtime through Tor (0.42.0)
734
+
735
+ Custom image and source deployments can opt in with `tor_egress: true` through
736
+ `impreza_deploy_custom` and saved deployment preparation. This option needs an
737
+ agent advertising `tor-egress-v1`, Docker Engine 28+, and a SOCKS5h-capable
738
+ application. The runtime has no direct outbound fallback. Source downloads,
739
+ image pulls and builds retain the server's normal network connection. Catalog
740
+ installs, imported manifests and external service bindings are unsupported.
741
+ See the [Tor runtime guide](https://docs.imprezahost.com/onion-services.html#runtime-egress)
742
+ for availability and verification. This option is separate from using Tor to
743
+ connect the MCP client itself and from publishing an inbound onion address.
744
+
745
+ ## Jurisdiction failover and safer reads (0.48.0)
746
+
747
+ **Reviewed cold failover.** Fourteen tools move an app to a cold standby on
748
+ another server you own, in a different country, through a review you confirm.
749
+ The reviewed apps are **Memos 0.31.0** and, since 0.48.1, **Uptime Kuma 2.5.5**
750
+ from the catalog. Create the standby with `impreza_deploy_catalog_app` and `standby: true`, without a
751
+ domain or onion; it starts with no public route. Then pair and read it
752
+ (`impreza_pair_failover_standby`, `impreza_get_failover_standby`). For an
753
+ external server, first declare its country with
754
+ `impreza_declare_external_failover_country` (declared by you, not verified by
755
+ Impreza; managed servers report theirs). Confirm the exact
756
+ backup/restore/redeploy chain (`impreza_confirm_failover_sync`), then prepare,
757
+ read and apply a review (`impreza_prepare_failover`, `impreza_get_failover`,
758
+ `impreza_apply_failover`, and `impreza_retry_failover_activation` when target
759
+ activation needs another try).
760
+
761
+ After a verified failover, `impreza_prepare_failback`, `impreza_get_failback`
762
+ and `impreza_apply_failback` release the old host and invert the pair: the old
763
+ primary becomes the cold standby, and no traffic moves. Returning traffic is an
764
+ ordinary backup, restore, sync confirmation and reviewed failover.
765
+ `impreza_set_failover_drill_policy`, `impreza_run_failover_drill` and
766
+ `impreza_get_failover_drill` refresh the standby with a platform-run cold copy,
767
+ on demand or every 60 to 10080 minutes, and record how long each step took.
768
+
769
+ What moves: a hostname in the managed zone, or a public onion address through
770
+ its sealed export. Custom domains, private onion services, database bindings
771
+ and dedicated servers are not supported. Applying stops the source and can
772
+ interrupt traffic or lose writes made since the restored backup: review the
773
+ source, target and backup age with the user, then pass the exact `cutover_id`
774
+ (or `failback_id`), `review_digest` and `confirm: true`. Acceptance is
775
+ asynchronous: read the review until it is verified or reports an actionable
776
+ failure. Where failover is not enabled on the API, these tools return the API's
777
+ 404. The hosted connector requires an unconfined account credential. Guide:
778
+ [jurisdiction failover](https://docs.imprezahost.com/jurisdiction-failover.html).
779
+
780
+ **Also in 0.48.0:**
781
+ - `impreza_vps_resize_recommendation`: whether a configurable VPS needs more
782
+ CPU, memory or disk, judged from the sustained load its agent reports.
783
+ - `impreza_get_host_inventory` omits SSH host key fingerprints unless you pass
784
+ `include_ssh_fingerprints: true`.
785
+ - API errors come back as `structuredContent` with a `code` and `next_steps`.
786
+ - `npx -y impreza-mcp login --code <code>` pairs the local server with a
787
+ one-time code from the client area (see [Pair the local CLI](#pair-the-local-cli)).
788
+ - The publish playbook diagnoses a failed deployment with `impreza_doctor` and
789
+ `impreza_get_logs`.
790
+
791
+ ## Account overview, playbooks and safer operations (0.47.0)
792
+
793
+ Twelve new tools and five prompts:
794
+
795
+ - **Account overview:** `impreza_get_account_overview` situates an assistant on
796
+ the account in one read-only call: servers, apps and environments, domains,
797
+ open alerts, recent deployment failures and the suggested next actions. A
798
+ credential confined to some resources sees every section filtered to them.
799
+ - **Playbooks as prompts:** `prompts/list` offers five guided procedures:
800
+ `impreza_publish_git`, `impreza_change_domain`,
801
+ `impreza_diagnose_deployment`, `impreza_restore_backup` and
802
+ `impreza_update_agent`. They grant no authority; every step still goes
803
+ through the tools and their confirmations.
804
+ - **Pause and resume a server's agent:** `impreza_pause_agent` stops new
805
+ command dispatch and suspends credentials confined to that server;
806
+ `impreza_resume_agent` brings them back. Work already dispatched may finish.
807
+ Both need an unrestricted credential with manage scope and `confirm: true`.
808
+ - **Host plans with human approval:** `impreza_host_permissions`,
809
+ `impreza_prepare_host_plan`, `impreza_get_host_plan` and
810
+ `impreza_apply_host_plan` prepare a VPS reinstall that a person approves in
811
+ the dashboard (exact server, template, digest and deadline) before it runs. An
812
+ AI cannot approve its own plan.
813
+ - **Zero-downtime redeploys:** `impreza_get_zero_downtime` explains whether an
814
+ app qualifies and every reason why not; `impreza_set_zero_downtime` turns it
815
+ on for a custom app and sets the readiness check. Needs agent 0.6.27 or later.
816
+ - **Reads:** `impreza_get_shield` (Shield policy and the last 24 hours of WAF
817
+ findings, no visitor identity), `impreza_privileged_audit` (the admission
818
+ audit of privileged operations on the account) and
819
+ `impreza_get_host_inventory` (allowlisted host facts; it needs agent 0.6.28,
820
+ not yet released, and says so).
821
+ - **Structured output:** read tools declare an `outputSchema` and return
822
+ `structuredContent`; one-time secrets stay in the text and never in the
823
+ structured result.
824
+
825
+ ## Local and hosted parity (0.46.0)
826
+
827
+ The local package now carries the 16 tools that only the hosted connector had:
828
+
829
+ - projects and environments: `impreza_rename_project`, `impreza_delete_project`,
830
+ `impreza_rename_environment` and `impreza_delete_environment`;
831
+ - variable groups: `impreza_get_variable_group` and `impreza_set_variable_group`;
832
+ - configuration promotion: `impreza_prepare_config_promotion`,
833
+ `impreza_get_config_promotion` and `impreza_apply_config_promotion`;
834
+ - ordered environment deploys: `impreza_deploy_environment`,
835
+ `impreza_get_environment_deploy` and `impreza_list_environment_deploys`;
836
+ - agent updates: `impreza_get_update_policy`, `impreza_set_update_policy` and
837
+ `impreza_request_agent_update`;
838
+ - Shield: `impreza_set_shield`.
839
+
840
+ Tool annotations (read-only, destructive, idempotent) now match the hosted
841
+ connector. A destructive tool called with `confirm` missing or false is refused
842
+ before any request is sent.
843
+
844
+ ## Point-in-time PostgreSQL recovery (0.45.0)
845
+
846
+ Six tools cover status, configuration, a recovery drill, and prepare/get/apply
847
+ of a reviewed UTC recovery point: `impreza_get_pitr`, `impreza_configure_pitr`,
848
+ `impreza_drill_pitr`, `impreza_prepare_pitr_restore`,
849
+ `impreza_get_pitr_restore`, and `impreza_apply_pitr_restore`. Status uses read
850
+ scope; changes use deploy scope. The hosted connector requires a credential
851
+ without resource confinement because physical PostgreSQL recovery can cover
852
+ several bindings on a provider.
853
+
854
+ WAL and base backups consume the account's storage. After six consecutive
855
+ failures, automatic work pauses until the cause is repaired and configuration
856
+ is saved again. Disabling stops protection but retains stored objects. A
857
+ restore requires the review digest and `confirm: true`, creates a new database,
858
+ and never redirects the live application. Poll the review until its receipt
859
+ says `verified` or `failed`; acceptance alone is not a successful recovery.
860
+
861
+ ## Scheduled tasks (0.45.0)
862
+
863
+ `impreza_create_task` creates a scheduled task on an app and `impreza_update_task`
864
+ changes one that exists (any field you leave out keeps its current value, so
865
+ `enabled=false` pauses a task without losing its schedule or history), as on the
866
+ hosted connector. They replace `impreza_schedule_task`, which is gone: update
867
+ any client or prompt that still calls it. `impreza_list_tasks`,
868
+ `impreza_run_task` and `impreza_delete_task` are unchanged.
869
+
870
+ ## VPS resize (0.44.0)
871
+
872
+ `impreza_vps_resize` gives a configurable VPS more vCPUs, memory or disk. Price it
873
+ first with `impreza_api_call` on `/services/{id}/resize/quote`, passing the new
874
+ sizes as `query`: it returns the pro-rated amount due today (the billing
875
+ system's own figure), what the VPS renews at and whether the balance covers it.
876
+ Then call `impreza_vps_resize` with the same sizes and `max_amount` set to that
877
+ `due_today`, so a price that moved in between is refused rather than charged.
878
+ Sizes only go up. The disk is enlarged at once; the new vCPU count and memory
879
+ take effect when the VPS is restarted with `impreza_vps_power` action=reboot (a
880
+ reboot from inside the server keeps the old ones). See
881
+ [Resize a VPS](https://docs.imprezahost.com/order-vps.html#resize).
882
+
883
+ ## Configurable VPS (0.43.0)
884
+
885
+ The VPS is one configurable product: choose the location, operating system,
886
+ vCPUs, memory and SSD disk. `impreza_vps_offer` lists every choice with its
887
+ price per unit for each billing cycle, in the account currency; given a whole
888
+ configuration (`billing_cycle`, `location`, `os`, `cpu_cores`, `memory_gb`,
889
+ `disk_gb`) it returns the exact price, whether the balance covers it and
890
+ whether that location has room right now. `impreza_order_vps` orders that
891
+ configuration with `product_id` left out; fixed plans such as Tor Hosting are
892
+ still ordered by `product_id`. The price charged is the price quoted. See
893
+ [Order a VPS](https://docs.imprezahost.com/order-vps.html).
894
+
895
+ ## Private onion previews and retained identities (0.42.0)
896
+
897
+ Preview creation supports `private: true`; optionally supply one or more `onion_clients`.
898
+ Supplied reviewers use a name and X25519 public key. Without supplied clients, a reviewer keypair is generated and the private key is shown once. This mode requires agent
899
+ 0.6.20 with `onion-private-preview-v1`; reviewer authorization is installed
900
+ before the first onion publication. Repeated deploys preserve later revocations.
901
+ Do not combine this option with password-protected HTTPS previews.
902
+
903
+ `impreza_purge_onion_key` requires the exact old onion address and explicit
904
+ confirmation. Queued work is not proof of deletion: inspect its completed
905
+ result. Active addresses are refused. Purge removes retained copies on that
906
+ server; exports and backups elsewhere remain. Releasing a reservation for an
907
+ uninstalled application does not delete key material.
908
+
909
+ See the [onion guide](https://docs.imprezahost.com/onion-services.html)
910
+ for permissions, customer update steps and supported limitations.
911
+