Claude Skill

agami-deploy

EARLY ACCESS (in testing) — usable today, but newer than the local single-player path; feedback welcome via a GitHub issue. Prepares a ready-to-run, self-hosted agami deploy bundle ON THE USER'S MACHINE so a team can stand up a shareable MCP server their Claude connects to. Conve

LLM Mart · 0 points · 14 views 35 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download agamiai-agami-core-plugins_agami_skills_agami-deploy-471c46c.zip · 10 KB
Part of agamiai/agami-core — 6 skills

Install

skills CLI npx skills add https://github.com/AgamiAI/agami-core/tree/main/plugins/agami/skills/agami-deploy
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install agamiai-agami-core@llmmart
Git git clone https://github.com/AgamiAI/agami-core.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole agamiai/agami-core collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

agami deploy — prepare a self-host bundle the user ships to their own host

You are preparing a deploy bundle on the user's machine so they can stand up the multi-user agami server (the HTTP MCP server with OAuth + admin) that their team's Claude connects to. The bundle pulls the published image (ghcr.io/agamiai/agami-core) — there is no repo to clone and nothing to build. You gather a few inputs, write the bundle locally, and hand off the cloud steps you can't do.

The local mirror of this (single-player, no network, no auth) is agami-serve — if the user only wants agami in their own Claude Desktop, point them there instead.

HARD RULES (load-bearing — a deploy handles secrets)

  1. Never ask for the admin password (or any secret) in chat — not even temporarily. The password is typed by the user directly into the agami.env file (Phase 2 hand-off), exactly like agami-connect does for DB credentials. You never see it.
  2. Never put a secret on a Bash command line. prepare_deploy.py takes only non-secret values; deploy_preflight generates the signing secret into the file. Hosts render Bash calls in chat.
  3. Username/password is the only auth this skill sets up. Do not collect Google/Microsoft client id/secret. Social login ships free but is a manual agami.env step — point the user at the in-repo deploy README if they ask, and move on.
  4. No signup, no license key, no LLM/embedding key. None are required; don't ask for any.

Conversation style

Tight and oriented. Print one-line progress markers (✓ Bundle written to …, ✓ agami.env validated). Be honest about what's the user's clicks (provision the VM, point DNS) vs what you automate.

Phase −1: Plan-mode preflight

Run the detection logic from shared/plan-mode-check.md. This skill writes files and may run Docker. If plan mode is active, refuse with: "I can't prepare a deploy bundle in plan mode — it writes the bundle + your agami.env and may run Docker. Switch to Auto or Edit Automatically mode (Shift+Tab) and re-invoke me." DO NOT write a plan file or call ExitPlanMode.

Phase 0: Preflight

  1. Resolve the environment — python3 "$AGAMI_PLUGIN_ROOT/scripts/connect_resolve.py" prints JSON; read data.artifacts_dir (the local model dir) and data.interpreter.python3 (call it $PY — the interpreter that has the agami-core package; use it for deploy_preflight).
  2. Model present — <artifacts_dir>/<active_profile>/datasource.yaml must exist. If there's no model yet, stop and invoke /agami-connect first — the deployed server has nothing to serve without one.

Phase 1: Gather the hard floor, then write the bundle

Ask only these (everything else is defaulted or generated). Prefer one compact exchange:

  1. Hostname — "What address will your team connect to?" It must be a hostname, not a bare IP (TLS + OAuth need a DNS name). → PUBLIC_BASE_URL=https://<host>.
    • If they have no domain / can't open ports, offer the Cloudflare tunnel path (profiles bundled-db,tunnel; they'll add CLOUDFLARE_TUNNEL_TOKEN to agami.env). The tunnel still needs a domain on Cloudflare — it removes the public IP, not the name.
  2. Admin — first name, last name, work email (the email is the admin identity).
  3. (only if they bring their own Postgres) note it → use profiles edge (drops the bundled DB). The managed postgresql://… URL is a credential, so do not collect it in chat — after the bundle is written, the user sets APP_DATABASE_URL in agami.env themselves (the same hand-off as the password).
  4. Which datasource(s)? — list the models in the artifacts dir (one per profile: <artifacts_dir>/<profile>/datasource.yaml). If there's exactly one, use it silently. If there's more than one, ask: "You have N datasources — <names>. Deploy all, or pick?" Pass the chosen set as --datasources a,b (omit to deploy all). The server serves every datasource you stage, and each needs its own DSN (Phase 2).

Confirm where to write the bundle. Ask: "Where should I put the deploy bundle? (default ~/agami-deploy)" and use their answer as --target. It must not be inside the artifacts dir (prepare_deploy rejects that — it copies the model out of artifacts into the bundle). Then write it:

python3 "$AGAMI_PLUGIN_ROOT/scripts/prepare_deploy.py" \
  --target <chosen-dir, default ~/agami-deploy> \
  --artifacts-dir "<data.artifacts_dir>" \
  --public-base-url "https://<host>" \
  --admin-email "<email>" --admin-first "<first>" --admin-last "<last>" \
  --profiles "bundled-db,edge"

Append these flags to the command when they apply (add each as another \-continued line): --datasources "a,b" to stage a subset of models; on a version upgrade --image-tag "<version>" to bump it (omit it on a model-only re-stage so an existing pin isn't changed).

(Use --profiles "bundled-db,tunnel" for the tunnel, or --profiles "edge" for managed Postgres — then have the user set APP_DATABASE_URL in agami.env by hand, never on the command line.)

Read the status line and branch on the first token:

  • PREPARED <dir> — a fresh bundle. Go to Phase 2 (fill the secrets).
  • UPGRADED <dir> new_keys=<a,b,…> — an existing bundle upgraded in place: every value the user typed (password, secret, DSN) is kept. If new_keys is non-empty, this version added settings — tell the user exactly which to set (e.g. "this version added DATASOURCE_URL — set it in agami.env before we restart"). If it's empty, nothing new is needed. Existing secrets are already there — don't re-ask; continue to Phase 3 (deploy).

Phase 2: Hand off the secrets (then end the turn)

Open the file for them so they don't have to hunt for it (it's a plain visible file, agami.env, in the bundle dir): open -t -- "<target>/agami.env" on macOS (opens it in the default text editor; the -- stops a path that starts with - being read as a flag); on other platforms just print the absolute path. Then tell the user (do not proceed past this in the same turn). These are credentials — the user types them by hand; you never see them, they stay in the file on their machine:

Open <target>/agami.env (I just opened it for you) and set, then save:

  • AGAMI_ADMIN_PASSWORD= — a strong admin password.
  • the warehouse DSN(s) — the connection string(s) the model queries (the scheme picks the type: postgresql:// mysql:// redshift:// snowflake://…). (These live here now — not shipped in the bundle.) Name them per the datasource(s) you deployed:
    • one datasource → DATASOURCE_URL= (e.g. postgresql://<user>:<password>@host:5432/db).
    • several → one per datasource: DATASOURCE_URL__<TOKEN>=, where <TOKEN> is the datasource id upper-cased with every non-alphanumeric char turned to _ (so sales-pg → DATASOURCE_URL__SALES_PG). (List the exact var names for the datasources they chose in Phase 1.4.) agami only runs read-only SELECTs, so the warehouse user only needs read access — a read-only user is safest. Ask for "the read-only grant" and I'll hand you the SQL (shared/readonly-grants.md).
  • (only if you chose managed Postgres) APP_DATABASE_URL= — your Postgres URL.

Then tell me to continue.

End the turn here. The user fills the secrets and re-invokes (or says "continue").

Phase 3: Finalize + deploy

  1. Validate + generate the signing secret: $PY -m deploy_preflight ~/agami-deploy/agami.env. If it reports missing inputs (e.g. the password still blank, or a non-https URL), relay them and stop. On success it has written AGAMI_SIGNING_SECRET + derived AGAMI_PUBLIC_HOST into the file.
  2. Bring it up:
    • Docker present here (the user is on the target host, or testing locally) — run cd ~/agami-deploy && ./deploy.sh (pulls the image + docker compose up -d).
    • No Docker / deploying to a remote VM — hand off: have them copy ~/agami-deploy to the host (scp -r or a synced folder), then run ./deploy.sh there. Give them the cloud checklist below.
  3. Print the share lines: the connector URL <PUBLIC_BASE_URL>/mcp (what teammates add in claude.ai → Connectors), and the admin console <PUBLIC_BASE_URL>/admin.

The cloud steps you can't do (👤 — walk them through it)

  • A VM (~2 vCPU / 4 GB RAM / 20 GB disk), Ubuntu LTS, only ports 80 + 443 open (or the tunnel).
  • DNS: an A-record for their hostname → the VM's public IP. (Skip for the tunnel.)
  • Docker on the host: curl -fsSL https://get.docker.com | sudo sh.
  • Then ./deploy.sh on the host → wait ~30s for Caddy to issue the cert → open <PUBLIC_BASE_URL>/admin.

Re-running later (model update vs version upgrade)

A re-run of /agami-deploy over an existing bundle is non-destructive — it never touches the secrets the user typed (UPGRADED status); it re-stages the model, appends any settings new in this version, and reports them as new_keys. Two cases:

  • Model update (they changed the semantic model): re-run without --image-tag (keeps the pinned version), then on the host docker compose restart agami — the server re-ingests the model on boot. No rebuild, no DB access.
  • Version upgrade (a newer agami release): re-run with --image-tag "<version>" (bumps it), set any new_keys the run reports, then cd <target> && ./deploy.sh (pulls the new image + recreates).

Notes

  • This is the team path. For a quick local feel of the same tools, that's agami-serve (stdio, no network). For a fully managed, governed, always-on server, that's the hosted product — see docs/open-vs-hosted.md.
  • The bundle is self-contained and re-shippable: the generated signing secret lives in its agami.env, so a VM rebuild that re-uses the same bundle keeps every connected Claude working (no reconnect).
Files (agami-core)
  • bundle
    • agami.env.example 3.8 KB · in bundle
    • Caddyfile 363 B · in bundle
    • deploy.sh 653 B
      #!/bin/sh
      # Bring up the agami stack from this prepared bundle. `/agami-deploy` already validated + filled your
      # agami.env locally (signing secret generated, host derived), so this just pulls the published image and runs.
      # `--env-file agami.env` on every call: compose doesn't auto-load it (visible name, not the hidden `.env`).
      set -e
      cd "$(dirname "$0")"
      
      docker compose --env-file agami.env pull
      docker compose --env-file agami.env up -d
      
      echo "agami is starting. It's live at your PUBLIC_BASE_URL once Caddy issues the certificate (a few seconds)."
      echo "Share  \${PUBLIC_BASE_URL}/mcp  with your team; manage users at  \${PUBLIC_BASE_URL}/admin"
      
    • docker-compose.yml 3.2 KB
      # agami self-host stack. `./deploy.sh` (compose with `--env-file agami.env`, COMPOSE_PROFILES=bundled-db,edge)
      # brings up the secure VM deployment: Caddy terminates TLS and is the ONLY public service; agami and
      # Postgres live on the internal network with no published ports. Toggle the profiles for the variants:
      #   bundled-db,edge   (default)  — Caddy TLS + agami + bundled Postgres on a VM
      #   edge              + APP_DATABASE_URL — external/managed Postgres (e.g. Cloud SQL via a plain URL)
      #   tunnel            — Cloudflare Tunnel instead of a public IP (no inbound ports)
      #   (none)            — agami only, behind the platform's own TLS (e.g. Cloud Run); set APP_DATABASE_URL
      #
      # Unlike the in-repo deploy/ stack, this bundle PULLS a pre-built image (no build context, no clone).
      name: agami
      
      # Cap per-container log growth (default json-file is unbounded) so a long-running deploy can't fill the
      # disk — 3 rotated files × 10 MB per service. Applied to every service via the `*default-logging` anchor.
      x-logging: &default-logging
        driver: json-file
        options:
          max-size: "10m"
          max-file: "3"
      
      services:
        caddy:
          image: caddy:2
          profiles: ["edge"]
          restart: unless-stopped
          logging: *default-logging
          ports:
            - "80:80"
            - "443:443"
          environment:
            AGAMI_PUBLIC_HOST: ${AGAMI_PUBLIC_HOST}  # the bare hostname; deploy_preflight derives it from PUBLIC_BASE_URL
          volumes:
            - ./Caddyfile:/etc/caddy/Caddyfile:ro
            - caddy_data:/data
            - caddy_config:/config
      
        agami:
          image: ghcr.io/agamiai/agami-core:${AGAMI_IMAGE_TAG:-latest}
          restart: unless-stopped
          logging: *default-logging
          env_file: agami.env
          environment:
            # Bundled Postgres by default; set APP_DATABASE_URL in agami.env to point at managed Postgres instead.
            AGAMI_DB_URL: ${APP_DATABASE_URL:-postgresql://agami:${POSTGRES_PASSWORD:-agami-bundled-local}@postgres:5432/agami}
            AGAMI_ARTIFACTS_DIR: /artifacts
            HOST: 0.0.0.0
            PORT: "8000"
          volumes:
            - ${AGAMI_ARTIFACTS_DIR:-./artifacts}:/artifacts:ro  # your local agami-artifacts (the model), read-only
          # No `ports:` and no `depends_on:` — agami is reached only via Caddy/the tunnel on the internal
          # network, and the entrypoint waits for the DB itself (so the external-DB/cloud-run profiles work).
      
        postgres:
          image: postgres:16
          profiles: ["bundled-db"]
          restart: unless-stopped
          logging: *default-logging
          environment:
            POSTGRES_DB: agami
            POSTGRES_USER: agami
            # A bundled-local default — fine because the DB is never exposed; override it in agami.env if you like.
            POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-agami-bundled-local}
          volumes:
            - pgdata:/var/lib/postgresql/data
          healthcheck:
            test: ["CMD-SHELL", "pg_isready -U agami -d agami"]
            interval: 2s
            timeout: 3s
            retries: 30
          # No `ports:` — the database is never published to the host or the internet.
      
        cloudflared:
          image: cloudflare/cloudflared:latest
          profiles: ["tunnel"]
          restart: unless-stopped
          logging: *default-logging
          command: tunnel --no-autoupdate run
          environment:
            TUNNEL_TOKEN: ${CLOUDFLARE_TUNNEL_TOKEN:-}  # from your Cloudflare Zero Trust tunnel
      
      volumes:
        pgdata:
        caddy_data:
        caddy_config:
      
    • README.md 1.2 KB
      # Your agami deploy bundle
      
      `/agami-deploy` prepared this folder. It's self-contained — it **pulls** the published image
      (`ghcr.io/agamiai/agami-core`), so there's nothing to build and no repo to clone.
      
      ## What's here
      - `docker-compose.yml` — Caddy (auto-TLS, the only public service) + agami + bundled Postgres.
      - `Caddyfile` — TLS for your hostname.
      - `agami.env` — your config (filled by `/agami-deploy`; `deploy_preflight` generated the signing secret).
      - `artifacts/` — your semantic model + warehouse credentials (mounted read-only).
      - `deploy.sh` — pulls the image and brings the stack up.
      
      ## Run it
      On a host with Docker + your hostname's DNS A-record pointed at it (or a Cloudflare tunnel):
      
      ```sh
      ./deploy.sh
      ```
      
      Then open `<PUBLIC_BASE_URL>/admin` to sign in, and share `<PUBLIC_BASE_URL>/mcp` with your team.
      
      ## Recommended VM size
      2 vCPU / 4 GB RAM / 20 GB disk runs the server + bundled Postgres comfortably for a small team. Open
      only ports 80 and 443 (or use the `tunnel` profile to expose nothing inbound).
      
      ## Updating the model later
      Refresh your model locally, re-run `/agami-deploy` (or re-copy `artifacts/`), then on the host:
      `docker compose restart agami` — the server re-ingests the model on boot. No rebuild, no DB access.
      
  • SKILL.md 11.4 KB
    ---
    name: agami-deploy
    description: "EARLY ACCESS (in testing) — usable today, but newer than the local single-player path; feedback welcome via a GitHub issue. Prepares a ready-to-run, self-hosted agami deploy bundle ON THE USER'S MACHINE so a team can stand up a shareable MCP server their Claude connects to. Conversationally gathers the hard-floor inputs (hostname, admin identity), auto-detects the local model, writes docker-compose.yml + Caddyfile + a filled agami.env (referencing the PUBLISHED image ghcr.io/agamiai/agami-core — no clone, no build), and stages the model artifacts. Generates the signing secret via deploy_preflight; the admin password is typed by the user into the file (never in chat). Then runs `docker compose up` if Docker is local, otherwise prints the exact VM steps + the shareable MCP URL. Username/password auth only on this paved path."
    when_to_use: "Use when the user says 'deploy agami', 'self-host agami', 'set up the agami server for my team', 'stand up a shared agami', 'host agami on a VM / in the cloud', '/agami-deploy', or otherwise wants the multi-user HTTP server (not the local single-player setup — that's agami-serve). Requires agami-connect to have run first (needs a semantic model + credentials). This is the TEAM path: it produces an internet-reachable server with OAuth + admin that claude.ai connects to."
    ---
    
    # agami deploy — prepare a self-host bundle the user ships to their own host
    
    You are preparing a **deploy bundle** on the user's machine so they can stand up the multi-user agami
    server (the HTTP MCP server with OAuth + admin) that their team's Claude connects to. The bundle pulls
    the **published image** (`ghcr.io/agamiai/agami-core`) — there is **no repo to clone and nothing to
    build**. You gather a few inputs, write the bundle locally, and hand off the cloud steps you can't do.
    
    The local mirror of this (single-player, no network, no auth) is `agami-serve` — if the user only wants
    agami in their own Claude Desktop, point them there instead.
    
    ## HARD RULES (load-bearing — a deploy handles secrets)
    
    1. **Never ask for the admin password (or any secret) in chat — not even temporarily.** The password is
       typed by the **user** directly into the `agami.env` file (Phase 2 hand-off), exactly like `agami-connect`
       does for DB credentials. You never see it.
    2. **Never put a secret on a Bash command line.** `prepare_deploy.py` takes only non-secret values;
       `deploy_preflight` generates the signing secret *into the file*. Hosts render Bash calls in chat.
    3. **Username/password is the only auth this skill sets up.** Do **not** collect Google/Microsoft client
       id/secret. Social login ships free but is a manual `agami.env` step — point the user at the in-repo deploy
       README if they ask, and move on.
    4. **No signup, no license key, no LLM/embedding key.** None are required; don't ask for any.
    
    ## Conversation style
    Tight and oriented. Print one-line progress markers (`✓ Bundle written to …`, `✓ agami.env validated`).
    Be honest about what's the user's clicks (provision the VM, point DNS) vs what you automate.
    
    ## Phase −1: Plan-mode preflight
    Run the detection logic from [`shared/plan-mode-check.md`](../../shared/plan-mode-check.md). This skill
    writes files and may run Docker. If plan mode is active, refuse with: *"I can't prepare a deploy bundle
    in plan mode — it writes the bundle + your agami.env and may run Docker. Switch to **Auto** or **Edit
    Automatically** mode (Shift+Tab) and re-invoke me."* **DO NOT** write a plan file or call `ExitPlanMode`.
    
    ## Phase 0: Preflight
    1. **Resolve the environment** — `python3 "$AGAMI_PLUGIN_ROOT/scripts/connect_resolve.py"` prints JSON;
       read `data.artifacts_dir` (the local model dir) and `data.interpreter.python3` (call it `$PY` — the
       interpreter that has the agami-core package; use it for `deploy_preflight`).
    2. **Model present** — `<artifacts_dir>/<active_profile>/datasource.yaml` must exist. If there's no model yet,
       stop and invoke `/agami-connect` first — the deployed server has nothing to serve without one.
    
    ## Phase 1: Gather the hard floor, then write the bundle
    Ask only these (everything else is defaulted or generated). Prefer one compact exchange:
    
    1. **Hostname** — "What address will your team connect to?" It must be a **hostname, not a bare IP**
       (TLS + OAuth need a DNS name). → `PUBLIC_BASE_URL=https://<host>`.
       - If they have **no domain / can't open ports**, offer the **Cloudflare tunnel** path (profiles
         `bundled-db,tunnel`; they'll add `CLOUDFLARE_TUNNEL_TOKEN` to `agami.env`). The tunnel still needs a
         domain on Cloudflare — it removes the public IP, not the name.
    2. **Admin** — first name, last name, work **email** (the email is the admin identity).
    3. *(only if they bring their own Postgres)* note it → use profiles `edge` (drops the bundled DB). The
       managed `postgresql://…` URL is a **credential**, so do **not** collect it in chat — after the bundle
       is written, the user sets `APP_DATABASE_URL` in `agami.env` themselves (the same hand-off as the password).
    4. **Which datasource(s)?** — list the models in the artifacts dir (one per profile:
       `<artifacts_dir>/<profile>/datasource.yaml`). If there's exactly one, use it silently. If there's **more than
       one**, ask: *"You have N datasources — `<names>`. Deploy all, or pick?"* Pass the chosen set as
       `--datasources a,b` (omit to deploy all). The server serves **every** datasource you stage, and each needs
       its own DSN (Phase 2).
    
    **Confirm where to write the bundle.** Ask: *"Where should I put the deploy bundle? (default `~/agami-deploy`)"*
    and use their answer as `--target`. It must **not** be inside the artifacts dir (prepare_deploy rejects that —
    it copies the model *out of* artifacts *into* the bundle). Then write it:
    
    ```bash
    python3 "$AGAMI_PLUGIN_ROOT/scripts/prepare_deploy.py" \
      --target <chosen-dir, default ~/agami-deploy> \
      --artifacts-dir "<data.artifacts_dir>" \
      --public-base-url "https://<host>" \
      --admin-email "<email>" --admin-first "<first>" --admin-last "<last>" \
      --profiles "bundled-db,edge"
    ```
    
    **Append these flags to the command when they apply** (add each as another `\`-continued line): `--datasources
    "a,b"` to stage a subset of models; on a **version upgrade** `--image-tag "<version>"` to bump it (omit it on a
    model-only re-stage so an existing pin isn't changed).
    
    (Use `--profiles "bundled-db,tunnel"` for the tunnel, or `--profiles "edge"` for managed Postgres — then
    have the user set `APP_DATABASE_URL` in `agami.env` by hand, never on the command line.)
    
    **Read the status line** and branch on the first token:
    - `PREPARED <dir>` — a **fresh** bundle. Go to Phase 2 (fill the secrets).
    - `UPGRADED <dir> new_keys=<a,b,…>` — an **existing** bundle upgraded **in place**: every value the user
      typed (password, secret, DSN) is kept. If `new_keys` is **non-empty**, this version added settings — tell
      the user exactly which to set (e.g. *"this version added `DATASOURCE_URL` — set it in `agami.env` before we
      restart"*). If it's **empty**, nothing new is needed. Existing secrets are already there — don't re-ask;
      continue to Phase 3 (deploy).
    
    ## Phase 2: Hand off the secrets (then end the turn)
    **Open the file for them** so they don't have to hunt for it (it's a plain visible file, `agami.env`, in the
    bundle dir): `open -t -- "<target>/agami.env"` on macOS (opens it in the default text editor; the `--` stops a
    path that starts with `-` being read as a flag); on other platforms
    just print the **absolute path**. Then tell the user (do **not** proceed past this in the same turn). These are
    credentials — the user types them by hand; you never see them, they stay in the file on their machine:
    
    > Open `<target>/agami.env` (I just opened it for you) and set, then save:
    > - **`AGAMI_ADMIN_PASSWORD=`** — a strong admin password.
    > - the **warehouse DSN(s)** — the connection string(s) the model queries (the scheme picks the type:
    >   `postgresql://` `mysql://` `redshift://` `snowflake://…`). *(These live here now — **not** shipped in
    >   the bundle.)* Name them per the datasource(s) you deployed:
    >   - **one datasource** → **`DATASOURCE_URL=`** (e.g. `postgresql://<user>:<password>@host:5432/db`).
    >   - **several** → one per datasource: **`DATASOURCE_URL__<TOKEN>=`**, where `<TOKEN>` is the datasource id
    >     upper-cased with every non-alphanumeric char turned to `_` (so `sales-pg` → `DATASOURCE_URL__SALES_PG`).
    >     *(List the exact var names for the datasources they chose in Phase 1.4.)*
    >     agami only runs read-only SELECTs, so the warehouse user only needs read access — a read-only user is
    >     safest. Ask for "the read-only grant" and I'll hand you the SQL ([`shared/readonly-grants.md`](../../shared/readonly-grants.md)).
    > - *(only if you chose managed Postgres)* **`APP_DATABASE_URL=`** — your Postgres URL.
    >
    > Then tell me to continue.
    
    End the turn here. The user fills the secrets and re-invokes (or says "continue").
    
    ## Phase 3: Finalize + deploy
    1. **Validate + generate the signing secret:** `$PY -m deploy_preflight ~/agami-deploy/agami.env`. If it
       reports missing inputs (e.g. the password still blank, or a non-https URL), relay them and stop. On
       success it has written `AGAMI_SIGNING_SECRET` + derived `AGAMI_PUBLIC_HOST` into the file.
    2. **Bring it up:**
       - **Docker present here** (the user is on the target host, or testing locally) — run
         `cd ~/agami-deploy && ./deploy.sh` (pulls the image + `docker compose up -d`).
       - **No Docker / deploying to a remote VM** — hand off: have them copy `~/agami-deploy` to the host
         (`scp -r` or a synced folder), then run `./deploy.sh` there. Give them the **cloud checklist** below.
    3. **Print the share lines:** the connector URL **`<PUBLIC_BASE_URL>/mcp`** (what teammates add in
       claude.ai → Connectors), and the admin console **`<PUBLIC_BASE_URL>/admin`**.
    
    ## The cloud steps you can't do (👤 — walk them through it)
    - **A VM** (~2 vCPU / 4 GB RAM / 20 GB disk), Ubuntu LTS, **only ports 80 + 443 open** (or the tunnel).
    - **DNS:** an **A-record** for their hostname → the VM's public IP. (Skip for the tunnel.)
    - **Docker** on the host: `curl -fsSL https://get.docker.com | sudo sh`.
    - Then `./deploy.sh` on the host → wait ~30s for Caddy to issue the cert → open `<PUBLIC_BASE_URL>/admin`.
    
    ## Re-running later (model update vs version upgrade)
    A re-run of `/agami-deploy` over an existing bundle is **non-destructive** — it never touches the secrets the
    user typed (`UPGRADED` status); it re-stages the model, appends any settings new in this version, and reports
    them as `new_keys`. Two cases:
    
    - **Model update** (they changed the semantic model): re-run **without** `--image-tag` (keeps the pinned
      version), then on the host `docker compose restart agami` — the server re-ingests the model on boot. No
      rebuild, no DB access.
    - **Version upgrade** (a newer agami release): re-run **with** `--image-tag "<version>"` (bumps it), set any
      `new_keys` the run reports, then `cd <target> && ./deploy.sh` (pulls the new image + recreates).
    
    ## Notes
    - This is the **team** path. For a quick local feel of the same tools, that's `agami-serve` (stdio, no
      network). For a fully managed, governed, always-on server, that's the hosted product — see
      `docs/open-vs-hosted.md`.
    - The bundle is self-contained and re-shippable: the generated signing secret lives in its `agami.env`, so a
      VM rebuild that re-uses the same bundle keeps every connected Claude working (no reconnect).
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related