Beginner Paperclip 10 min read

How to Install Paperclip: Server, Dashboard, and First Company

#paperclip #installation #setup #nodejs #react #docker #dashboard
📚

Read these first:

If you have read What Is Paperclip?, you already understand the Company OS concept — companies, roles, org charts, heartbeats, and budget governance. Now it is time to turn that understanding into a running system.

This guide walks you through the complete installation process: cloning the repository, installing dependencies, starting the Node.js server and React dashboard, creating your first company, adding your first agent, and watching that agent complete its first heartbeat cycle. By the end, you will have a fully operational Paperclip installation running locally — ready for you to extend into a real autonomous agent organization.


Prerequisites

Before installing Paperclip, confirm that the following are available on your machine.

Runtime requirements:

RequirementMinimum VersionCheck Command
Node.js18.x or highernode --version
npm9.x or highernpm --version
GitAny recent versiongit --version

API keys — at least one of the following:

ProviderPurposeWhere to Get It
Anthropic (Claude)Default agent LLM backendconsole.anthropic.com
OpenAIAlternative agent LLM backendplatform.openai.com

Paperclip itself is model-agnostic — it manages scheduling, governance, and organizational structure, while the actual LLM calls happen in whichever backend each agent uses. That said, you need at least one LLM API key to power agent execution.

Verify your Node.js version before proceeding:

node --version
# Expected: v18.x.x or higher

npm --version
# Expected: 9.x.x or higher

If Node.js 18 is not installed, the recommended approach is to use nvm (Node Version Manager):

# Install nvm (macOS / Linux)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

# Reload shell
source ~/.bashrc

# Install and activate Node.js 18
nvm install 18
nvm use 18

# Confirm
node --version  # v18.x.x

On Windows, use nvm-windows or the official Node.js LTS installer from nodejs.org.


Installing the Paperclip Server

Paperclip is distributed as an open-source Node.js project on GitHub. The installation method is a standard git clone followed by npm install.

Step 1 — Clone the repository:

git clone https://github.com/paperclipai/paperclip.git
cd paperclip

Step 2 — Install all dependencies:

npm install

This installs the server backend, the React dashboard UI, and all shared utilities in a single command. Depending on your network speed, this typically takes 30–90 seconds.

Step 3 — Copy and configure the environment file:

cp .env.example .env

Open .env in your editor and fill in your configuration:

# .env

# === Server Configuration ===
PORT=3000                        # Port for the Paperclip REST API server
DASHBOARD_PORT=3001              # Port for the React dashboard UI

# === LLM API Keys ===
ANTHROPIC_API_KEY=sk-ant-...     # Claude API key (recommended default)
OPENAI_API_KEY=sk-...            # Optional: OpenAI API key for GPT-based agents

# === Database ===
DB_PATH=./data/paperclip.db      # SQLite database path (created automatically)

# === Security ===
JWT_SECRET=your-random-secret    # Replace with a long random string
ADMIN_EMAIL=[email protected]      # Dashboard admin account email
ADMIN_PASSWORD=changeme          # Dashboard admin account password — change this

# === Heartbeat ===
HEARTBEAT_DEFAULT_INTERVAL=3600  # Default agent heartbeat interval in seconds (1 hour)

Generate a strong JWT_SECRET with this command:

node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

Step 4 — Initialize the database:

npm run db:init

This creates the SQLite database file at the path specified in DB_PATH and runs all initial migrations. You should see output similar to:

[db] Initializing database at ./data/paperclip.db
[db] Running migration 001_initial_schema... done
[db] Running migration 002_audit_log... done
[db] Running migration 003_budget_tracking... done
[db] Database ready.

Step 5 — Build the React dashboard:

npm run build:dashboard

This compiles the React UI into static assets that the server will serve. The build output goes to packages/dashboard/dist/.


Starting the React Dashboard

With the build complete, you can start the full Paperclip stack — server and dashboard — in a single command:

npm run start

You should see output like this:

[paperclip] Starting Paperclip server...
[server] REST API listening on http://localhost:3000
[dashboard] UI available at http://localhost:3001
[heartbeat] Scheduler initialized — 0 active agents
[paperclip] Ready.

Open your browser and navigate to http://localhost:3001. You will see the Paperclip dashboard login screen. Log in with the ADMIN_EMAIL and ADMIN_PASSWORD you set in .env.

Running server and dashboard separately (development mode):

If you are doing active development or debugging, you can run each component in its own terminal:

# Terminal 1: Start the API server only
npm run start:server

# Terminal 2: Start the dashboard in hot-reload development mode
npm run dev:dashboard

In development mode, the dashboard runs on port 3001 with hot reload enabled, so UI changes are reflected instantly without rebuilding.

Keeping Paperclip running in the background:

For a persistent local setup, use pm2 to run Paperclip as a background process that survives terminal closes and system reboots:

# Install pm2 globally
npm install -g pm2

# Start Paperclip under pm2
pm2 start npm --name "paperclip" -- run start

# Auto-start on system boot
pm2 startup
pm2 save

# View logs
pm2 logs paperclip

# Restart after config changes
pm2 restart paperclip

Creating Your First Company

A Paperclip “company” is the top-level organizational unit that groups agents, goals, budgets, and audit logs under a single isolated namespace. You can create companies through the dashboard UI or the REST API. Both approaches are shown below.

Via the Dashboard UI:

  1. Log in at http://localhost:3001
  2. Click Companies in the left sidebar
  3. Click New Company
  4. Fill in the following fields:
    • Company Name: Acme AI (or any name you choose)
    • Slug: acme-ai (auto-generated, URL-safe)
    • Monthly Budget: $100.00 (total spend cap across all agents)
    • Budget Alert Threshold: 80% (receive an alert when 80% of budget is consumed)
    • Governance Mode: Standard (agents operate within role permissions; Strict requires human approval for actions above a cost threshold)
  5. Click Create Company

Via the REST API:

curl -X POST http://localhost:3000/api/v1/companies \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -d '{
    "name": "Acme AI",
    "slug": "acme-ai",
    "budget": {
      "monthly_limit_usd": 100.00,
      "alert_threshold_pct": 80
    },
    "governance": {
      "mode": "standard",
      "require_approval_above_usd": null
    }
  }'

The response confirms creation:

{
  "id": "cmp_01HX9...",
  "name": "Acme AI",
  "slug": "acme-ai",
  "budget": {
    "monthly_limit_usd": 100.00,
    "used_usd": 0.00,
    "alert_threshold_pct": 80
  },
  "governance": {
    "mode": "standard"
  },
  "created_at": "2026-04-08T09:00:00Z"
}

Retrieve a JWT token for API calls:

curl -X POST http://localhost:3000/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "password": "changeme"
  }'

Response:

{
  "token": "eyJhbGciOiJIUzI1NiIs...",
  "expires_in": 86400
}

Export the token for subsequent commands:

export PAPERCLIP_TOKEN="eyJhbGciOiJIUzI1NiIs..."

Adding Your First Agent

With a company created, you can add your first agent. Paperclip agents are defined by their role (which shapes their default prompt and behavior), their LLM backend (Claude, GPT-4, etc.), their heartbeat interval, and their individual budget cap.

Option A — Install from ClipHub (recommended for beginners):

ClipHub is Paperclip’s built-in marketplace of pre-configured agent templates. Installing from ClipHub gives you a well-tuned agent without needing to write a role prompt from scratch.

First, install the paperclipai CLI globally:

npm install -g paperclipai

Then install a senior Python engineer agent into your company:

paperclipai install cliphub:acme/senior-python-eng \
  --agent \
  --company acme-ai \
  --server http://localhost:3000 \
  --token $PAPERCLIP_TOKEN

You will be prompted to configure the agent:

Installing cliphub:acme/senior-python-eng into company "acme-ai"...

? Agent display name: Senior Python Engineer
? LLM backend: Claude (Anthropic)
? Heartbeat interval: Every 1 hour
? Monthly budget cap (USD): $20.00
? Activate immediately? Yes

Agent "Senior Python Engineer" installed successfully.
Agent ID: agt_02KY3...

Option B — Create an agent manually via the REST API:

For custom roles not covered by ClipHub, define the agent directly:

curl -X POST http://localhost:3000/api/v1/companies/acme-ai/agents \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $PAPERCLIP_TOKEN" \
  -d '{
    "name": "Senior Python Engineer",
    "role": "engineer",
    "role_prompt": "You are a senior Python engineer at Acme AI. Your responsibilities include reviewing pull requests, writing clean modular code, documenting functions, and flagging technical debt. Always follow PEP 8 style guidelines and write tests for any code you produce.",
    "llm": {
      "provider": "anthropic",
      "model": "claude-opus-4-5",
      "api_key_env": "ANTHROPIC_API_KEY"
    },
    "heartbeat": {
      "interval_seconds": 3600,
      "enabled": true
    },
    "budget": {
      "monthly_limit_usd": 20.00
    }
  }'

Verify the agent was added:

curl http://localhost:3000/api/v1/companies/acme-ai/agents \
  -H "Authorization: Bearer $PAPERCLIP_TOKEN"

Response:

{
  "agents": [
    {
      "id": "agt_02KY3...",
      "name": "Senior Python Engineer",
      "role": "engineer",
      "status": "idle",
      "heartbeat": {
        "interval_seconds": 3600,
        "next_fire_at": "2026-04-08T10:00:00Z",
        "last_fired_at": null
      },
      "budget": {
        "monthly_limit_usd": 20.00,
        "used_usd": 0.00
      }
    }
  ]
}

You can also view the agent in the dashboard by navigating to Companies → Acme AI → Agents.


Running Your First Task

An agent runs tasks autonomously on its heartbeat schedule, but you can also trigger an immediate task execution through the dashboard or REST API without waiting for the next heartbeat interval. This is the best way to verify that your setup is working correctly.

Step 1 — Assign a goal to the company:

Goals provide context that all agents in the company can access. Think of them as the strategic objectives your organization is working toward.

curl -X POST http://localhost:3000/api/v1/companies/acme-ai/goals \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $PAPERCLIP_TOKEN" \
  -d '{
    "title": "Refactor legacy data processing module",
    "description": "Audit the existing data_processor.py module for inefficiencies, rewrite any functions that exceed 50 lines, add type annotations to all public functions, and write unit tests achieving at least 80% coverage.",
    "priority": "high",
    "due_date": "2026-04-30"
  }'

Step 2 — Trigger an immediate heartbeat on the agent:

curl -X POST http://localhost:3000/api/v1/companies/acme-ai/agents/agt_02KY3.../heartbeat \
  -H "Authorization: Bearer $PAPERCLIP_TOKEN"

This forces the agent to execute its current task queue right now rather than waiting for the scheduled interval.

Step 3 — Monitor the heartbeat execution:

Watch the live execution log in the dashboard under Companies → Acme AI → Agents → Senior Python Engineer → Heartbeat Log, or poll the API:

curl http://localhost:3000/api/v1/companies/acme-ai/agents/agt_02KY3.../heartbeat/latest \
  -H "Authorization: Bearer $PAPERCLIP_TOKEN"

A completed heartbeat response looks like this:

{
  "heartbeat_id": "hb_09ZP1...",
  "agent_id": "agt_02KY3...",
  "status": "completed",
  "started_at": "2026-04-08T09:15:00Z",
  "completed_at": "2026-04-08T09:15:47Z",
  "duration_ms": 47210,
  "tasks_processed": 1,
  "cost_usd": 0.0083,
  "output": {
    "summary": "Reviewed goal: Refactor legacy data processing module. Identified 3 functions exceeding 50 lines. Drafted refactoring plan and flagged missing type annotations in 12 functions. Next action: begin rewriting process_batch() function.",
    "next_action": "Begin rewriting process_batch() — estimated 2 heartbeat cycles."
  }
}

Step 4 — Review the audit log:

Every heartbeat execution — including what the agent did, what it cost, and what decisions it made — is recorded in the audit log:

curl "http://localhost:3000/api/v1/companies/acme-ai/audit?limit=10" \
  -H "Authorization: Bearer $PAPERCLIP_TOKEN"

The audit log is also viewable in the dashboard under Companies → Acme AI → Audit Log, where you can filter by agent, date range, or cost threshold.

Understanding the heartbeat lifecycle:

Heartbeat fires


Agent wakes up


Server delivers context (goals, pending messages, prior outputs)


Agent executes role-appropriate actions (LLM calls, tool use)


Agent reports results + cost to server


Audit log updated, budget consumed


Agent goes idle until next heartbeat

This cycle repeats on the configured interval — every hour in the default setup — allowing your agent to make steady, autonomous progress on goals without requiring any human input between cycles.


Common Issues

Port Conflict on Startup

Symptom: The server fails to start with an EADDRINUSE error.

Error: listen EADDRINUSE: address already in use :::3000

Cause: Another process is already using port 3000 (or 3001 for the dashboard).

Fix: Either stop the conflicting process or change the ports in .env:

# Find what is using port 3000
lsof -i :3000          # macOS / Linux
netstat -ano | findstr :3000   # Windows

# Or simply change ports in .env
PORT=3010
DASHBOARD_PORT=3011

After changing ports, restart with npm run start and access the dashboard at the new port.


API Key Authentication Error

Symptom: The heartbeat fires but the agent returns an authentication error.

{
  "status": "failed",
  "error": "LLM provider returned 401 Unauthorized. Check API key for provider: anthropic"
}

Cause: The ANTHROPIC_API_KEY (or OPENAI_API_KEY) in .env is missing, expired, or incorrect.

Fix:

  1. Verify the key is correctly set in .env — no extra spaces, no missing sk-ant- prefix
  2. Test the key directly:
curl https://api.anthropic.com/v1/messages \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{"model":"claude-haiku-4-5","max_tokens":10,"messages":[{"role":"user","content":"ping"}]}'
  1. If the key is valid but the error persists, restart the server so it re-reads the environment variables:
npm run start
# or if using pm2:
pm2 restart paperclip

Heartbeat Not Firing on Schedule

Symptom: The agent shows status: idle and last_fired_at: null even after the configured interval has passed.

Cause: The heartbeat scheduler typically fails to start due to one of three issues: the server did not complete npm run db:init before first start, the HEARTBEAT_DEFAULT_INTERVAL in .env is set to a very large number for testing, or the agent’s heartbeat was explicitly disabled during creation.

Fix:

# Step 1: Confirm heartbeat is enabled for the agent
curl http://localhost:3000/api/v1/companies/acme-ai/agents/agt_02KY3... \
  -H "Authorization: Bearer $PAPERCLIP_TOKEN"
# Check: "heartbeat": { "enabled": true }

# Step 2: Enable heartbeat if disabled
curl -X PATCH http://localhost:3000/api/v1/companies/acme-ai/agents/agt_02KY3... \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $PAPERCLIP_TOKEN" \
  -d '{"heartbeat": {"enabled": true, "interval_seconds": 3600}}'

# Step 3: Manually trigger a heartbeat to confirm the agent is functional
curl -X POST http://localhost:3000/api/v1/companies/acme-ai/agents/agt_02KY3.../heartbeat \
  -H "Authorization: Bearer $PAPERCLIP_TOKEN"

# Step 4: Check the scheduler status
curl http://localhost:3000/api/v1/system/scheduler \
  -H "Authorization: Bearer $PAPERCLIP_TOKEN"

If the scheduler shows status: stopped, restart the server to reinitialize it.


Frequently Asked Questions

Do I need a separate database for Paperclip?

No. Paperclip ships with SQLite as its built-in database and creates the database file automatically at the path specified by DB_PATH in your .env. For a local or small-team installation, SQLite is fully sufficient — Paperclip’s data access patterns (structured reads and writes, low concurrency) are well suited to SQLite’s strengths. If you plan to scale to a large number of concurrent agents or companies and require higher write throughput, Paperclip’s architecture is designed to support swapping in PostgreSQL, but that is an advanced configuration not needed for most deployments. For the vast majority of use cases, the default SQLite setup requires no additional infrastructure.

How do I set up Paperclip behind a reverse proxy?

Paperclip’s server and dashboard are standard HTTP services, so any reverse proxy that can proxy HTTP — Nginx, Caddy, Apache, Traefik — works with it. Below is a minimal Nginx configuration that proxies both the API server and the dashboard under a single domain:

server {
    listen 80;
    server_name paperclip.yourdomain.com;

    # Dashboard UI
    location / {
        proxy_pass http://localhost:3001;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    # REST API
    location /api/ {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

After setting up the reverse proxy, update your .env to reflect the public URL so that any server-generated links use the correct base:

PUBLIC_BASE_URL=https://paperclip.yourdomain.com

Use Certbot or Caddy’s built-in HTTPS to add TLS — always encrypt a public-facing Paperclip installation since it handles LLM API keys and audit data.

Can I run multiple companies on the same server?

Yes — multi-company isolation is a first-class feature of Paperclip. A single installation can host any number of companies, each with completely independent agents, org charts, goals, budgets, and audit logs. No data leaks between companies at the API layer; each company operates as a fully sandboxed namespace identified by its slug.

To create additional companies, simply repeat the company creation step from earlier in this guide with a different name and slug. Each new company starts with zero agents and an empty audit log, completely isolated from all others. This makes Paperclip particularly well-suited for agencies managing AI operations for multiple clients, or for developers who want to maintain separate experimental and production environments on the same server without running duplicate infrastructure.


Next Steps

You now have a running Paperclip installation with a company, an agent, and your first completed heartbeat cycle. Here are the logical next steps to build on this foundation:

Expand your org chart. Add more agents with different roles — a CEO agent for strategic planning, a CTO for technical direction, or specialist agents for marketing, support, or data analysis. The real power of Paperclip’s Company OS model emerges when multiple agents are working in coordination under a shared set of goals.

Explore ClipHub templates. Browse the available marketplace templates with paperclipai search cliphub to find pre-configured agents for common roles. Installing well-tuned templates is much faster than writing role prompts from scratch, especially when you are still learning what prompt patterns produce reliable agent behavior.

Tighten your governance configuration. Review your budget limits and consider enabling Strict governance mode if your agents will be taking consequential actions. Setting per-agent budget caps and enabling budget alerts ensures that runaway API costs are caught before they become expensive.

Set up real monitoring. For production use, configure log aggregation so that audit logs are preserved outside the SQLite database for long-term retention. Tools like Grafana, Datadog, or a simple log shipping setup to S3 can give you durable audit history and cost trend analysis over time.

For a comparison of how Paperclip’s persistent-server, heartbeat-driven model differs from pipeline-oriented frameworks, see our guide on how to install MetaGPT — walking through both installations side-by-side is one of the best ways to develop intuition for when to use which tool.

Related Articles