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.
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +20 -0
- package/README.md +9 -5
- package/dist/access/guard.js +17 -0
- package/dist/access/policy.js +203 -0
- package/dist/execute.js +25 -1
- package/dist/manage/routes.js +46 -2
- package/dist/mcp.js +6 -5
- package/dist/oauth/pg-store.js +13 -1
- package/dist/oauth/provider.js +50 -1
- package/dist/oauth/store.js +20 -0
- package/dist/public-api/types.js +1 -1
- package/dist/server.js +2 -2
- package/dist/site/markdown.js +26 -5
- package/dist/site/site.js +10 -1
- package/docs/CONTROL-ROOM.md +79 -0
- package/docs/SECURITY.md +1 -1
- package/docs/SITEMAP.md +3 -1
- package/docs/supabase-schema.sql +12 -1
- package/migrations/007_control_room.sql +9 -0
- package/package.json +1 -1
- package/site/docs/access-modes.md +72 -0
- package/site/docs/connect-your-paperclip.md +139 -93
- package/site/docs/control-room.md +61 -0
- package/site/docs/faq.md +16 -1
- package/site/docs/getting-started.md +2 -2
- package/site/docs/host-coolify.md +78 -0
- package/site/docs/host-fly.md +129 -0
- package/site/docs/host-railway.md +105 -0
- package/site/docs/host-render.md +79 -0
- package/site/docs/host-vps.md +202 -0
- package/site/docs/hosting.md +105 -0
- package/site/docs/limits-and-errors.md +1 -0
- package/site/docs/manage-api.md +12 -1
- package/site/docs/paperclip-plugin.md +21 -10
- package/site/docs/permissions.md +8 -0
- package/site/docs/prompts.md +349 -0
- package/site/docs/public-api.md +1 -1
- package/site/docs/signup.md +1 -1
- package/site/docs/tools.md +35 -35
- 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 [
|
|
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 [
|
|
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,
|
|
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).
|