Installation
There are three ways to install Paperclip. Choose the one that fits how you work:
- Desktop App — a regular macOS application. Download it, open it, done. No terminal, no developer tools, no configuration files. This is the right choice if you're not a developer.
- Terminal — install and run Paperclip locally from the command line. For developers who want full control over configuration and hosting on their own machine.
- Server / VPS — deploy Paperclip to a cloud server (AWS, GCP, DigitalOcean, Hetzner, etc.) behind a custom domain with HTTPS. For teams and anyone who wants their instance reachable from anywhere.
All three paths end up in the same place: a running Paperclip instance and the onboarding flow where you create your first company, first agent, and first piece of work.
Step 1 — Check which Mac you have
Paperclip Desktop comes in two versions depending on your Mac's chip. If you're not sure which one you have:
- Click the Apple menu () in the top-left corner of your screen
- Click About This Mac
- Look at the line that says Chip or Processor
- If it says Apple M1, M2, M3, or M4 — you have Apple Silicon
- If it says Intel Core — you have an Intel Mac
Step 2 — Download Paperclip Desktop
Go to the Paperclip Desktop releases page and download the installer for your Mac:
| My Mac has… | Download this file |
|---|---|
| Apple Silicon (M1/M2/M3/M4) | Paperclip.Desktop-[version]-arm64.dmg |
| Intel | Paperclip.Desktop-[version].dmg |
Note: The version number in the filename will match the latest release. If you see multiple
.dmgfiles, the one witharm64in the name is for Apple Silicon. The one without is for Intel.
Step 3 — Install the app
- Open the
.dmgfile you downloaded — it will mount like a disk image and open a window - Drag the Paperclip icon into the Applications folder
That's the whole installation. You can eject the .dmg and move it to the trash once the drag is done.
Step 4 — Open Paperclip
Open Paperclip from your Applications folder, or press Cmd+Space and type Paperclip.
Warning: The first time you open Paperclip, macOS may show a prompt saying it can't verify the developer. This is a standard macOS warning for apps downloaded outside the App Store. Click Open to proceed — Paperclip is safe to run.
The first launch takes 10–30 seconds while Paperclip starts its local server in the background. You'll see a loading indicator. Subsequent launches are faster.
Step 5 — Get your API key
Before your agents can do any work, you need an API key. An API key is a private token — similar to a password — that allows your agents to make calls to an AI provider like Anthropic (Claude) or OpenAI. Without one, agents have no way to generate responses or take actions.
Warning: AI providers charge for usage. Every time an agent works, it makes API calls that cost a small amount of money. The cost depends on which model you use and how much your agents work. Paperclip lets you set budgets to keep this under control, but you should be aware of this before your agents start running.
Choose your AI provider and follow the steps to get a key:
Anthropic makes Claude — the AI that powers the claude_local adapter, which is the most common choice for Paperclip agents.
- Go to console.anthropic.com and create an account (or sign in)
- In the left sidebar, click API Keys
- Click Create Key
- Give it a name you'll recognise (e.g. "Paperclip")
- Copy the key — it starts with
sk-ant-
Warning: Copy the key immediately. Anthropic only shows it once. If you lose it, you'll need to create a new one.
Store it somewhere safe — you'll add it to Paperclip as an environment variable or secret when you set up your first agent.
OpenAI makes the models that power the codex_local adapter.
- Go to platform.openai.com and create an account (or sign in)
- Click your profile icon in the top-right, then API keys
- Click Create new secret key
- Give it a name (e.g. "Paperclip") and click Create secret key
- Copy the key — it starts with
sk-
Warning: Copy the key immediately. OpenAI only shows it once. If you lose it, you'll need to create a new one.
You don't need to enter the key into Paperclip yet. You'll wire it up when you configure your first agent in the next guide.
Step 6 — Choose Local or Remote mode
When Paperclip Desktop opens, it asks how you want to connect:
Local mode runs a complete Paperclip instance directly on your Mac. Your agents run on your machine, all data stays local, and nothing is sent to an external server (beyond the API calls your agents make to Anthropic or OpenAI). This is the right choice when you're getting started.
Remote mode connects the Desktop app to a Paperclip instance running on another machine — a team server, a cloud host, or a colleague's computer. You'll only need this if someone has already set up a shared Paperclip instance that you're connecting to.
For now, choose Local. You can always connect to a remote instance later from the app's settings.
After selecting Local, Paperclip finishes starting up and takes you into onboarding (or a start screen with a New Company button). That's expected. You haven't created a company yet.
Note: This path is for developers who are comfortable working in a terminal. If that's not you, use the Desktop App tab instead — it covers the same ground without any of this.
Step 1 — Install Node.js 20 or later
If you don't have Node.js installed, download the installer from nodejs.org and run it. Choose the LTS version.
To check if Node.js is already installed and at the right version:
node --version
# Should print v20.x.x or higher
Step 2 — Install pnpm
npm install -g corepack
corepack enable
corepack prepare pnpm@latest --activate
Step 3 — Run the onboarding command
Warning: Do not run this command with
sudoor from a root/admin shell. The default setup starts embedded PostgreSQL, and PostgreSQL refuses to run as an administrative user. Run it as your normal user on a local machine. On a server, first switch to the dedicatedpaperclipuser withsudo -iu paperclip, then run the command.
npx paperclipai onboard --yes
This single command handles everything: it downloads Paperclip, creates a configuration directory at ~/.paperclip/, initialises an embedded database, and starts the server at http://localhost:3100. The --yes flag accepts all defaults — you can run without it to customise deployment mode, database, and storage.
✓ Created config at ~/.paperclip/instances/default/config.json
✓ Initialised database
✓ Server running at http://localhost:3100
→ Opening Paperclip in your browser...
Step 4 — Open Paperclip
Paperclip opens automatically in your browser. If it doesn't, navigate to http://localhost:3100.
You'll land in Paperclip ready to start onboarding. You haven't created a company yet — that's the next step.
Note: To run Paperclip again after restarting your machine, run
npx paperclipai runfrom your terminal. For persistent background runs, see the advanced deployment docs.
Note: This path is for deploying Paperclip to an internet-facing server behind a domain name, with login required. You'll need SSH access to a Linux VPS, a registered domain name, and a little comfort with the command line. If you only need Paperclip for yourself on your own Mac, use the Desktop App tab instead.
Any Linux VPS with 1 vCPU and 2 GB of RAM is enough to get started. These instructions use Ubuntu 22.04 / 24.04 LTS as the reference distribution — commands on AWS EC2, Google Cloud Compute Engine, DigitalOcean Droplets, Hetzner Cloud, Linode, and similar providers are effectively identical.
Step 1 — Provision the server
Create a VPS with your provider of choice:
- DigitalOcean — create a Droplet with Ubuntu 24.04, the Basic plan with 2 GB RAM is plenty to start.
- AWS EC2 — launch a
t3.small(ort4g.smallfor ARM) instance running Ubuntu 24.04. - Google Cloud — create an
e2-smallCompute Engine VM with the Ubuntu 24.04 LTS image. - Hetzner / Linode / Vultr — any ~€5/month Ubuntu 24.04 instance works.
In the provider's firewall or security group, open the following inbound ports:
| Port | Protocol | Purpose |
|---|---|---|
| 22 | TCP | SSH |
| 80 | TCP | HTTP (Let's Encrypt challenge + redirect) |
| 443 | TCP | HTTPS |
Do not open port 3100 to the internet. Paperclip itself will bind to 127.0.0.1 — Nginx is what the world talks to.
SSH in as a sudo-capable user:
ssh [email protected]
Step 2 — Point your domain at the server
Before installing anything, create a DNS A record for the hostname you want to use:
| Type | Name | Value |
|---|---|---|
| A | paperclip.example.com |
<your server's public IPv4> |
Wait a minute or two and confirm it resolves:
dig +short paperclip.example.com
# Should print your server's IP
HTTPS certificate issuance in Step 7 will fail if DNS isn't pointing at the server yet, so get this right first.
Step 3 — Install Node.js 20+ and pnpm
Paperclip requires Node.js 20 or later and pnpm. Install Node.js from NodeSource:
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs git ca-certificates
Enable pnpm via Corepack (shipped with Node.js):
sudo npm install -g corepack
sudo corepack enable
corepack prepare pnpm@latest --activate
Verify:
node --version # v20.x or higher
pnpm --version # 9.x or higher
Step 4 — Create a dedicated service user
Running Paperclip as a non-root user keeps the blast radius small if anything goes wrong:
sudo useradd --system --create-home --shell /bin/bash paperclip
sudo -iu paperclip
The rest of the installation commands run as the paperclip user, unless marked with sudo.
Step 5 — Install Paperclip in public deployment mode
From the paperclip user's home directory, export the environment variables that tell Paperclip it's an internet-facing instance, then run onboarding:
export PAPERCLIP_DEPLOYMENT_MODE=authenticated
export PAPERCLIP_DEPLOYMENT_EXPOSURE=public
export PAPERCLIP_AUTH_PUBLIC_BASE_URL=https://paperclip.example.com
export PAPERCLIP_ALLOWED_HOSTNAMES=paperclip.example.com
npx paperclipai onboard --yes
Warning: The variable names matter.
PAPERCLIP_AUTH_PUBLIC_BASE_URL(notPAPERCLIP_PUBLIC_BASE_URLorPAPERCLIP_API_URL) is what the CLI reads. If you setdeploymentMode=authenticated+exposure=publicwithout it,paperclipai doctorwill fail the config withauth.publicBaseUrl is requiredand the server won't start.
What each variable does:
PAPERCLIP_AUTH_PUBLIC_BASE_URL— the external URL users will hit. This becomes Better Auth's canonical base URL and setsauth.baseUrlMode=explicitautomatically.PAPERCLIP_ALLOWED_HOSTNAMES— comma-separated list of hostnames Paperclip will accept requests for. The hostname from your base URL is added automatically; include any extra aliases (e.g.paperclip.example.com,www.paperclip.example.com). Requests for unknown hosts are rejected.- The server binds to
127.0.0.1:3100by default, which is exactly what you want behind Nginx — noPAPERCLIP_BINDoverride needed. (If you ever need to expose it on a LAN or Tailnet instead, the CLI acceptsPAPERCLIP_BIND=lan|tailnet|customwithPAPERCLIP_BIND_HOSTfor thecustomcase.)
The --yes flag accepts Quickstart defaults: authenticated/public deployment, embedded PostgreSQL (port 54329, data in ~/.paperclip/instances/default/db), local disk storage, and a fresh 32-byte secrets master key at ~/.paperclip/instances/default/secrets/master.key.
Warning: Back up
secrets/master.keysomewhere safe. It encrypts every API key and secret stored in Paperclip — if you lose it, you lose access to all of them.
To customise any of those choices, omit --yes and walk through the prompts, or re-run paperclipai configure --section <name> later. Valid sections are: llm, database, logging, server, storage, secrets. (Auth URL settings live under the server section, not a separate auth section — the error message suggesting --section database is misleading.)
Onboarding creates the config at ~/.paperclip/instances/default/config.json and initialises the database. When it finishes, press Ctrl+C if it offered to start the server — you'll run it under systemd next. You'll generate the first-user invite link in Step 9 using paperclipai auth bootstrap-ceo.
Step 6 — Run Paperclip under systemd
As the paperclip user, write an environment file so systemd picks up the same config:
cat > ~/paperclip.env <<'EOF'
PAPERCLIP_DEPLOYMENT_MODE=authenticated
PAPERCLIP_DEPLOYMENT_EXPOSURE=public
PAPERCLIP_AUTH_PUBLIC_BASE_URL=https://paperclip.example.com
PAPERCLIP_ALLOWED_HOSTNAMES=paperclip.example.com
EOF
chmod 600 ~/paperclip.env
Note:
PAPERCLIP_AGENT_JWT_SECRETwas already written to~/.paperclip/instances/default/.envduring onboarding and is loaded automatically — don't duplicate it here.
Then, switch back to your sudo user (exit) and create the service unit:
sudo tee /etc/systemd/system/paperclip.service > /dev/null <<'EOF'
[Unit]
Description=Paperclip control plane
After=network.target
[Service]
Type=simple
User=paperclip
Group=paperclip
WorkingDirectory=/home/paperclip
EnvironmentFile=/home/paperclip/paperclip.env
ExecStart=/usr/bin/npx paperclipai run
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now paperclip
sudo systemctl status paperclip
Check the logs if anything looks off:
sudo journalctl -u paperclip -f
You should see Paperclip listening on http://127.0.0.1:3100.
Step 7 — Put Nginx in front of Paperclip
Install Nginx:
sudo apt-get install -y nginx
Create a site config for your domain:
sudo tee /etc/nginx/sites-available/paperclip > /dev/null <<'EOF'
server {
listen 80;
server_name paperclip.example.com;
client_max_body_size 50m;
location / {
proxy_pass http://127.0.0.1:3100;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket / long-lived streaming endpoints
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
}
EOF
sudo ln -sf /etc/nginx/sites-available/paperclip /etc/nginx/sites-enabled/paperclip
sudo rm -f /etc/nginx/sites-enabled/default
sudo nginx -t && sudo systemctl reload nginx
Replace paperclip.example.com with your own hostname.
Step 8 — Add HTTPS with Let's Encrypt
Install Certbot and issue a certificate. Certbot will edit the Nginx config to handle TLS termination and HTTP → HTTPS redirects automatically:
sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d paperclip.example.com
Accept the Terms of Service, enter an email for expiry notifications, and choose redirect when asked whether to force HTTPS.
Certbot sets up a systemd timer that auto-renews certificates before they expire. Confirm it's active:
systemctl list-timers | grep certbot
Visit https://paperclip.example.com in a browser — you should see Paperclip's login screen served over HTTPS.
Step 9 — Bootstrap the CEO account
Because you set PAPERCLIP_DEPLOYMENT_MODE=authenticated, the instance requires login. The first user is created via a one-time invite link generated by the CLI.
As the paperclip user, generate the invite:
sudo -iu paperclip
npx paperclipai auth bootstrap-ceo
The command prints an Invite URL that looks like:
Invite URL: https://paperclip.example.com/invite/<token>
Note:
bootstrap-ceoonly runs in authenticated mode and needs to reach the database. If you're using the embedded PostgreSQL, make sure thepaperclipsystemd service is running when you invoke it, or the DB file lock will be held elsewhere.
Open the invite URL in a browser, create your account (email + password via Better Auth), and you'll land on the instance as the CEO/owner.
If you lose the link, re-run the command with --force to rotate the token:
npx paperclipai auth bootstrap-ceo --force
Optional flags: --expires-hours N to change link lifetime, --base-url <URL> to override the URL used for the invite, --db-url <URL> if you're pointing at an external database.
Step 10 — Get your API key
You still need an Anthropic or OpenAI key for your agents to do any work. Follow the Get your API key step in the Desktop App tab — it's identical for server deployments. Paste the key into Paperclip's Secrets UI once you're signed in; it will be encrypted with the master key from Step 5 and referenced by the adapter config.
Troubleshooting
Useful diagnostic commands if anything goes wrong:
paperclipai doctor— validates config and environment. Run it beforerunto catch schema errors early. Pass--repairto auto-fix what it can.paperclipai env— prints the env vars Paperclip is actually reading, so you can confirm your exports landed.paperclipai allowed-hostname <host>— add a hostname toserver.allowedHostnamesafter install (e.g. if you add a second domain).paperclipai configure --section server— re-prompt for the server/auth settings (bind, exposure, public base URL, allowed hostnames) without rebuilding everything.sudo journalctl -u paperclip -f— tail the server logs.
Common errors:
Embedded PostgreSQL failedwithExecution of PostgreSQL by a user with administrative permissions is not permitted— Paperclip was started as root or with elevated privileges. Stop it, switch to a normal non-root user, and runnpx paperclipai runagain. On a VPS, make sure you have runsudo -iu paperclipbefore onboarding or starting Paperclip. If you accidentally created files under the wrong account, remove the root-owned instance or fix ownership before retrying.auth.publicBaseUrl is required when deploymentMode=authenticated and exposure=public— you didn't exportPAPERCLIP_AUTH_PUBLIC_BASE_URLbefore runningonboard. Re-export it and runpaperclipai configure --section server(or re-runpaperclipai onboard --yes).- Requests rejected with a host mismatch — the hostname you're accessing isn't in
server.allowedHostnames. Add it viapaperclipai allowed-hostname <host>or by editingPAPERCLIP_ALLOWED_HOSTNAMESin~/paperclip.envand restarting the service. - Invite link 404s — the invite was already consumed, or the base URL on the printed link doesn't match what the browser is hitting. Re-run
paperclipai auth bootstrap-ceo --force --base-url https://paperclip.example.com.
Common variations
- Hosted PostgreSQL — set
DATABASE_URL=postgres://...in~/paperclip.envbefore onboarding. Use the pooled connection (port 6543 on Supabase) for the app and the direct connection for migrations. See Database deployment. - Object storage — set
PAPERCLIP_STORAGE_MODE=s3plus the relevant S3 env vars. See Storage deployment. - Private team server over Tailscale instead of a public domain — skip Nginx/Certbot and use
PAPERCLIP_DEPLOYMENT_EXPOSURE=privatewithPAPERCLIP_BIND=tailnet. See Tailscale private access. On a private, authenticated instance you can also skip the CLI invite for the first user: the very first person to sign in from a browser can claim themselves as the instance admin straight from the UI — whoever clicks first wins, and everyone else is locked out of the claim. See Claim first instance admin for the details. - Docker instead of bare metal — a production-ready image and Compose file ship in the repo. See Docker deployment.
Connecting the Desktop app to your server
Once your server is live, anyone on the team can use the macOS Desktop app as a thin client:
- Install the Desktop app (see the Desktop App tab).
- On the first-launch screen, choose Remote.
- Enter
https://paperclip.example.comas the instance URL. - Sign in with the account you created during the board claim.
The Desktop app becomes a UI shell over your VPS — everyone on the team sees the same companies, agents, and issues.
You're in
Paperclip is running. The next guide walks you through creating your first company, setting a goal if you have one ready, and getting it ready for agents.