# Connect an AI tool to Impreza Host

Source: https://docs.imprezahost.com/tutorials/ai-mcp-integration.html

Talk to your infrastructure in plain language: _"what do I have running?"_, _"deploy this project to my Impreza server and give me the URL"_. Impreza speaks **MCP** (Model Context Protocol - the "USB standard" AI tools use to gain new abilities), so the AI can act for you without leaving the chat. There are **two ways to connect** - start with the easy one.

**No account yet?** An AI agent can create its own Impreza account with **no e-mail and no KYC** in a single call: connect to `https://mcp.imprezahost.com/mcp` with no token and call the `impreza_bootstrap_account` tool (or `POST /v1/account/bootstrap`). Before that, the same connection can already [look around](#lobby) without an account. You get back a login ID + an operating credential. **Already have a server?** Call `impreza_add_server`: the [first external server is free](#add-server), with no plan and no balance. To run on Impreza hardware instead, fund the account in Bitcoin/Monero and order a VPS - fully unattended. The two paths below assume you (or a customer) already have an account.

## Anonymous account credentials and privacy

Since **9 October 2026**, `impreza_bootstrap_account` and
`POST /v1/account/bootstrap` return an MCP bearer token valid for **15 minutes**.
Read `mcp_token_expires_at` and `mcp_token_ttl_seconds` from the response, then
reconnect your MCP client with `mcp_token`. Save the returned `account_id`,
`api_key`, `api_secret` and one-time `recovery_code` in a private credential
store. The REST key does not expire when the MCP token expires; account recovery
with the recovery code remains available after MCP expiry.

**Older anonymous-account MCP tokens issued without an expiry expire on
16 October 2026 at 21:48 UTC.** Renew before that deadline to keep your automation
connected. This change concerns anonymous-account MCP tokens; the OAuth
connector and the agent's registration token have separate lifecycles.

### Renew through REST

Call `POST /v1/credentials` with the account's REST key and secret in
`X-API-Key` and `X-API-Secret`. The expired MCP bearer is not the authentication
for this request. The response's `data.token` is shown once; store it privately,
read `data.expires_at`, and reconnect MCP with the new bearer before it expires.

This POSIX-shell example reads credentials from environment variables, requests
900 seconds and only `read` and `deploy`, and saves the response to a new private
file. Set `IMPREZA_API_URL` to `https://api.imprezahost.com` for this HTTPS example.
Populate `IMPREZA_API_KEY` and `IMPREZA_API_SECRET` from your credential store;
do not paste them into a chat or shell history. Keep shell tracing disabled.

```sh
(
  umask 077
  : "${IMPREZA_API_URL:?Set the official REST base URL}"
  : "${IMPREZA_API_KEY:?Load the account REST key}"
  : "${IMPREZA_API_SECRET:?Load the account REST secret}"
  renewal_file=$(mktemp "${TMPDIR:-/tmp}/impreza-mcp-renewal.XXXXXX") || exit 1
  curl --fail --silent --show-error --proto '=https' --config - \
    --request POST --header 'Content-Type: application/json' \
    --data '{"scopes":["read","deploy"],"ttl_seconds":900}' \
    --output "$renewal_file" <<EOF
url = "${IMPREZA_API_URL}/v1/credentials"
header = "X-API-Key: ${IMPREZA_API_KEY}"
header = "X-API-Secret: ${IMPREZA_API_SECRET}"
EOF
  result=$?
  if [ "$result" -ne 0 ]; then rm -f "$renewal_file"; exit "$result"; fi
  printf 'Save the renewal response from this private file: %s\n' "$renewal_file"
)
```

The example does not grant `manage`, so it cannot authorize purchases. If your
workflow needs `manage`, request it explicitly with positive `spend_cap_cents`
and `spend_monthly_cap_cents` ceilings in the account currency's minor units.
Renewal creates a **new credential**: it does not copy the old token's spending
history or optional restrictions. Request resource restrictions, quotas and
approval policy explicitly when needed; renewal is not a reset of your budget
policy. Account limits and the REST key's granted scopes still apply. Move the
response into your private credential store and remove the temporary file.

### Creation IP retention

The raw IP used for anonymous-account creation abuse limits is cleared after
**24 hours on the next cron pass**. Cleanup is batched, so a backlog can take
additional passes. Operational idempotency metadata remains for the account's
lifetime; this cleanup does not erase backups or other records. The account's
`privacy_report` declares the retention rule and cleanup state. A Tor connection
changes the transport; it does not promise that every account record is erased.

## Before sign-up: what the lobby can read

Without a token, the hosted connector offers `impreza_bootstrap_account` and a few
reads of public information. None of them writes anything or reads an account:

| Tool | What it answers |
| --- | --- |
| `impreza_search_docs` | Search this documentation |
| `impreza_vps_offer` | VPS locations, operating systems, sizes and prices, or the price of one configuration |
| `impreza_list_products` | Orderable products and prices |
| `impreza_list_apps` | The app catalog |
| `impreza_validate_manifest` | Check a deploy manifest before deploying |
| `impreza_domain_check` | Domain availability and price |
| `impreza_domain_pricing` | Domain prices by extension |

These calls are limited per visitor per minute. The two domain tools also have a daily
allowance per visitor and a daily total for all visitors, because they query the registrar.
The counter identifies a visitor by a keyed fingerprint of the address that changes
every day; it keeps no address. These calls are not written to the MCP call log.
Everything else needs an account: create one with `impreza_bootstrap_account`.

## Add a server you already have (free)

Every account can connect **one server outside Impreza for free** (any Linux
machine with root access and outbound HTTPS). No plan or account balance is needed.
`impreza_add_server` (scope `deploy`) returns a one-line install command and its
one-time token, valid for **10 minutes**. Run that command as root on that server.
Once the agent is online, `impreza_list_servers` shows the server, and apps deploy
to it as they do to an Impreza VPS.

| Tier | External servers | How you get it |
| --- | --- | --- |
| Starter | 1 | Every account, with no Impreza service |
| Bundled | 5 | Any active Impreza VPS on the account |
| Unlimited | No limit | The Unlimited plan |

The response's `used` count includes install tokens that have not been used yet,
so an unused token holds a slot until it expires. New external servers are also
limited per day. The token is shown once; Impreza keeps only its hash, so call the
tool again if the token is lost or expires.

On an account without a paid service, apps keep the [Shield](/security/shield.html)
on (at least the audit-only standard profile) and the default egress policy.
Hostnames on the platform domain also need a paid service. Without one,
deploy with a domain you own, or as an [onion-only app](/onion-services.html).

## The idea in one sentence

Both remote OAuth and the local MCP server can operate your account within the permissions you grant. Use the remote connector for a quick start; use the local server when you need to upload a project folder from your computer.

## How many MCP tools are available?

This section is the canonical documentation reference for tool counts. Other
pages and package READMEs should link here instead of promising one universal
total. A historical release announcement describes that release, not today's
connection inventory.

**Verified snapshot: 14 October 2026; local package row updated 21 October 2026 (0.55.1).** These totals count distinct tool names within each interface. Local and hosted catalogs overlap, so their totals are not added together.

| Measurement | Tool count | What it means |
| --- | --- | --- |
| Local `impreza-mcp` **0.55.1** package catalog | **219** | Named tool definitions shipped in this version, before account filtering. |
| Hosted MCP enabled catalog | **221** | Named tool definitions enabled in production, before account and credential filtering. Disabled features are excluded. |
| Hosted MCP account snapshot | **211** | The list returned for one verified account with the full connector profile on this date. Other accounts can receive a different list. |

The local package count was checked against the [published npm version](https://www.npmjs.com/package/impreza-mcp/v/0.55.1). The hosted rows are the 14 October measurement. Local and hosted releases evolve independently; identical tool counts or complete parity are not assumed.

**Your connection's exact count comes from `tools/list`.** Account services, connector profiles and credential tool restrictions can change the visible list. The local server also applies account service filtering. Granted scopes authorize tool calls; a visible tool can still require a compatible Agent, an eligible service or application, and any operation-specific confirmation.

After initializing your MCP connection, request its tool list:

```json
{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}
```

If the response includes `nextCursor`, request the next page with `params.cursor` until all pages have been collected. Count unique `name` values in `result.tools`. Keep the installed package version or hosted connector profile and the measurement date with that result. Refresh the list after changes to your services or credential restrictions.

This table is a dated catalog measurement. The list returned by your own connection determines what your AI client can discover at that moment.

## Two ways to connect

|   | A · Remote connector + OAuth | B · Local `impreza-mcp` |
| --- | --- | --- |
| **Best for** | Any client that supports remote MCP connectors - **Claude** (incl. the web app), **Codex CLI**, **VS Code / GitHub Copilot**, and other coding agents. Zero install. | Shipping **local code** - uploading a project folder straight from your machine to build & deploy. |
| **Setup** | Paste a URL, click _Authorize_. No install. | One `npx` command + an API key. |
| **Credentials** | None to copy - OAuth, signed in your clientarea. | `X-API-Key` + secret (or pair with a code). |
| **Tools** | Enabled tools for your account and connector profile; calls require granted scopes. | Tools in the installed package, filtered by account services; supports local project uploads. |
| **Runs where** | Our server (`mcp.imprezahost.com`). | Your machine (next to the AI tool). |

**Both work side by side, and nothing was removed.** The classic key + secret + IP whitelist setup keeps working exactly as before - these are just easier on-ramps. Both can do the full job; pick A for the fastest setup (Claude, Codex CLI, any remote-connector client - no install), B when you need to upload a local project folder from your own machine.

## Install in Cursor or VS Code

Connect the hosted MCP server with the buttons below. Your editor will ask you
 to review the server configuration; finish OAuth in your browser and review the
account permissions. Tool approvals remain under your control.

<div class="tut-grid">
<a class="tut-card" href="cursor://anysphere.cursor-deeplink/mcp/install?name=impreza&amp;config=eyJ1cmwiOiJodHRwczovL21jcC5pbXByZXphaG9zdC5jb20vbWNwIn0%3D"><strong>Install in Cursor</strong><p>Open Cursor and review the hosted connector.</p></a>
<a class="tut-card" href="vscode:mcp/install?%7B%22name%22%3A%22impreza%22%2C%22type%22%3A%22http%22%2C%22url%22%3A%22https%3A%2F%2Fmcp.imprezahost.com%2Fmcp%22%7D"><strong>Install in VS Code</strong><p>Open VS Code and review the hosted connector.</p></a>
</div>

The buttons contain only the server name and public HTTPS endpoint. If your
browser cannot open an editor link, add `https://mcp.imprezahost.com/mcp` manually
in the editor's MCP settings. These links configure remote access; use the local
server section below for local folder uploads.

### Configure another supported client

The optional [add-mcp utility](https://github.com/neon-solutions/add-mcp) writes
MCP configuration for the client you select. With Node.js and npm installed,
run this from the project where you want the connection:

```sh
npx add-mcp@2.4.1 https://mcp.imprezahost.com/mcp --name impreza
```

npm may offer to download this pinned third-party utility. Review that prompt,
choose the client and configuration scope interactively, and review the file
changes before accepting. Authenticate in the chosen client afterward. This
command does not include credentials or enable automatic tool approval.

For [Gemini CLI](https://geminicli.com/docs/tools/mcp-server/), the official MCP
configuration guide remains active (checked 12 October 2026). If it is already
installed, use its own command:

```sh
gemini mcp add --transport http impreza https://mcp.imprezahost.com/mcp
```

Complete OAuth in a browser and retain the client's tool confirmation policy.
A directory listing does not grant access to your account.

## VS Code & GitHub Copilot - the extension does both

In VS Code you don't have to wire up either path by hand. Install the **[Impreza
Host extension](https://marketplace.visualstudio.com/items?itemName=imprezahost.impreza-host)**
from the Marketplace and it contributes **both** servers to VS Code's own MCP
list - nothing to paste into a config file.

1.  Install **Impreza Host - deploy from your AI** (publisher `imprezahost`).
2.  Command Palette → **MCP: List Servers**. Two entries appear:

    - **Impreza Host (OAuth)** - the [remote connector](#oauth) below. Start it
      and VS Code runs the OAuth flow in your browser; you approve the scopes in
      your own clientarea and nothing is copied by hand.
    - **Impreza Host (local, API key)** - the [local server](#local) below. The
      first start asks for your API key + secret and keeps them in VS Code's
      **SecretStorage** - never in `settings.json`, never in the workspace. It
      runs with your open folder as its working directory, so this is the entry
      that can upload the project you have in front of you.

3.  Open **Copilot Chat** in _Agent_ mode and check that the tools icon lists
    Impreza. Then just ask: _"deploy this project to my Impreza server and give
    me the URL"_.

Requires **VS Code 1.101 or newer** (that release added MCP server providers).
The `npx -y impreza-mcp setup` helper has no `vscode` target because the
extension _is_ the setup; everything below about scopes, keys and tools applies
unchanged to both entries.

## A · Remote connector + one-click OAuth

If your AI client supports **remote MCP connectors** (Claude and Codex CLI do), this is the fastest path: **no install, no API key, no IP whitelist**. You paste one URL, the AI sends you to your Impreza clientarea to sign in and approve, and you're connected. Authorization happens entirely **inside your own account** - the client does not receive your account password or API secret; it receives a scoped access token.

~~~text
 ┌───────────┐  add connector   ┌──────────────────┐  sign in  ┌─────────────────────┐
 │  Claude / │ ───────────────▶ │ mcp.imprezahost  │ ────────▶ │ portal.imprezahost  │
 │ MCP client│  paste URL +     │ .com/mcp (remote)│  approve  │ .com (your account) │
 └───────────┘ ◀─────────────── └──────────────────┘ ◀──────── └─────────────────────┘
   tool calls     "Authorize"        access token       consent screen (you pick scope)
~~~

### Connect in 4 steps

1.  In a GUI client (e.g. **Claude**): **Settings → Connectors → Add custom connector**. Terminal agents like **Codex CLI** use the command line instead - see the note right under these steps.
2.  Give it a name (e.g. `Impreza`) and paste the server URL:

    ```
    https://mcp.imprezahost.com/mcp
    ```

3.  Click **Connect**. The client registers itself automatically and opens an Impreza page - **sign in to your clientarea** if you aren't already.
4.  Review the **consent screen**, including the app name, redirect target and permissions. **Read** and **Deploy** are checked by default; **Manage** is unchecked. For a read-only connection, **uncheck Deploy** and leave Manage unchecked, even if the client requested only `read`. Click **Authorize**, then return to the client and confirm that it completed the connection.

**Codex CLI** (and other terminal agents) do the same over the command line - add the remote server, then run the OAuth login. Add to `~/.codex/config.toml`:

```
[mcp_servers.impreza]
url = "https://mcp.imprezahost.com/mcp"
```

then start the login (opens the same Impreza sign-in + consent, then you're connected):

```
codex mcp login impreza
```

See the [official Codex MCP documentation](https://learn.chatgpt.com/docs/extend/mcp?surface=cli) for client configuration and OAuth commands.

**Why this is safe even though it's so quick.** You approve the connection _inside your own clientarea_, after logging in - the AI client only receives a scoped, revocable token, never your password or API secret. The consent screen lets you pick exactly what to grant - **Read** and **Deploy** are offered, **Manage** (destructive, e.g. uninstall) is opt-in - and you can revoke it any time (below). Third-party AI clients register themselves, so the consent screen marks them **"unverified"** - that's expected; verify the app name and the redirect target look right before approving.

### No account yet? Create one while connecting

A person connecting an application such as Claude can create an account without
an e-mail address directly on the Impreza authorization page, then decide what
the application may access. The [anonymous account tool](#anonymous-account)
for AI agents keeps working as before.

**When the option is shown.** The authorization page offers **Create an
anonymous account now** only when all of these hold:

- you are not signed in yet;
- you opened it on the clearnet portal, and the portal is set up for HTTPS. It
  is **not** offered on the onion portal;
- the application started a standard, protected OAuth request (with `state` and
  PKCE `S256`). Requests without them get the normal sign-in page instead.

Otherwise you see the normal sign-in page. Where the option is shown, **Sign in
to an existing account** stays available next to it. An account that is already
signed in goes straight to the consent screen and no new account is created.

**The steps.**

1. Choose **Create an anonymous account now**.
2. The page shows your **account ID** and a **recovery code**, once. Save both
   somewhere private before you continue: the recovery code is how you get the
   account back. It is not kept in your connection session after this page.
3. Tick **I saved my account ID and recovery code** and choose **Continue to
   review access**. You are signed in to the new account.
4. On the consent screen, review the application and the access it asks for.
   The new account is offered **only the access the application requested**.
   Choose **Authorize** or **Deny**. **Deny** returns to the application without
   granting anything.

**Creating the account does not connect the application.** The application gets
access only after you choose **Authorize** on the consent screen, as the owner
of the account. Account creation alone gives the application no API key and no
MCP token.

**It is short-lived and single-use.**

- A pending connection lasts **ten minutes**.
- Starting another connection in the same browser replaces it.
- A form that was changed, has expired or was already used is refused with
  *"…unavailable, changed, expired, or already used. Start again from your
  application."* Start the connection again from your application.

**If something goes wrong after you chose Create.** Every failure in this
sign-up flow shows the same short message, on purpose. If you see it after choosing **Create an anonymous
account now**, **do not submit that form again**: an account may have been
created anyway.

- If you saved the account ID and recovery code, recover the account with them.
- If you did not, contact support so the account's ownership can be reconciled.
  Do not create a second account to work around it.

**Limits.** Account creation is limited per network, per larger network block,
and in total, and the limits are counted even when an attempt fails. When a
limit is reached, creation is refused with the same short message; wait
before you try again, and use the normal sign-in if you already have an
account. Many Tor users share the same exit addresses, so on Tor you can meet a
limit that other people used up.

**Privacy.**

- No e-mail address is asked for.
- **This does not by itself make you anonymous.** How you connect, the
  application you use, and what you do with the account still matter.
- The signup limits are kept as short-lived fingerprints that change every UTC
  day, not as your IP address. They are counted in windows of a minute, an hour
  or a UTC day, and a cleanup job removes them after the window ends (it can
  run late).
- This describes the signup counters only, not every log kept by the hosting
  infrastructure.
- The authorization pages are not cached and send no referrer.

### What you can ask

Use the tools listed for your connection within the scopes you granted. See the [verified tool counts](#tool-count) for the distinction between a catalog total and your account list. For example:

*   _"List my Impreza servers and what's deployed."_
*   _"Deploy this GitHub repo to my VPS at app.example.com with a .onion mirror."_
*   _"Tail the logs for app X and restart it."_
*   _"Uninstall the old staging app."_

**Scope-gated.** Each call to an available tool is checked against what you approved on consent - `read` (see), `deploy` (create & operate), `manage` (destructive, opt-in). A call beyond your grant comes back with a clear "scope does not permit" message; re-authorize to widen or narrow it. The one thing only the local path does: upload a project folder straight from your machine - the hosted connector builds from a git URL or a public image instead.

### Manage & disconnect

Every app you authorize shows up in **clientarea → Impreza API → Connected Apps**, with its scope and last-used time. Click **Disconnect** to revoke its token instantly (the AI client loses access on its next call). You can also remove the connector from the AI client's own settings.

### Short video walkthroughs

See an OAuth connection walkthrough, then two read-only examples with Claude:

- <a class="impreza-video-link" href="https://www.youtube.com/watch?v=gdEqAE0gV9Q" target="_blank" rel="noopener noreferrer" aria-label="Watch MCP OAuth setup on YouTube, opens in a new tab" style="display:inline-flex;align-items:center;gap:.4rem;max-width:100%"><svg width="22" height="16" viewBox="0 0 24 24" aria-hidden="true" focusable="false" style="flex:0 0 22px"><path fill="#FF0033" d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.121 2.136c1.872.505 9.377.505 9.377.505s7.505 0 9.376-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814z"/><path fill="#fff" d="M9.545 15.568V8.432L15.818 12z"/></svg><strong>MCP OAuth setup: connect your AI assistant</strong><span aria-hidden="true">↗</span></a><br>Add the hosted connector, review permissions, make a read-only request and revoke access. One desktop client is shown; setup differs across clients. This is a clearnet example, not a Tor walkthrough.
- <a class="impreza-video-link" href="https://www.youtube.com/watch?v=P1lAj53AjKk" target="_blank" rel="noopener noreferrer" aria-label="Watch List servers and check Agent status on YouTube, opens in a new tab"><svg width="22" height="16" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path fill="#FF0033" d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.121 2.136c1.872.505 9.377.505 9.377.505s7.505 0 9.376-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814z"/><path fill="#fff" d="M9.545 15.568V8.432L15.818 12z"/></svg><strong>List servers and check Agent status</strong><span aria-hidden="true">↗</span></a><br>Find your registered servers and read the Agent's connection state. Agent status is separate from application health.
- <a class="impreza-video-link" href="https://www.youtube.com/watch?v=miwDih_6C9Q" target="_blank" rel="noopener noreferrer" aria-label="Watch Check VPS status, CPU, memory and uptime on YouTube, opens in a new tab"><svg width="22" height="16" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path fill="#FF0033" d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.121 2.136c1.872.505 9.377.505 9.377.505s7.505 0 9.376-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814z"/><path fill="#fff" d="M9.545 15.568V8.432L15.818 12z"/></svg><strong>Check VPS status, CPU, memory and uptime</strong><span aria-hidden="true">↗</span></a><br>Read CPU, memory and uptime for a supported managed VPS. These are VPS metrics, not app metrics; the video explains the memory-reporting caveat.

Opens YouTube in a new tab. No player loads on this page; you can follow the
written instructions without opening YouTube. The two server examples use read-only calls
and need the permitted tools and `read` scope. For connection setup, grant only
the scopes needed for your own task.

**.onion / Tor users:** the hosted connector URL is [http://mcp.imprezareshna326gqgmbdzwmnad2wnjmeowh45bs2buxarh5qummjad.onion/mcp](http://mcp.imprezareshna326gqgmbdzwmnad2wnjmeowh45bs2buxarh5qummjad.onion/mcp). Hosted OAuth supports this endpoint when your client can reach it through Tor and validate its issuer. Discovery on the onion endpoint returns onion addresses for both the protected resource and the authorization server, so a client that follows RFC 9728 stays on Tor through sign-in; a token issued through either address works on both, for the same account and scopes. Discover metadata from that endpoint rather than replacing individual URLs in a clearnet flow. See [OAuth through Tor Browser](/onion-services.html#oauth-browser), including local callback troubleshooting. The local `impreza-mcp` path (Method B) with an API key is also available and does not require browser consent. Its onion API base URL is [http://api.imprezareshna326gqgmbdzwmnad2wnjmeowh45bs2buxarh5qummjad.onion](http://api.imprezareshna326gqgmbdzwmnad2wnjmeowh45bs2buxarh5qummjad.onion); configure an explicit Tor proxy. Find the [portal and documentation onion addresses](/onion-services.html#official-addresses) in the same guide.

## B · Local impreza-mcp - the full deploy toolset

For coding agents - **Claude Code, Cursor, Codex CLI, Continue, Zed** - install the `impreza-mcp` server next to the tool. It runs **on your machine** (not the VPS) and gives the AI all **available tools**, including deploy. This is the AI-native path for shipping code.

~~~text
 ┌───────────┐   tool calls    ┌─────────────┐   HTTPS   ┌───────────────┐   poll    ┌──────────┐
 │ Claude /  │ ──────────────▶ │ impreza-mcp │ ────────▶ │ api.imprezahost│ ◀──────── │  agent   │
 │ Codex / … │ "do the deploy" │ (your laptop)│  X-API-* │ .com (control) │ ────────▶ │ your VPS │
 └───────────┘ ◀────────────── └─────────────┘ ◀──────── └───────────────┘  commands └──────────┘
                "done: URL X"
~~~

**The part that confuses people:** `impreza-mcp` runs **on your machine** (next to Claude Code), **not** on the VPS. It is only the bridge between the AI and our API. The thing that actually runs your apps is the **agent** inside the VPS, covered in [Tutorial 2](/tutorials/agent-apps-panels.html).

### The 3 prerequisites (read this first)

Most beginner problems come from skipping one of these three. The AI will complain with `"no servers on your account"` or `403 IP_NOT_WHITELISTED`, and it is always one of them:

| # | Prerequisite | How to know you have it |
| --- | --- | --- |
| 1 | **A server** (VPS / dedicated, Impreza or BYO) | Shows under **My Apps** |
| 2 | **The agent** running on it | `status: online` in **My Apps** |
| 3 | **An API key** (IP whitelist optional - see below) | Created under **Impreza API** |

#### 1 - A server

Three ways to get one:

*   **Buy a VPS from Impreza** - provisions in ~3 minutes (Proxmox). At checkout you pick what comes installed (see the box below).
*   **Buy a dedicated from Impreza** - bare metal, manual provisioning (24–48h). Our team installs the agent for you.
*   **Bring your own (BYO)** - any Debian / Ubuntu / RHEL / Alpine works. You just install the agent (next step).

**At checkout, pick what to install.** The cart shows a tile picker:

*   **Impreza Agent** - just the agent.
*   **Agent + MCP for AI tools** - the agent plus a post-purchase email with the MCP quickstart. **Best pick for the AI flow in this tutorial.**
*   **A catalog app** (WordPress, n8n, Vaultwarden…) - the agent plus that app.
*   **No app** - bare server, _no_ agent (install later).
*   **A control panel** - exclusive mode, no agent and no Docker catalog. Not for the AI flow; see [Tutorial 2](/tutorials/agent-apps-panels.html#panels).

**MCP purchase default (hosted MCP since 21 October 2026; local `impreza-mcp` 0.54.0 or later):** configurable and fixed-plan VPS purchases through hosted or local MCP request Impreza Agent (`@agent`) when `app` is omitted, `null`, empty or whitespace-only. Direct portal and REST purchases keep No app by default; explicit `none` or another supported app remains your choice, and non-VPS products do not gain an agent. Hosted MCP shows the app in its existing quote and confirmation; local MCP states the default before invocation and buys directly through REST, with `app_requested` recording only the request. A hosted MCP checkout link preserves the presented choice. See [the purchase contract](/order-vps.html). This default does not prove first-boot installation, service binding, heartbeat or readiness, connect your AI tool or create credentials automatically.

#### 2 - The agent running on the server

If you bought from Impreza and selected "Impreza Agent", "Agent + MCP" or a catalog app, wait for installation to complete. Confirm the agent is bound to that service and has an online heartbeat with the required capabilities before continuing to the API key. An accepted purchase or a provisioning status alone does not prove the agent is ready; installation failures or pending work must remain visible.

**Impreza VPS ordered with "No app":** open the VPS in the client area and use **Install the Impreza Agent with one click**. It shows the exact script and its SHA-256, asks for your consent and installs the agent in about a minute, without SSH. It is not offered on Windows, control-panel servers or the RHEL family (AlmaLinux, Rocky, RHEL, CentOS, Oracle Linux); details in [Add the agent later](/order-vps.html#add-agent).

Otherwise (dedicated, bring your own, or a VPS where the button is not offered):

1.  Sign in to [portal.imprezahost.com](https://portal.imprezahost.com/) → **My Apps**.
2.  Click **Bring your own server** (or the **Deploy a custom app** tile, shown when you have a server but no online agent). The panel mints a **10-minute bootstrap token** and prints a one-liner:

    ```
    curl -fsSL https://raw.githubusercontent.com/imprezahost/agent-public/main/install.sh \
      | IMPREZA_BOOTSTRAP=<token-from-panel> sh
    ```

3.  Run it on the VPS as `root`. Either SSH in yourself and paste it, or grant the AI SSH access and let it run the one-liner for you.
4.  Within ~10 seconds the agent appears in **My Apps** as `status: online`. Done.

**The token expires in 10 minutes.** Past that, the curl fails with `BOOTSTRAP_EXPIRED` - just click **Bring your own server** again for a fresh one.

### 3 - API key (IP whitelist is now optional)

This is the credential the local **MCP** uses (different from the agent's own credential, issued automatically at bootstrap).

1.  Portal → **Impreza API**.
2.  Give it a label (`laptop`, `claude`, `ci`…), pick an **IP mode** (next paragraph), and click **Generate New Key**.
3.  **Copy the secret immediately.** It is shown _once_; if you close the modal you cannot retrieve it (delete + recreate). The `imp_…` prefix stays visible. _(Or skip the copy entirely - [pair with a code](#pair).)_

**Choose how the key's second factor (IP) works - per key:**

| IP mode | What it does | Use when |
| --- | --- | --- |
| **Whitelist** | You add the allowed IP(s); calls from anywhere else get `403 IP_NOT_WHITELISTED`. The original behaviour. | Static IP, maximum control. |
| **Trust on first use** | The first successful call **pins** that IP automatically; later calls must match. No manual whitelist step. | You don't know the IP up front but it's stable (laptop, one server). |
| **Key only** | Skips the IP factor entirely - the key + secret alone authenticate. (Availability is set by the operator.) | The caller's IP changes (CI, dynamic egress) and the secret is kept safe. |

**So the `403` is opt-out now.** Pick _Trust on first use_ or _Key only_ and there is no whitelist step at all. Staying on _Whitelist_? Open the **IP Whitelist** tab and add the public IP of the machine running the AI tool (find it with `curl https://api.ipify.org`) - or just click **Add my current IP**. You can change a key's mode any time, and reset a trust-on-first-use binding to re-pin from a new location.

### Install the local MCP (one command)

```
npx -y impreza-mcp setup --tool claude-code
# other examples: cursor | continue | zed
# VS Code: install the extension instead - see "VS Code & GitHub Copilot" above
```

The setup helper prints a configuration snippet and restart instructions. Review the destination and paste the configuration into the client. For Codex CLI, use the TOML example below.

#### Manual config for JSON clients

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

For Codex CLI, add the following to `~/.codex/config.toml`. Supply credentials through environment variables in the shell that starts Codex:

```toml
[mcp_servers.impreza]
command = "npx"
args = ["-y", "impreza-mcp"]
env_vars = ["IMPREZA_API_KEY", "IMPREZA_API_SECRET"]
```

Use the native client configuration above for Codex CLI; older Impreza setup-helper output may show the JSON format used by other clients.

Fill `IMPREZA_API_KEY` / `IMPREZA_API_SECRET` with the key/secret from the step above and **restart** the AI tool. The only machine prerequisite is Node.js (it ships with `npx`).

### Pair with a code (no secret to copy)

Don't want to copy-paste a secret into a config file? **Pair** the tool instead:

1.  Clientarea → **Impreza API → Connect an AI assistant**. Pick what the assistant may do (read / deploy / manage) and generate a **one-time pairing code** (valid 10 minutes).
2.  On the machine running the tool:

    ```
    npx -y impreza-mcp login --code <code-from-clientarea>
    ```

3.  The CLI exchanges the code for a key and stores it in `~/.impreza/credentials.json` (permissions `0600`). The secret is **never printed**. The MCP server reads it automatically - no env vars to set.

Paired keys come pre-scoped to what you picked and default to an IP mode that "just works" from the paired machine, so there's no whitelist step. Revoke a paired key any time from **Impreza API** like any other key.

### Tools by task the AI gains

You never have to memorize these - just talk in plain language and the AI picks the right one. The [remote connector](#oauth) lists the tools available for your connection; this table contains examples, not a complete catalog. Each call is gated by the scope you granted - **• needs only `read`**, unmarked needs `deploy`, and **⚠ needs `manage`** (destructive or financial - opt-in on the consent screen):

| Tool | Does |
| --- | --- |
| **Apps & deployments** |
| `impreza_list_servers` • | List the account's VPSes + agents |
| `impreza_list_apps` • | Browse the catalog |
| `impreza_list_deployments` • | What is currently running |
| `impreza_deploy_custom` | Deploy code from cwd (image / dockerfile / manifest) |
| `impreza_deploy_catalog_app` | Install a catalog app |
| `impreza_uninstall_deployment` ⚠ | Tear down a deployment |
| `impreza_restart_deployment` | Restart a deployment's containers |
| `impreza_redeploy_deployment` | Rebuild a custom deployment in place (domain + URL preserved) |
| `impreza_get_logs` | Tail the last N lines of container logs |
| `impreza_change_domain` | Re-route a running deployment to a new hostname (agent 0.6.22 or later) |
| `impreza_add_onion` | Provision a Tor `.onion` mirror for a deployment |
| `impreza_git_webhook_status` • | Inspect the auto-deploy connection of a git-backed deployment |
| `impreza_git_webhook_connect` | Install a GitHub push webhook (every commit re-deploys) |
| `impreza_git_webhook_disconnect` | Disable auto-deploy (optionally delete the hook on GitHub) |
| **Account & balance** |
| `impreza_account_info` • | Profile, account status, currency + current balance |
| `impreza_list_services` • | List billable services (VPS / hosting / domains) + their IDs |
| `impreza_topup` ⚠ | Create a balance top-up invoice in BTC / XMR / USDT / TRX |
| `impreza_topup_status` • | Poll a top-up invoice until it's paid |
| `impreza_topup_payment` • | Wallet address + exact crypto amount to pay a top-up (BTC/XMR/USDT/TRX/altcoins) |
| **Catalog & ordering** |
| `impreza_list_products` • | List orderable products with pricing (the VPS at its smallest size, Tor Hosting, dedicated) |
| `impreza_vps_offer` • | VPS locations, operating systems, CPU / memory / disk ranges and prices — or the exact price of one configuration |
| `impreza_order_vps` ⚠ | Order a VPS by location, OS and size (or a fixed plan by product id), paid from account balance. This MCP requests `@agent` when `app` is omitted; direct REST and the portal cart default to `none`. Pass `none` for a bare OS. A product that is not a VPS does not gain an agent. Installation is not instant; on an existing server, `impreza_install_agent` still needs confirmation |
| **Domains & DNS** |
| `impreza_domain_check` • | Check availability + price for one or more domains |
| `impreza_domain_details` • | Status, expiry, nameservers, registrar-lock state |
| `impreza_list_dns` • | List a domain's DNS records |
| `impreza_add_dns_record` | Add an A / AAAA / CNAME / MX / TXT / … record |
| `impreza_update_dns_record` | Change an existing DNS record |
| `impreza_delete_dns_record` | Remove a DNS record |
| `impreza_set_nameservers` | Replace a domain's authoritative nameservers |
| **VPS lifecycle** (Proxmox) |
| `impreza_vps_status` • | Power state + live CPU / memory, disk and network I/O counters since start, uptime |
| `impreza_vps_list_backups` • | List available backups |
| `impreza_vps_list_templates` • | List OS templates (to pick one for reinstall) |
| `impreza_vps_power` | Start / shutdown / reboot / stop |
| `impreza_vps_create_backup` | Trigger an on-demand backup |
| `impreza_vps_reinstall` ⚠ | Wipe + reinstall from an OS template (erases all data) |
| `impreza_vps_resize` ⚠ | Give a VPS more vCPUs, memory or disk, at the exact pro-rated price, paid from account balance |
| `impreza_vps_resize_recommendation` • | Whether sustained load (from the optional agent) calls for a larger VPS, and its price; orders nothing |
| `impreza_install_agent` ⚠ | Install the Impreza agent on a VPS that has none, only with the customer's agreement (two calls; see [Add the agent later](/order-vps.html#add-agent-ai)) |
| `impreza_get_agent_install` • | Whether a VPS can take the one-click agent install, and the install's progress |
| `impreza_add_server` | Add a server you already have, outside Impreza: a one-line agent install command valid for 10 minutes (the first external server is free; see [Add a server you already have](#add-server)) |

## Using it in practice

Some prompts that work well (the AI understands plain English):

*   **Ship the current project:** _"Deploy this project to my Impreza server and give me the URL."_ → `impreza_list_servers` to find the `agent_id`, then `impreza_deploy_custom`.
*   **Install a catalog app:** _"Install Vaultwarden on my VPS at vault.example.com with a .onion mirror."_ → `impreza_deploy_catalog_app` with `onion: true`.
*   **Investigate:** _"Is app X down? Show me the last logs and restart it if needed."_ → `impreza_list_deployments` → `impreza_get_logs` → `impreza_restart_deployment`.
*   **Turn on auto-deploy:** _"Connect git auto-deploy so every push to main ships a new version."_ → `impreza_git_webhook_connect`.
*   **Point a domain:** _"Add an A record for app.example.com pointing at my VPS's IP."_ → `impreza_list_dns` to see what's there → `impreza_add_dns_record`.
*   **Manage a VPS:** _"Is my VPS up? Take a backup, then reboot it."_ → `impreza_vps_status` → `impreza_vps_create_backup` → `impreza_vps_power`.
*   **Top up in crypto:** _"Add $50 to my balance in Monero."_ → `impreza_topup` returns a payment link; `impreza_topup_status` confirms once paid.

**Flow tip:** you never copy IDs (`agt_…`, `dpl_…`) by hand. Ask "list my servers" / "list my deployments" and the AI discovers the IDs before acting.

## Host inventory and SSH fingerprints

**Available in the hosted connector and local MCP 0.48.0 or later:** `impreza_get_host_inventory` withholds SSH
host-key fingerprints by default in both the hosted connector and local MCP.
The `fingerprints` array remains empty to preserve the inventory schema; this
does not mean the server has no host keys. Other inventory facts remain visible.

Only set `include_ssh_fingerprints: true` when you explicitly want those values
sent to the AI client. Although SSH host-key fingerprints are public, scan
databases can associate them with a server's public IP. A third-party AI provider
receiving them may be able to correlate a server or `.onion` service with that
address. Impreza does not submit inventory to a model automatically; a connector
or local MCP can send its returned data to the provider you chose.

The portal and direct REST inventory continue to include the public fingerprints.
The generic `impreza_api_call` reader also withholds fingerprints, including
when a query requests them; use the dedicated inventory tool to opt in.
Existing local installations need an explicit update to MCP 0.48.0 or later.
Do not assume an older MCP withholds these values.

## Troubleshooting

| Symptom | Cause | Fix |
| --- | --- | --- |
| Connector says `"automatic client registration isn't supported"` | Old cached connector entry | Remove the connector and re-add `https://mcp.imprezahost.com/mcp` - registration is automatic now |
| OAuth screen says the app is **unverified** | Expected - third-party AI clients self-register | Check the app name + redirect look right, then Authorize. Revoke later under Connected Apps |
| `403 IP_NOT_WHITELISTED` (local MCP) | Key is in _Whitelist_ mode and the IP isn't listed | Add it under **Impreza API → IP Whitelist** (or click **Add my current IP**), or switch the key to _Trust on first use_ / _Key only_ |
| `"no servers on your account"` | You have a VPS but no agent installed | Do prerequisite 2 (My Apps → Bring your own server) |
| `BOOTSTRAP_EXPIRED` | The 10-min token expired | Generate another via Bring your own server |
| AI does not see the `impreza_*` tools | MCP did not load | Check the config JSON + env vars, then restart the tool |
| `401 / Unauthorized` | Wrong key/secret, or a revoked OAuth token | The secret shows once - delete the key and generate a new one; for OAuth, re-authorize the connector |
| `400 "already in use"` (domain) | `*.imprezaapps.com` name is taken (shared namespace) | Pick another name or leave it empty to auto-allocate |

## Under the hood

*   **Remote connector (OAuth 2.1):** the AI client talks to `https://mcp.imprezahost.com/mcp` and authorizes via standard OAuth - you consent in your clientarea, the client gets a scoped, **revocable** access token (no password or API secret ever leaves Impreza). Tokens are short-lived and refreshed automatically; revoke instantly under **Connected Apps**.
*   **Customer ↔ API (local MCP):** headers `X-API-Key: imp_…` + `X-API-Secret: …`. The second factor (IP) is per-key: _whitelist_ (default), _trust-on-first-use_, or _key-only_. The MCP reads the key from `IMPREZA_API_KEY` / `IMPREZA_API_SECRET` or from `~/.impreza/credentials.json` (after pairing).
*   **Agent ↔ API:** headers `X-Agent-Id: agt_…` + `X-Agent-Secret: …`, issued at bootstrap and stored in `/etc/impreza-agent/credentials.toml`. You never touch this.
*   **Domains:** empty `domain` auto-allocates `<app>-<6hex>.imprezaapps.com`. Own domain? Point its A record at the agent IP _before_ calling so Let's Encrypt can issue.
*   **Other paths (no AI):** the `impreza` CLI ([Tutorial 4](/tutorials/devkit-cli.html)) and the REST API ([Tutorial 3](/tutorials/rest-api.html)).

## Keep secrets out of conversations

When your connector lists the secret-entry tools, prepare an owner-authenticated
portal link and enter the value yourself. The AI sees only the link and status.
Follow the [secret entry workflow](/customer-workflows.html#secret-entry), including
its rollout requirements and the [scope of secret protection](/customer-workflows.html#secret-entry-boundary). Never paste
a password, application token or private key into chat.

USDT and TRX payments through TronPay are available only for USD invoices. A non-USD request to `impreza_topup_payment` returns an error before any payment is created. Choose another payment method. Existing non-USD TronPay payments require support reconciliation.
