papercliped 2.2.1 → 2.4.0

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.
Files changed (41) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/CHANGELOG.md +20 -0
  3. package/README.md +9 -5
  4. package/dist/access/guard.js +17 -0
  5. package/dist/access/policy.js +203 -0
  6. package/dist/execute.js +25 -1
  7. package/dist/manage/routes.js +46 -2
  8. package/dist/mcp.js +6 -5
  9. package/dist/oauth/pg-store.js +13 -1
  10. package/dist/oauth/provider.js +50 -1
  11. package/dist/oauth/store.js +20 -0
  12. package/dist/public-api/types.js +1 -1
  13. package/dist/server.js +2 -2
  14. package/dist/site/markdown.js +26 -5
  15. package/dist/site/site.js +10 -1
  16. package/docs/CONTROL-ROOM.md +79 -0
  17. package/docs/SECURITY.md +1 -1
  18. package/docs/SITEMAP.md +3 -1
  19. package/docs/supabase-schema.sql +12 -1
  20. package/migrations/007_control_room.sql +9 -0
  21. package/package.json +1 -1
  22. package/site/docs/access-modes.md +72 -0
  23. package/site/docs/connect-your-paperclip.md +139 -93
  24. package/site/docs/control-room.md +61 -0
  25. package/site/docs/faq.md +16 -1
  26. package/site/docs/getting-started.md +2 -2
  27. package/site/docs/host-coolify.md +78 -0
  28. package/site/docs/host-fly.md +129 -0
  29. package/site/docs/host-railway.md +105 -0
  30. package/site/docs/host-render.md +79 -0
  31. package/site/docs/host-vps.md +202 -0
  32. package/site/docs/hosting.md +105 -0
  33. package/site/docs/limits-and-errors.md +1 -0
  34. package/site/docs/manage-api.md +12 -1
  35. package/site/docs/paperclip-plugin.md +21 -10
  36. package/site/docs/permissions.md +8 -0
  37. package/site/docs/prompts.md +349 -0
  38. package/site/docs/public-api.md +1 -1
  39. package/site/docs/signup.md +1 -1
  40. package/site/docs/tools.md +35 -35
  41. package/site/docs/troubleshooting.md +11 -1
package/site/docs/faq.md CHANGED
@@ -12,12 +12,27 @@ Only what it asks for through the tools, within your level. Issue and comment te
12
12
  ## What do you store?
13
13
  Your username, a hash of your secret key, your Paperclip's address, an encrypted Paperclip key, connection records and a 30-day activity log. Details in [Privacy](/privacy).
14
14
 
15
+ ## What can I ask it?
16
+ Anything you'd otherwise click through Paperclip for: "Catch me up", "Give the Web Engineer this task", "Approve the hire", "Weekly cost report". Browse ready-to-copy prompts in the [prompt gallery](/docs/prompts).
17
+
18
+ ## Where should I host Paperclip?
19
+ At home with a free tunnel to try it; a small VPS (best value) or Railway (easiest) to keep it on all the time. Compare every option in [Host your Paperclip](/docs/hosting).
20
+
21
+ ## Paperclip has its own MCP server now. Do I still need Papercliped?
22
+ Newer Paperclip versions include an experimental, off-by-default MCP endpoint for connecting assistants straight to your instance. Use whichever suits you. Papercliped adds a hosted connector that works with older Paperclips too, ChatGPT GPT Actions, the two access levels enforced on every call, an audit log, ready-made status, cost and performance reports, and connection management in the Paperclip plugin.
23
+
15
24
  ## Can I use it without a public Paperclip?
16
- Yes: run it locally with `npx papercliped@latest`. The hosted bridge needs a public https address; see [Set up your Paperclip](/docs/connect-your-paperclip).
25
+ Yes: run it locally with `npx papercliped@latest`. The hosted bridge needs a public https address; see [Host your Paperclip](/docs/hosting).
17
26
 
18
27
  ## Why does pausing an agent fail with 403?
19
28
  Pause, resume, wake and approve need a Paperclip **board** token, and a connection at **Full control**. Check your level in the [Paperclip plugin](/docs/paperclip-plugin).
20
29
 
30
+ ## Why was a call blocked, or a tool missing?
31
+ Your own settings. Open **Papercliped** in Paperclip: the switch (API only, Full, Agent only), an agent's setting, or the session's tool and agent lists decide what an AI app may do, and **Activity** shows each blocked call and the reason. See [API only, Full or Agent only](/docs/access-modes).
32
+
33
+ ## Can I keep an agent away from AI apps?
34
+ Yes. In the [control room](/docs/control-room), open **Agents** and set it to **Off**: AI apps can't see it, touch it, or see what's assigned to it.
35
+
21
36
  ## How do I stop it?
22
37
  Disconnect the app on the manage page, revoke the key in your Paperclip, or delete your account. It stops at once.
23
38
 
@@ -3,7 +3,7 @@
3
3
  Papercliped connects Claude (and ChatGPT) to **your** Paperclip. You keep control: you choose how much the AI may do, and you can cut access at any time.
4
4
 
5
5
  ## What you need
6
- - A Paperclip that is reachable over the internet at an `https://` address (for example `https://workforce.example.com`). Private, local and `http://` addresses are refused on purpose. No public address yet? See [Set up your Paperclip](/docs/connect-your-paperclip).
6
+ - A Paperclip that is reachable over the internet at an `https://` address (for example `https://workforce.example.com`). Private, local and `http://` addresses are refused on purpose. No public address yet? See [Host your Paperclip](/docs/hosting).
7
7
  - A Claude account that can add connectors, or Claude Code.
8
8
 
9
9
  ## Connect from Claude
@@ -30,7 +30,7 @@ This starts a local server for one Paperclip, using `PAPERCLIP_API_URL` and `PAP
30
30
  Any app that supports MCP can use Papercliped. See [Any AI app (MCP)](/docs/other-ai-apps).
31
31
 
32
32
  ## Inside your Paperclip
33
- The Papercliped plugin for Paperclip is where you manage everything: connected apps, levels, privacy and your account. See [Paperclip plugin](/docs/paperclip-plugin).
33
+ The Papercliped plugin for Paperclip is where you manage everything: the [control room](/docs/control-room) for connected apps, what each may do and which agents it applies to, plus privacy and your account. See [Paperclip plugin](/docs/paperclip-plugin).
34
34
 
35
35
  ## ChatGPT
36
36
  Papercliped publishes an OpenAPI description at `{{MCP}}/openapi.json` for GPT Actions. See [ChatGPT setup](/docs/chatgpt).
@@ -0,0 +1,78 @@
1
+ # Host Paperclip with Coolify
2
+
3
+ Coolify is a free, open-source control panel you install on your own server. It gives you a Railway-style dashboard (deploys, domains, certificates, logs, a terminal) on a VPS you pay for directly.
4
+
5
+ **You'll end up with:** Coolify on your server, running Paperclip at `https://paperclip.yourdomain.com`, connected to Papercliped.
6
+
7
+ **Time:** about 30 minutes. **Cost:** your server. Coolify itself needs about 2 GB of memory, Paperclip another 2–4 GB, so pick an **8 GB** server (for example Hetzner's 8 GB plans). Self-hosted Coolify is free; Coolify Cloud (they run the panel, you bring the server) is about $5 a month.
8
+
9
+ ## 1. Get a server and install Coolify
10
+
11
+ 1. Rent an Ubuntu 24.04 server with 8 GB of memory (see the provider table in [VPS with Docker](/docs/host-vps#1-rent-the-server)).
12
+ 2. Connect with `ssh root@YOUR_IP` and run Coolify's installer:
13
+ ```
14
+ curl -fsSL https://cdn.coollabs.io/coolify/install.sh | sudo bash
15
+ ```
16
+ 3. Open `http://YOUR_IP:8000` and create your Coolify admin account straight away (the first person to open it becomes the admin).
17
+
18
+ ## 2. Point your domain at it
19
+
20
+ At your DNS provider, add an **A record**: `paperclip` → your server's IP (on Cloudflare: **DNS only**, grey cloud).
21
+
22
+ ## 3. Create Paperclip
23
+
24
+ 1. In Coolify: **Projects → your project → New Resource → Docker Image**.
25
+ 2. Image: `ghcr.io/paperclipai/paperclip:latest`.
26
+ 3. **Ports Exposes:** `3100`.
27
+ 4. **Domains:** `https://paperclip.yourdomain.com`. Coolify gets the certificate for you.
28
+
29
+ ## 4. Add storage, health check and settings
30
+
31
+ - **Persistent Storage → Add → Volume:** destination path **`/paperclip`**.
32
+ - **Health check:** path `/api/health`, port `3100`.
33
+ - **Environment Variables:** add
34
+
35
+ ```
36
+ PAPERCLIP_DEPLOYMENT_MODE=authenticated
37
+ PAPERCLIP_DEPLOYMENT_EXPOSURE=public
38
+ PAPERCLIP_PUBLIC_URL=https://paperclip.yourdomain.com
39
+ BETTER_AUTH_SECRET=YOUR-FIRST-SECRET
40
+ PAPERCLIP_TOOL_ACTION_SIGNING_SECRET=YOUR-SECOND-SECRET
41
+ ANTHROPIC_API_KEY=
42
+ OPENAI_API_KEY=
43
+ ```
44
+
45
+ Make each secret with `openssl rand -hex 32` (run it on the server). Then **Deploy**.
46
+
47
+ Prefer Docker Compose? Choose **Docker Compose** as the resource type and paste the Paperclip service from the [VPS guide](/docs/host-vps#5-create-the-docker-compose-file) **without** the `caddy` service: Coolify's own proxy takes Caddy's place.
48
+
49
+ ## 5. Create your account
50
+
51
+ Open the resource's **Terminal** tab and run:
52
+
53
+ ```
54
+ HOME=/paperclip gosu node npx --yes paperclipai auth bootstrap-ceo --data-dir /paperclip --base-url https://paperclip.yourdomain.com
55
+ ```
56
+
57
+ Open the invite link, create your account and your first company. Optionally add `PAPERCLIP_AUTH_DISABLE_SIGN_UP=true` and redeploy to close public sign-ups. To sign agents in with a subscription, run `HOME=/paperclip gosu node claude` in the same terminal.
58
+
59
+ ## 6. Check and connect
60
+
61
+ ```
62
+ curl https://paperclip.yourdomain.com/api/health
63
+ ```
64
+
65
+ You want `"status":"ok"`, `"deploymentExposure":"public"` and `"bootstrapStatus":"ready"`. Then [connect Papercliped](/docs/hosting#connect-papercliped) and send *"Catch me up on my Paperclip."*
66
+
67
+ ## Updates and backups
68
+
69
+ - **Update:** **Redeploy** pulls the newest image (restarts Paperclip, so do it when agents are idle).
70
+ - **Backups:** Coolify can back up its own databases to S3-compatible storage; for Paperclip's volume, use your provider's server snapshots or the `tar` backup from the [VPS guide](/docs/host-vps#backups).
71
+ - Keep Coolify itself updated from its settings page.
72
+
73
+ ## Troubleshooting
74
+
75
+ - **No certificate:** the A record isn't pointing at the server yet, or Cloudflare's proxy is on.
76
+ - **"This hostname is not allowed":** `PAPERCLIP_PUBLIC_URL` doesn't match the domain.
77
+ - **Data reset after redeploy:** the volume isn't mounted at exactly `/paperclip`.
78
+ - More: [Troubleshooting](/docs/troubleshooting).
@@ -0,0 +1,129 @@
1
+ # Host Paperclip on Fly.io
2
+
3
+ Fly.io runs the official Paperclip image on a small virtual machine in the region you pick, with a volume for its data and a free `https://` address. Everything happens from the `fly` command line.
4
+
5
+ **You'll end up with:** Paperclip at `https://<app>.fly.dev` (or your own domain), always on, connected to Papercliped.
6
+
7
+ **Time:** about 20 minutes. **Cost:** a `shared-cpu-1x` machine with 2 GB is about $11 a month, `shared-cpu-2x` with 4 GB about $22, plus the volume ($0.15 per GB a month). Fly has no free allowance for new accounts and needs a card. Check Fly's pricing page for current numbers.
8
+
9
+ ## Before you start
10
+
11
+ Install `flyctl` (see Fly's install page; on macOS `brew install flyctl`, on Linux `curl -L https://fly.io/install.sh | sh`, on Windows `pwsh -Command "iwr https://fly.io/install.ps1 -useb | iex"`), then:
12
+
13
+ ```
14
+ fly auth login
15
+ mkdir paperclip-fly && cd paperclip-fly
16
+ ```
17
+
18
+ ## 1. Create the app
19
+
20
+ ```
21
+ fly launch --image ghcr.io/paperclipai/paperclip:latest --no-deploy
22
+ ```
23
+
24
+ Pick an app name (this becomes `https://<app>.fly.dev`) and a region near you. Say **no** to any database Fly offers; Paperclip brings its own.
25
+
26
+ ## 2. Create the volume
27
+
28
+ Use the same region you picked (for example `iad`, `lhr`, `fra`, `syd`):
29
+
30
+ ```
31
+ fly volumes create paperclip_data --size 10 --region iad
32
+ ```
33
+
34
+ ## 3. Write `fly.toml`
35
+
36
+ Replace the file `fly launch` made with this, changing `app`, `primary_region` and the URL:
37
+
38
+ ```
39
+ app = "your-app-name"
40
+ primary_region = "iad"
41
+
42
+ [build]
43
+ image = "ghcr.io/paperclipai/paperclip:latest"
44
+
45
+ [env]
46
+ PAPERCLIP_DEPLOYMENT_MODE = "authenticated"
47
+ PAPERCLIP_DEPLOYMENT_EXPOSURE = "public"
48
+ PAPERCLIP_PUBLIC_URL = "https://your-app-name.fly.dev"
49
+ PORT = "3100"
50
+
51
+ [[mounts]]
52
+ source = "paperclip_data"
53
+ destination = "/paperclip"
54
+
55
+ [http_service]
56
+ internal_port = 3100
57
+ force_https = true
58
+ auto_stop_machines = "off"
59
+ auto_start_machines = true
60
+ min_machines_running = 1
61
+
62
+ [[http_service.checks]]
63
+ method = "GET"
64
+ path = "/api/health"
65
+ interval = "30s"
66
+ timeout = "5s"
67
+ grace_period = "60s"
68
+
69
+ [[vm]]
70
+ size = "shared-cpu-2x"
71
+ memory = "4gb"
72
+ ```
73
+
74
+ `auto_stop_machines = "off"` matters: a stopped machine stops your agents mid-task.
75
+
76
+ ## 4. Add the secrets and deploy
77
+
78
+ ```
79
+ fly secrets set BETTER_AUTH_SECRET=$(openssl rand -hex 32) PAPERCLIP_TOOL_ACTION_SIGNING_SECRET=$(openssl rand -hex 32)
80
+ fly deploy --ha=false
81
+ ```
82
+
83
+ Add your agents' keys the same way if you use them: `fly secrets set ANTHROPIC_API_KEY=... OPENAI_API_KEY=...`.
84
+
85
+ `--ha=false` keeps it to **one machine**: a volume belongs to one machine, and two copies of Paperclip must never share data.
86
+
87
+ ## 5. Create your account
88
+
89
+ ```
90
+ fly ssh console
91
+ ```
92
+
93
+ Inside the machine:
94
+
95
+ ```
96
+ HOME=/paperclip gosu node npx --yes paperclipai auth bootstrap-ceo --data-dir /paperclip --base-url https://your-app-name.fly.dev
97
+ ```
98
+
99
+ Open the invite link it prints, create your account and your first company. Optionally close public sign-ups afterwards: `fly secrets set PAPERCLIP_AUTH_DISABLE_SIGN_UP=true`.
100
+
101
+ To sign agents in with a subscription instead of keys, run `HOME=/paperclip gosu node claude` (or `codex`) in the same console. The login is saved on the volume.
102
+
103
+ ## 6. Your own domain (optional)
104
+
105
+ ```
106
+ fly certs add paperclip.yourdomain.com
107
+ ```
108
+
109
+ Create the DNS records it prints, then change `PAPERCLIP_PUBLIC_URL` in `fly.toml` to the new address and `fly deploy` again.
110
+
111
+ ## 7. Check and connect
112
+
113
+ ```
114
+ curl https://your-app-name.fly.dev/api/health
115
+ ```
116
+
117
+ You want `"status":"ok"`, `"deploymentExposure":"public"` and `"bootstrapStatus":"ready"`. Then [connect Papercliped](/docs/hosting#connect-papercliped) and send *"Catch me up on my Paperclip."*
118
+
119
+ ## Updates and backups
120
+
121
+ - **Update:** `fly deploy` pulls the newest `latest` image. It restarts the machine, so runs in progress stop; update when agents are idle.
122
+ - **Backups:** Fly snapshots volumes daily (`fly volumes snapshots list`). Keep your own copy for anything important.
123
+
124
+ ## Troubleshooting
125
+
126
+ - **Health check failing:** `fly logs`. Usually a missing secret or a public URL without `https://`.
127
+ - **"This hostname is not allowed":** `PAPERCLIP_PUBLIC_URL` doesn't match the address you opened.
128
+ - **Two machines running:** `fly scale count 1`. Never run more than one.
129
+ - More: [Troubleshooting](/docs/troubleshooting).
@@ -0,0 +1,105 @@
1
+ # Host Paperclip on Railway
2
+
3
+ Railway runs the official Paperclip image for you: no server to look after, a free `https://` address, and a dashboard for everything. The fewest steps of any always-on option.
4
+
5
+ **You'll end up with:** Paperclip at `https://<name>.up.railway.app` (or your own domain), its data on a Railway volume, connected to Papercliped.
6
+
7
+ **Time:** about 15 minutes. **Cost:** Railway bills by usage. Paperclip with 1–2 GB of memory, always on, is roughly **$10–25 a month** on the Hobby plan ($5 a month including $5 of usage). Railway's free plan is too small for Paperclip (0.5 GB of memory). Check Railway's pricing page for current numbers.
8
+
9
+ ## Before you start
10
+
11
+ - A Railway account on the **Hobby** plan (or the trial, to try it).
12
+ - Two random secrets. Make each with `openssl rand -hex 32`, or have your password manager generate a 64-character password of letters and numbers.
13
+
14
+ > **About community templates:** Railway's template gallery has community-made Paperclip templates. They're not made by Paperclip or by us. They can be quicker, but check that they set `PAPERCLIP_DEPLOYMENT_EXPOSURE=public` and attach a volume at `/paperclip`. The steps below use the official image directly, so you know exactly what's running.
15
+
16
+ ## 1. Create the service
17
+
18
+ 1. In Railway, **New Project → Docker Image** (or **Deploy a Docker Image**).
19
+ 2. Image: `ghcr.io/paperclipai/paperclip:latest`. Railway creates the service and starts a first deploy; it's fine if that one doesn't work yet.
20
+
21
+ ## 2. Add the volume
22
+
23
+ Right-click the service (or use the command palette) → **Attach Volume**. Mount path: **`/paperclip`**. This is where Paperclip keeps its database, secrets key, uploads, workspaces and agent logins. Without it, everything is lost on each deploy.
24
+
25
+ ## 3. Get your address
26
+
27
+ Service → **Settings → Networking → Generate Domain**. If Railway asks for the port, enter **3100**. Note the address, like `https://paperclip-production-1234.up.railway.app`.
28
+
29
+ Want your own domain? Use **Custom Domain** instead, add the CNAME record Railway shows at your DNS provider, and use that address below.
30
+
31
+ ## 4. Add the settings
32
+
33
+ Service → **Variables → Raw Editor**, paste and fill in:
34
+
35
+ ```
36
+ PAPERCLIP_DEPLOYMENT_MODE=authenticated
37
+ PAPERCLIP_DEPLOYMENT_EXPOSURE=public
38
+ PAPERCLIP_PUBLIC_URL=https://YOUR-ADDRESS
39
+ BETTER_AUTH_SECRET=YOUR-FIRST-SECRET
40
+ PAPERCLIP_TOOL_ACTION_SIGNING_SECRET=YOUR-SECOND-SECRET
41
+ PORT=3100
42
+ ANTHROPIC_API_KEY=
43
+ OPENAI_API_KEY=
44
+ ```
45
+
46
+ `PAPERCLIP_PUBLIC_URL` must be exactly your address from step 3, with `https://` and no slash at the end. Leave the API keys empty if you'll sign agents in with a subscription (step 7).
47
+
48
+ **Optional managed database:** add a Postgres from **New → Database → PostgreSQL** and set `DATABASE_URL=${{Postgres.DATABASE_URL}}`. Without it Paperclip uses its built-in Postgres on the volume, which is cheaper and fine for most people.
49
+
50
+ ## 5. Health check and memory
51
+
52
+ - Service → **Settings → Deploy → Healthcheck Path:** `/api/health`.
53
+ - Keep **serverless / app sleeping off**. A sleeping Paperclip stops your agents.
54
+ - Watch memory in the **Metrics** tab for the first days; you pay per GB used.
55
+
56
+ Deploy (Railway usually redeploys after variable changes; otherwise press **Deploy**).
57
+
58
+ ## 6. Create your account
59
+
60
+ Install the Railway CLI (`npm i -g @railway/cli`), then in a terminal:
61
+
62
+ ```
63
+ railway login
64
+ railway link
65
+ railway ssh
66
+ ```
67
+
68
+ Pick your project and service when asked. Inside the container:
69
+
70
+ ```
71
+ HOME=/paperclip gosu node npx --yes paperclipai auth bootstrap-ceo --data-dir /paperclip --base-url https://YOUR-ADDRESS
72
+ ```
73
+
74
+ Open the invite link it prints, create your account and your first company. Then, optionally, add `PAPERCLIP_AUTH_DISABLE_SIGN_UP=true` to the variables to close public sign-ups.
75
+
76
+ ## 7. Sign in your agents
77
+
78
+ Put `ANTHROPIC_API_KEY` / `OPENAI_API_KEY` in the variables, or sign in with a subscription from `railway ssh`:
79
+
80
+ ```
81
+ HOME=/paperclip gosu node claude
82
+ ```
83
+
84
+ The login is saved on the volume.
85
+
86
+ ## 8. Check and connect
87
+
88
+ ```
89
+ curl https://YOUR-ADDRESS/api/health
90
+ ```
91
+
92
+ You want `"status":"ok"`, `"deploymentExposure":"public"` and `"bootstrapStatus":"ready"`. Then [connect Papercliped](/docs/hosting#connect-papercliped) and send *"Catch me up on my Paperclip."*
93
+
94
+ ## Updates and backups
95
+
96
+ - **Update:** service → **Deployments → Redeploy** pulls the latest `latest` image. A service with a volume has a short downtime on each deploy, and runs in progress stop, so do it when agents are idle.
97
+ - **Backups:** Railway volumes have backups in the volume's settings; turn on scheduled backups. If you use Railway Postgres, it has its own backups.
98
+
99
+ ## Troubleshooting
100
+
101
+ - **Deploy fails its health check:** look at the deploy logs. Usually a missing `BETTER_AUTH_SECRET`, or `PAPERCLIP_PUBLIC_URL` not starting with `https://`.
102
+ - **"This hostname is not allowed":** `PAPERCLIP_PUBLIC_URL` doesn't match the address you opened, or exposure isn't `public`.
103
+ - **Everything reset after a deploy:** the volume isn't mounted at exactly `/paperclip`.
104
+ - **Agents are killed or slow:** give the service more memory (2–4 GB).
105
+ - More: [Troubleshooting](/docs/troubleshooting).
@@ -0,0 +1,79 @@
1
+ # Host Paperclip on Render
2
+
3
+ Render runs the official Paperclip image as a web service with a persistent disk and a free `https://` address.
4
+
5
+ **You'll end up with:** Paperclip at `https://<name>.onrender.com` (or your own domain), its data on a Render disk, connected to Papercliped.
6
+
7
+ **Time:** about 15 minutes. **Cost:** Paperclip needs at least 2 GB of memory, which is Render's **Standard** instance (about $25 a month), plus the disk ($0.25 per GB a month; 10 GB is plenty to start). Render's free instances **sleep and can't have a disk**, and the 512 MB Starter instance is too small, so neither works for Paperclip. Check Render's pricing page for current numbers.
8
+
9
+ ## Before you start
10
+
11
+ - A Render account with a payment method.
12
+ - Two random secrets. Make each with `openssl rand -hex 32`, or have your password manager generate a 64-character password of letters and numbers.
13
+
14
+ ## 1. Create the web service
15
+
16
+ 1. **New → Web Service → Existing Image** (deploy an existing image from a registry).
17
+ 2. Image URL: `ghcr.io/paperclipai/paperclip:latest`.
18
+ 3. Pick a region near you and the **Standard** instance type (2 GB) or larger.
19
+
20
+ ## 2. Add the settings
21
+
22
+ Under **Environment Variables**, add:
23
+
24
+ | Key | Value |
25
+ | --- | --- |
26
+ | `PAPERCLIP_DEPLOYMENT_MODE` | `authenticated` |
27
+ | `PAPERCLIP_DEPLOYMENT_EXPOSURE` | `public` |
28
+ | `PAPERCLIP_PUBLIC_URL` | `https://YOUR-SERVICE.onrender.com` (you'll see the exact name after creating it; update this then) |
29
+ | `BETTER_AUTH_SECRET` | your first secret |
30
+ | `PAPERCLIP_TOOL_ACTION_SIGNING_SECRET` | your second secret |
31
+ | `PORT` | `3100` |
32
+ | `ANTHROPIC_API_KEY`, `OPENAI_API_KEY` | optional, for your agents |
33
+
34
+ ## 3. Add the disk and health check
35
+
36
+ Under **Advanced**:
37
+
38
+ - **Add Disk:** mount path **`/paperclip`**, size 10 GB. This is where Paperclip keeps its database, secrets key, uploads, workspaces and agent logins.
39
+ - **Health Check Path:** `/api/health`.
40
+
41
+ Create the service. When it's live, check that `PAPERCLIP_PUBLIC_URL` matches the address Render shows at the top of the page exactly; if not, fix it (Render redeploys).
42
+
43
+ **Your own domain:** **Settings → Custom Domains → Add**, create the DNS record Render shows, and change `PAPERCLIP_PUBLIC_URL` to the new address.
44
+
45
+ **Optional managed database:** create a Render Postgres (a paid one; the free one is deleted after 30 days) and set `DATABASE_URL` to its **Internal** URL. Without it Paperclip uses its built-in Postgres on the disk.
46
+
47
+ ## 4. Create your account
48
+
49
+ Open the service's **Shell** tab and run:
50
+
51
+ ```
52
+ HOME=/paperclip gosu node npx --yes paperclipai auth bootstrap-ceo --data-dir /paperclip --base-url https://YOUR-SERVICE.onrender.com
53
+ ```
54
+
55
+ Open the invite link it prints, create your account and your first company. Optionally, add `PAPERCLIP_AUTH_DISABLE_SIGN_UP=true` afterwards to close public sign-ups.
56
+
57
+ ## 5. Sign in your agents
58
+
59
+ Add `ANTHROPIC_API_KEY` / `OPENAI_API_KEY`, or sign in with a subscription from the Shell tab (`HOME=/paperclip gosu node claude`). The login is saved on the disk.
60
+
61
+ ## 6. Check and connect
62
+
63
+ ```
64
+ curl https://YOUR-SERVICE.onrender.com/api/health
65
+ ```
66
+
67
+ You want `"status":"ok"`, `"deploymentExposure":"public"` and `"bootstrapStatus":"ready"`. Then [connect Papercliped](/docs/hosting#connect-papercliped) and send *"Catch me up on my Paperclip."*
68
+
69
+ ## Updates and backups
70
+
71
+ - **Update:** **Manual Deploy → Deploy latest reference** pulls the newest `latest` image. A service with a disk can't do zero-downtime deploys: the old instance stops first, so runs in progress end. Update when agents are idle.
72
+ - **Backups:** Render takes daily snapshots of disks; you can restore them from the disk's settings. Keep your own copy too for anything important.
73
+
74
+ ## Troubleshooting
75
+
76
+ - **Deploy fails:** read the logs. Usually a missing `BETTER_AUTH_SECRET`, or a public URL without `https://`.
77
+ - **"This hostname is not allowed":** `PAPERCLIP_PUBLIC_URL` doesn't match the address you're opening.
78
+ - **Data gone after a deploy:** the disk isn't mounted at exactly `/paperclip`.
79
+ - More: [Troubleshooting](/docs/troubleshooting).
@@ -0,0 +1,202 @@
1
+ # Host Paperclip on a VPS with Docker
2
+
3
+ A small rented server running the official Paperclip image, with Caddy in front for the `https://` certificate. This is the best value for a Paperclip that's on all the time, and every step is copy and paste.
4
+
5
+ **You'll end up with:** Paperclip at `https://paperclip.yourdomain.com`, restarting by itself, with its data on the server's disk, connected to Papercliped.
6
+
7
+ **Time:** about 30 minutes. **Cost:** the server (about €5–12 a month) and a domain.
8
+
9
+ ## Before you start
10
+
11
+ - **A domain** you can add DNS records to (any registrar works). You'll use a subdomain like `paperclip.yourdomain.com`.
12
+ - **An SSH key.** On macOS, Linux and Windows 10+, run `ssh-keygen` in a terminal and press Enter at each question if you don't have one.
13
+
14
+ ## 1. Rent the server
15
+
16
+ Pick **Ubuntu 24.04**, at least **2 GB of memory (4 GB recommended)**, and add your SSH key when asked.
17
+
18
+ | Provider | A plan that fits (Oct 2026, approx.) | Notes |
19
+ | --- | --- | --- |
20
+ | Hetzner | CX23 (2 vCPU, 4 GB), about €5.50 | Best value; EU and US locations |
21
+ | DigitalOcean | Basic Droplet 2 GB, about $12 | Choose a *Droplet*, not App Platform |
22
+ | Linode (Akamai) | Shared 2 GB, about $12 | |
23
+ | Oracle Cloud Always Free | Ampere A1, $0 | Free but fiddly: see [Oracle notes](#oracle-cloud-free-tier) |
24
+
25
+ Note the server's **public IPv4 address**.
26
+
27
+ ## 2. Point your domain at it
28
+
29
+ At your DNS provider, add an **A record**: name `paperclip`, value the server's IP. (If your DNS is on Cloudflare, set it to **DNS only**, the grey cloud, so Caddy can get its certificate.) It usually works within a few minutes.
30
+
31
+ ## 3. Install Docker and open the firewall
32
+
33
+ Connect to the server (`ssh root@YOUR_IP`), then:
34
+
35
+ ```
36
+ curl -fsSL https://get.docker.com | sh
37
+ ufw allow 22/tcp && ufw allow 80/tcp && ufw allow 443/tcp && ufw allow 443/udp
38
+ ufw --force enable
39
+ ```
40
+
41
+ ## 4. Create the settings
42
+
43
+ Replace `paperclip.yourdomain.com` with your address:
44
+
45
+ ```
46
+ mkdir -p ~/paperclip && cd ~/paperclip
47
+ cat > .env <<EOF
48
+ DOMAIN=paperclip.yourdomain.com
49
+ BETTER_AUTH_SECRET=$(openssl rand -hex 32)
50
+ PAPERCLIP_TOOL_ACTION_SIGNING_SECRET=$(openssl rand -hex 32)
51
+ ANTHROPIC_API_KEY=
52
+ OPENAI_API_KEY=
53
+ EOF
54
+ chmod 600 .env
55
+ ```
56
+
57
+ Leave the two API keys empty if you'll sign your agents in with a subscription instead (step 8).
58
+
59
+ ## 5. Create the Docker Compose file
60
+
61
+ ```
62
+ cat > docker-compose.yml <<'EOF'
63
+ services:
64
+ paperclip:
65
+ image: ghcr.io/paperclipai/paperclip:latest
66
+ container_name: paperclip
67
+ restart: unless-stopped
68
+ pids_limit: 2048
69
+ environment:
70
+ PAPERCLIP_DEPLOYMENT_MODE: authenticated
71
+ PAPERCLIP_DEPLOYMENT_EXPOSURE: public
72
+ PAPERCLIP_PUBLIC_URL: https://${DOMAIN}
73
+ BETTER_AUTH_SECRET: ${BETTER_AUTH_SECRET}
74
+ PAPERCLIP_TOOL_ACTION_SIGNING_SECRET: ${PAPERCLIP_TOOL_ACTION_SIGNING_SECRET}
75
+ TRUST_PROXY: uniquelocal
76
+ ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY}
77
+ OPENAI_API_KEY: ${OPENAI_API_KEY}
78
+ volumes:
79
+ - paperclip-data:/paperclip
80
+ caddy:
81
+ image: caddy:2
82
+ restart: unless-stopped
83
+ ports: ["80:80", "443:443", "443:443/udp"]
84
+ environment:
85
+ DOMAIN: ${DOMAIN}
86
+ volumes:
87
+ - ./Caddyfile:/etc/caddy/Caddyfile:ro
88
+ - caddy-data:/data
89
+ - caddy-config:/config
90
+ depends_on: [paperclip]
91
+ volumes:
92
+ paperclip-data:
93
+ caddy-data:
94
+ caddy-config:
95
+ EOF
96
+ ```
97
+
98
+ What this does: runs the official image (no building), keeps everything Paperclip stores in the `paperclip-data` volume, and only Caddy is reachable from the internet. Paperclip uses its built-in Postgres on that volume.
99
+
100
+ ## 6. Create the Caddy file
101
+
102
+ ```
103
+ cat > Caddyfile <<'EOF'
104
+ {$DOMAIN} {
105
+ reverse_proxy paperclip:3100
106
+ }
107
+ EOF
108
+ ```
109
+
110
+ Caddy gets and renews the certificate by itself and passes Paperclip's live updates (WebSockets) through.
111
+
112
+ ## 7. Start it and create your account
113
+
114
+ ```
115
+ docker compose up -d
116
+ docker compose logs -f paperclip
117
+ ```
118
+
119
+ Wait until the log says the server is listening (press Ctrl+C to stop watching; Paperclip keeps running). Then create the one-time invite for your admin account:
120
+
121
+ ```
122
+ docker compose exec -u node paperclip npx --yes paperclipai auth bootstrap-ceo --data-dir /paperclip --base-url https://paperclip.yourdomain.com
123
+ ```
124
+
125
+ Open the link it prints, create your account, and set up your first company.
126
+
127
+ Optional, once you have your account: add `PAPERCLIP_AUTH_DISABLE_SIGN_UP: "true"` under `environment:` and run `docker compose up -d` to close public sign-ups.
128
+
129
+ ## 8. Sign in your agents
130
+
131
+ Either put `ANTHROPIC_API_KEY` / `OPENAI_API_KEY` in `.env` and run `docker compose up -d`, or sign in with your subscription inside the container:
132
+
133
+ ```
134
+ docker compose exec -it -u node paperclip claude
135
+ docker compose exec -it -u node paperclip codex
136
+ ```
137
+
138
+ Logins are saved in the `paperclip-data` volume, so they survive restarts and updates.
139
+
140
+ ## 9. Check and connect
141
+
142
+ ```
143
+ curl https://paperclip.yourdomain.com/api/health
144
+ ```
145
+
146
+ You want `"status":"ok"`, `"deploymentExposure":"public"` and `"bootstrapStatus":"ready"`. Then [connect Papercliped](/docs/hosting#connect-papercliped) and send *"Catch me up on my Paperclip."*
147
+
148
+ ## Updates
149
+
150
+ When your agents are idle (an update restarts Paperclip and stops runs in progress):
151
+
152
+ ```
153
+ cd ~/paperclip && docker compose pull && docker compose up -d
154
+ ```
155
+
156
+ To pin a version instead of `latest`, use a tag like `ghcr.io/paperclipai/paperclip:2026.1005.0` and read Paperclip's release notes before changing it.
157
+
158
+ ## Backups
159
+
160
+ Everything is in the `paperclip-data` volume. The safest copy is with Paperclip stopped:
161
+
162
+ ```
163
+ cd ~/paperclip && docker compose stop paperclip
164
+ docker run --rm -v paperclip_paperclip-data:/data -v "$PWD":/backup alpine tar czf /backup/paperclip-$(date +%F).tgz -C /data .
165
+ docker compose start paperclip
166
+ ```
167
+
168
+ Copy the `.tgz` somewhere off the server. Many providers also sell automatic server snapshots for a small fee.
169
+
170
+ ## Use a separate Postgres (optional)
171
+
172
+ For bigger setups, add a Postgres service and point Paperclip at it:
173
+
174
+ ```
175
+ db:
176
+ image: postgres:17-alpine
177
+ restart: unless-stopped
178
+ environment:
179
+ POSTGRES_USER: paperclip
180
+ POSTGRES_PASSWORD: change-me-long-random
181
+ POSTGRES_DB: paperclip
182
+ volumes:
183
+ - pgdata:/var/lib/postgresql/data
184
+ ```
185
+
186
+ Then add `DATABASE_URL: postgres://paperclip:change-me-long-random@db:5432/paperclip` to Paperclip's `environment:` and `pgdata:` under `volumes:`. Do this on a fresh install; moving existing data needs a database export and import.
187
+
188
+ ## Oracle Cloud free tier
189
+
190
+ Oracle's Always Free Ampere A1 servers are free but take extra steps:
191
+
192
+ - Open ports 80 and 443 in **two places**: the VCN's security list in the Oracle console, **and** the server's own firewall (Oracle's Ubuntu images ship strict `iptables` rules; allow 80 and 443 there or replace them with `ufw`).
193
+ - A1 servers are ARM; the Paperclip image supports ARM, so nothing else changes.
194
+ - Free capacity is often "out of host capacity" in popular regions, and Oracle can reclaim idle free servers. Fine for trying things, risky for anything you rely on.
195
+
196
+ ## Troubleshooting
197
+
198
+ - **Caddy can't get a certificate:** the A record isn't pointing at the server yet, port 80 or 443 is closed, or Cloudflare's orange-cloud proxy is on. Check with `docker compose logs caddy`.
199
+ - **"This hostname is not allowed":** `PAPERCLIP_DEPLOYMENT_EXPOSURE` isn't `public`, or `PAPERCLIP_PUBLIC_URL` doesn't match the address you're using.
200
+ - **The container keeps restarting:** run `docker compose logs paperclip`. A missing `BETTER_AUTH_SECRET` or a public URL that isn't `https://` stops it at startup.
201
+ - **Agents fail straight away:** they have no API key or login (step 8).
202
+ - More: [Troubleshooting](/docs/troubleshooting).