Skip to main content
Glama
imprezahost

Impreza Host MCP Server

by imprezahost
README.md
# impreza-mcp

[Model Context Protocol](https://modelcontextprotocol.io) server for
[Impreza Host](https://imprezahost.com). Lets AI coding tools (Claude
Code, Cursor, Codex CLI, Continue, Zed, ...) deploy customer-built
apps to managed Impreza VPSes without leaving the chat.

When you say "deploy this for me" to Claude with this MCP server
loaded, Claude calls `impreza_deploy_custom` directly — packages your
project, uploads it, builds + runs on your Impreza VPS, and reports
back the URL.

## Why this host and not a mainstream one

Any provider can run your app. This one is built so an **agent can obtain and
operate infrastructure that is not tied to your identity**, end to end, without
you opening a browser:

- **No KYC, and no email address, to open an account.** An account is a
  generated client ID plus a recovery token. No documents, no selfie, no phone
  number.
- **Funded in cryptocurrency.** `impreza_topup` accepts BTC, XMR, USDT and TRX,
  and `impreza_order_vps` buys the server from that balance. The agent can go
  from "I need a server" to a running deployment without a card.
- **Offshore and onshore jurisdictions side by side**, chosen per project
  rather than per account.
- **Tor is a deployment target, not an add-on.** `impreza_add_onion` gives a
  deployment a `.onion` address in one call, so an agent can publish a hidden
  service the same way it publishes a normal site.
- **No API key in your config.** The hosted connector authenticates over OAuth.

If none of that matters for your project, a mainstream provider is a perfectly
good choice and usually cheaper to start with. This exists for the projects
where it does matter: research and journalism under pressure, censorship
circumvention, security work, and anything that should not be one support
ticket away from being linked to a legal name.

## Status

**Full surface live.** All 116 tools shipped — app deployment plus account +
crypto balance, catalog + ordering, domains/DNS + registration, invoices, VPS
lifecycle with snapshots and backups, dedicated / bare-metal servers, plan
upgrades, and Titan / Google Workspace mailboxes — with a setup wizard that
generates ready-to-paste config snippets for 5 AI tools.

On top of that, everything an app needs after it is running: backup and
restore into the customer's **own** S3 bucket, a timer on an app with its
output kept, outbound webhooks so you stop polling, and reading the app's own
files to find out why it behaves as if it were not configured.

On top of that, everything an app needs after it is running: backup and
restore into the customer's **own** S3 bucket, a timer on an app with its
output kept, outbound webhooks so you stop polling, reading the app's own
files, and running the app's own command line.

The local (`npx`) server and the hosted OAuth connector expose the **same 116
tools**, so nothing is lost by picking either path.

### New in 0.11.0

**Run the app's own command line.** WP-CLI for WordPress, `occ` for
Nextcloud, `gitea admin` for Gitea, and the database client for a dump —
`impreza_app_cli` to run, `impreza_get_cli_run` to collect the output. Call
`impreza_get_cli_run` with no `run_id` first: it names the command lines the
app has, says what each is for, and gives one example that works.

- **No docker socket, and that is measured rather than claimed.** The command
  runs in a separate container built from the app's own image, joined to the
  app's own network, with its data mounted — the shape the official CLI
  images are designed for. `cap_drop: ALL`, and no new privilege on the
  machine.
- **Arguments are a list, never a string.** Each element becomes one `argv`
  entry through `execve`, so nothing is split, globbed or substituted:
  quoting is not your problem, and a `$` or a `;` inside a value is just
  that. Verified against a live site — `option update blogname
  'dollars $HOME and a ; semicolon'` reads back exactly as sent.
- **Destructive, and treated as such.** A command line can do anything the
  app itself can, so it needs the `manage` scope and is confirmation-gated.
  Arguments are free rather than allowlisted: that is the same ceiling
  `uninstall` with `purge_data` already sits at, and a list of `wp`
  subcommands would age badly while protecting nothing the confirmation gate
  does not.
- **The CLI version follows the app.** Where the command line is the app's
  own image it is taken from that deployment, so a catalog bump carries it —
  running `occ` from an older Nextcloud against a newer database is how a
  maintenance command corrupts an install.

Custom deployments have no command line here: it is your own image and the
platform cannot know what it ships. Use a scheduled task of kind `command`
for those.

### New in 0.10.0

**Look inside the app's own files.** `impreza_get_logs` reads stdout, which
cannot answer the question a deploy that came up wrong actually raises: did
that variable reach the config file? Two tools now do —
`impreza_inspect_app` to ask and `impreza_get_app_read` to collect the answer.

- **Four actions, and no fifth:** `list` a directory, `read` a file (capped at
  256 KB), `tail` its last lines, `grep` under a path with an extended regular
  expression. There is no command string in the interface, and therefore no
  shell.
- **Read-only by construction.** A one-shot container mounts the app's storage
  read-only — the same mechanism the backup already uses — with no docker
  socket and no write capability. So it also works on an app that is `failed`
  and will not start, which is when it is wanted most.
- **Only the app's own storage:** `data`, or one of the named volumes the app's
  manifest declares (a WordPress exposes `data` and `wp_db`, so its database
  files are readable too). Call `impreza_get_app_read` with no `read_id` to
  see the list for a given app.
- **What comes back is untrusted and often secret** — an app's config file is
  where its database password lives. It reaches you and nothing else: the
  field is on our request log's deny list, and the record is deleted within a
  day.

### Since 0.6.1

Three releases the npm page never described, each one a whole capability:

- **0.7.0 — backup and restore** of a deployment's data into the account's own
  Impreza S3 bucket, with a per-chunk SHA-256 manifest that sits beside the
  data so the copy stays verifiable with the customer's own credentials and no
  call to us. Plus a schedule (daily by default, keeping 3), and a restore
  that can land in a *different* app, which is how an app moves between
  servers.
- **0.8.0 — scheduled tasks:** a timer on an app with the output kept, for the
  apps that need one to behave correctly (Nextcloud's cron, WordPress's
  `wp-cron` on a site with no visitors).
- **0.9.0 — outbound webhooks:** subscribe to deploy, backup and VPS events
  and stop polling, with HMAC-signed delivery and a delivery log.

### New in 0.6.1

**`tools/list` now reflects what your account actually owns.** About a third of
the tools only make sense if you have the machine behind them — VPS power
controls with no VPS can only ever answer "not found" — so those are left out
of the listing until you own one. Typical accounts see around 70 tools instead
of 97, which is roughly six thousand fewer tokens of context spent before you
ask anything.

Three things worth knowing about how it behaves:

- **The purchase path is never filtered.** An account that owns nothing is the
  one that needs to buy something, so ordering, top-up, invoices and the
  catalogue are always listed.
- **Buying something grows the list mid-session.** The server sends
  `notifications/tools/list_changed` on the same response as the order, so a
  client that honours it picks up the new tools without reconnecting.
- **It fails open.** If this server cannot reach the API to ask, it lists
  everything rather than guess.

Hiding a tool is not an authorization boundary — the API still refuses anything
your account does not own. This only stops the listing from carrying tools that
could never work for you.

### New in 0.6.0

Four things that only make sense on a host built for anonymity:

- **Dark previews** — push a branch, get a preview on its own ephemeral Tor
  `.onion`. Every other platform's preview URL puts your branch name into
  public DNS and into a permanent Certificate Transparency log; branch names
  carry ticket ids, customer names and unshipped features. This one creates
  neither record, and destroys its keys when the branch is deleted or the TTL
  runs out. `impreza_configure_previews`, `impreza_list_previews`,
  `impreza_retire_preview`.
- **Agent sub-credentials** — mint a narrower credential from the one you hold
  and hand it to a subtask: one deployment, one hour, no spending. A child can
  never exceed its parent on any axis, and revoking a credential revokes
  everything it minted, however deep. `impreza_mint_subcredential`,
  `impreza_list_credentials`, `impreza_revoke_credential`,
  `impreza_agent_activity`.
- **A privacy report you can check** — `impreza_privacy_report` returns every
  field we store about your account, what it is for, how long it survives and
  who else sees it, and then measures our own retention against the oldest
  record that actually survived. Counts and date ranges, never contents.
- **Ask before you guess** — search our docs, validate a deployment manifest
  before deploying it (including a privacy lint for third-party CDNs, public
  DNS resolvers and leaked secrets), or run a diagnosis when something is
  wrong. `impreza_search_docs`, `impreza_validate_manifest`, `impreza_doctor`.

Plus the Tasks extension, so long operations report completion instead of
leaving you to poll, and three MCP Apps panels — a payment card, a server card
and a deploy wizard — that render inside clients which support them.

The table below is a **selection**, not the full list — it covers the tools
most people reach for first. Your client's own tool listing is authoritative,
and `impreza_api_search` finds anything not named here.

| Tool | Wraps |
|------|-------|
| **Apps & deployments** | |
| `impreza_list_servers` | `GET /v1/platform/servers` |
| `impreza_list_apps` | `GET /v1/platform/apps` |
| `impreza_list_deployments` | `GET /v1/platform/deployments` + `/custom` (merged) |
| `impreza_deploy_custom` | `POST /v1/platform/deployments/custom` (3 modes) |
| `impreza_deploy_catalog_app` | `POST /v1/platform/deployments` |
| `impreza_uninstall_deployment` | `POST .../uninstall` |
| `impreza_get_logs` | `POST .../logs` (sync tail, last N lines) |
| `impreza_restart_deployment` | `POST .../restart` |
| `impreza_redeploy_deployment` | `POST .../custom/{id}/redeploy` (in-place rebuild, same domain) |
| `impreza_add_onion` | `POST .../onion/add` |
| `impreza_change_domain` | `POST .../domain` |
| `impreza_git_webhook_status` | `GET .../custom/{id}/git-webhook` |
| `impreza_git_webhook_connect` | `POST .../custom/{id}/git-webhook/connect` |
| `impreza_git_webhook_disconnect` | `POST .../custom/{id}/git-webhook/disconnect` |
| **Account & balance** | |
| `impreza_account_info` | `GET /v1/account` |
| `impreza_list_services` | `GET /v1/account/services` |
| `impreza_topup` | `POST /v1/account/topup` — top up in BTC / XMR / USDT / TRX |
| `impreza_topup_status` | `GET /v1/account/topup/{invoice_id}` |
| `impreza_topup_payment` | `GET /v1/account/topup/{invoice_id}/payment` — crypto address + amount to pay |
| **Catalog & ordering** | |
| `impreza_list_products` | `GET /v1/products` — plans + pricing (filter `type=server` for VPS/dedicated) |
| `impreza_order_vps` | `POST /v1/orders` — buy from balance; born deployable (`@agent`); 202 + poll `impreza_list_servers` |
| **Domains & DNS** | |
| `impreza_domain_check` | `GET /v1/domains/check` |
| `impreza_domain_details` | `GET /v1/domains/{domain}` |
| `impreza_list_dns` | `GET /v1/domains/{domain}/dns` |
| `impreza_add_dns_record` | `POST /v1/domains/{domain}/dns` |
| `impreza_update_dns_record` | `PUT /v1/domains/{domain}/dns` |
| `impreza_delete_dns_record` | `DELETE /v1/domains/{domain}/dns` |
| `impreza_set_nameservers` | `PUT /v1/domains/{domain}/nameservers` |
| **VPS lifecycle** (Proxmox) | |
| `impreza_vps_status` | `GET /v1/vps/proxmox/{id}/status` |
| `impreza_vps_power` | `POST /v1/vps/proxmox/{id}/{start\|shutdown\|reboot\|stop}` |
| `impreza_vps_list_backups` | `GET /v1/vps/proxmox/{id}/backups` |
| `impreza_vps_create_backup` | `POST /v1/vps/proxmox/{id}/backups` |
| `impreza_vps_list_templates` | `GET /v1/vps/proxmox/{id}/templates` |
| `impreza_vps_reinstall` | `POST /v1/vps/proxmox/{id}/reinstall` — destructive (wipes) |

## Install + setup

### Prerequisites

  - Node ≥ 20
  - An Impreza Host account with an API key + secret
    (clientarea → API Keys; the IP of the machine running this MCP
    server must be whitelisted under the key)

### One-shot via `npx`

No global install needed — `npx impreza-mcp` works.

### Or install globally

```sh
npm install -g impreza-mcp
```

### Get a ready-to-paste config snippet

The fastest path: ask the binary itself.

```sh
npx impreza-mcp setup --tool claude-code
# also: cursor | continue | zed | codex-cli
```

The wizard prints the JSON block to drop into your AI tool's MCP
config + the exact file path + the post-config step (usually "fully
quit + re-open the AI tool"). It does NOT write to disk — paste it
yourself so you don't accidentally clobber an existing config with
other MCP servers.

### Or wire it in manually

**Claude Code** — add to `~/Library/Application Support/Claude/claude_desktop_config.json`
(macOS) or `%APPDATA%/Claude/claude_desktop_config.json` (Windows):

```json
{
  "mcpServers": {
    "impreza": {
      "command": "npx",
      "args": ["-y", "impreza-mcp"],
      "env": {
        "IMPREZA_API_KEY": "imp_...",
        "IMPREZA_API_SECRET": "..."
      }
    }
  }
}
```

Restart Claude Code. The tools appear under the MCP icon.

**Cursor** — add to `~/.cursor/mcp.json` (same shape as above).

**Continue** — add to `~/.continue/config.json`:

```json
{
  "experimental": {
    "modelContextProtocolServers": [
      {
        "transport": {
          "type": "stdio",
          "command": "npx",
          "args": ["-y", "impreza-mcp"],
          "env": {
            "IMPREZA_API_KEY": "imp_...",
            "IMPREZA_API_SECRET": "..."
          }
        }
      }
    ]
  }
}
```

**Zed** — add to your settings:

```json
{
  "context_servers": {
    "impreza": {
      "command": {
        "path": "npx",
        "args": ["-y", "impreza-mcp"],
        "env": {
          "IMPREZA_API_KEY": "imp_...",
          "IMPREZA_API_SECRET": "..."
        }
      }
    }
  }
}
```

## Usage in chat

After setup, talk to your AI naturally:

> *"List my Impreza servers."* → calls `impreza_list_servers`
>
> *"Deploy this directory to my Impreza VPS, expose via .onion."* →
> packages the cwd as a Dockerfile-mode custom deploy, uploads, deploys
> with `onion=true`, reports the .onion address.
>
> *"What apps are running on my agent?"* → calls
> `impreza_list_deployments` filtered to the right server.

## Auth + security

`IMPREZA_API_KEY` + `IMPREZA_API_SECRET` live in the AI tool's MCP
config env — not in any file on disk owned by `impreza-mcp` itself.
The MCP server holds the secret only in memory and only attaches it
as HTTP request headers.

The IP of the machine running this MCP server (almost always your
laptop) must be on the API key's whitelist. Manage the whitelist in
your Impreza clientarea.

## Build

```sh
npm install
npm run build
# dist/server.js is the entry point
```

## License

MIT — see `LICENSE`.

TDQS

A4/5.0

Scored across 32 tools

Disambiguation5/5

Each tool targets a distinct resource-action pair with detailed descriptions, making it easy for an agent to select the correct tool without confusion.

Naming Consistency5/5

All tools follow a consistent 'impreza_verb_noun' pattern (e.g., impreza_list_servers, impreza_add_dns_record), with no mixing of conventions.

Tool Count3/5

With 32 tools, the server covers a broad hosting management scope, but this exceeds the typical 3-15 well-scoped range, feeling somewhat heavy though not excessive.

Completeness4/5

The tool set covers account, domain, DNS, deployment (catalog & custom), VPS, webhook, and billing operations. Minor gaps exist (e.g., no backup restoration tool), but the core workflows are well-covered.

Maintenance

ActivityMaintained
ResponsivenessNo issues