From f3a11a2d25ec931d3b0d9f41846f0d9da357a4cc Mon Sep 17 00:00:00 2001 From: fpulch <31630392+fpulch@users.noreply.github.com> Date: Fri, 17 Apr 2026 13:57:31 +0200 Subject: [PATCH 1/6] feat: add Paperclip helper script --- ct/paperclip.sh | 82 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 ct/paperclip.sh diff --git a/ct/paperclip.sh b/ct/paperclip.sh new file mode 100644 index 00000000..4bae19d8 --- /dev/null +++ b/ct/paperclip.sh @@ -0,0 +1,82 @@ +#!/usr/bin/env bash +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) +# Copyright (c) 2021-2026 community-scripts ORG +# Author: Fabian Pulch (fpulch) +# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE +# Source: https://github.com/paperclipai/paperclip + +APP="Paperclip" +var_tags="${var_tags:-ai;automation;dev-tools}" +var_cpu="${var_cpu:-4}" +var_ram="${var_ram:-8192}" +var_disk="${var_disk:-20}" +var_os="${var_os:-debian}" +var_version="${var_version:-13}" +var_unprivileged="${var_unprivileged:-1}" + +header_info "$APP" +variables +color +catch_errors + +function update_script() { + header_info + check_container_storage + check_container_resources + + if [[ ! -d /opt/paperclip ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + + if check_for_gh_release "paperclip" "paperclipai/paperclip"; then + msg_info "Stopping Service" + systemctl stop paperclip + msg_ok "Stopped Service" + + msg_info "Backing up Configuration" + cp /opt/paperclip/.env /opt/paperclip.env.bak + msg_ok "Backed up Configuration" + + CLEAN_INSTALL=1 fetch_and_deploy_gh_release "paperclip" "paperclipai/paperclip" "tarball" + + msg_info "Restoring Configuration" + mv /opt/paperclip.env.bak /opt/paperclip/.env + msg_ok "Restored Configuration" + + msg_info "Rebuilding Paperclip" + cd /opt/paperclip + export HUSKY=0 + export NODE_OPTIONS="--max-old-space-size=8192" + $STD pnpm install --frozen-lockfile + $STD pnpm build + unset NODE_OPTIONS + msg_ok "Rebuilt Paperclip" + + msg_info "Updating Agent CLIs" + $STD npm install -g \ + @anthropic-ai/claude-code@latest \ + @openai/codex@latest + msg_ok "Updated Agent CLIs" + + msg_info "Running Database Migrations" + set -a && source /opt/paperclip/.env && set +a + $STD pnpm db:migrate + msg_ok "Ran Database Migrations" + + msg_info "Starting Service" + systemctl start paperclip + msg_ok "Started Service" + msg_ok "Updated successfully!" + fi + exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" +echo -e "${INFO}${YW} Access it using the following URL:${CL}" +echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3100${CL}" From 971572f32de01637ab1131c61bd724a035fadc8e Mon Sep 17 00:00:00 2001 From: fpulch <31630392+fpulch@users.noreply.github.com> Date: Fri, 17 Apr 2026 13:57:32 +0200 Subject: [PATCH 2/6] fix: persist Paperclip bootstrap invite when available --- install/paperclip-install.sh | 154 +++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 install/paperclip-install.sh diff --git a/install/paperclip-install.sh b/install/paperclip-install.sh new file mode 100644 index 00000000..1358b98b --- /dev/null +++ b/install/paperclip-install.sh @@ -0,0 +1,154 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2026 community-scripts ORG +# Author: Fabian Pulch (fpulch) +# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE +# Source: https://github.com/paperclipai/paperclip + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +install_packages_with_retry \ + build-essential \ + git \ + python3 \ + ripgrep +msg_ok "Installed Dependencies" + +NODE_VERSION="24" NODE_MODULE="pnpm" setup_nodejs +PG_VERSION="17" setup_postgresql +PG_DB_NAME="paperclip" PG_DB_USER="paperclip" setup_postgresql_db + +fetch_and_deploy_gh_release "paperclip" "paperclipai/paperclip" "tarball" + +msg_info "Building Paperclip" +cd /opt/paperclip +export HUSKY=0 +export NODE_OPTIONS="--max-old-space-size=8192" +$STD pnpm install --frozen-lockfile +$STD pnpm build +unset NODE_OPTIONS +msg_ok "Built Paperclip" + +msg_info "Installing Agent CLIs" +$STD npm install -g \ + @anthropic-ai/claude-code@latest \ + @openai/codex@latest +msg_ok "Installed Agent CLIs" + +msg_info "Configuring Paperclip" +mkdir -p /opt/paperclip-data +mkdir -p /root/.claude /root/.codex +BETTER_AUTH_SECRET=$(openssl rand -hex 32) +cat </opt/paperclip/.env +DATABASE_URL=postgresql://${PG_DB_USER}:${PG_DB_PASS}@127.0.0.1:5432/${PG_DB_NAME} +HOST=0.0.0.0 +PORT=3100 +SERVE_UI=true +PAPERCLIP_HOME=/opt/paperclip-data +PAPERCLIP_INSTANCE_ID=default +PAPERCLIP_DEPLOYMENT_MODE=authenticated +PAPERCLIP_DEPLOYMENT_EXPOSURE=private +PAPERCLIP_PUBLIC_URL=http://${LOCAL_IP}:3100 +BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET} +EOF +msg_ok "Configured Paperclip" + +msg_info "Running Database Migrations" +set -a && source /opt/paperclip/.env && set +a +$STD pnpm db:migrate +msg_ok "Ran Database Migrations" + +msg_info "Bootstrapping Paperclip" +PAPERCLIP_ONBOARD_LOG=/opt/paperclip/paperclip-onboard.log +PAPERCLIP_BOOTSTRAP_LOG=/opt/paperclip/paperclip-bootstrap.log + +run_paperclip_onboard() { + rm -f "$PAPERCLIP_ONBOARD_LOG" + setsid bash -c "cd /opt/paperclip && $1" >"$PAPERCLIP_ONBOARD_LOG" 2>&1 & + PAPERCLIP_ONBOARD_PID=$! + for _ in {1..60}; do + if [[ -f /opt/paperclip-data/instances/default/config.json ]]; then + break + fi + if ! kill -0 "$PAPERCLIP_ONBOARD_PID" 2>/dev/null; then + break + fi + sleep 2 + done + if kill -0 "$PAPERCLIP_ONBOARD_PID" 2>/dev/null; then + kill -- -"${PAPERCLIP_ONBOARD_PID}" >/dev/null 2>&1 || true + wait "$PAPERCLIP_ONBOARD_PID" 2>/dev/null || true + fi +} + +run_paperclip_onboard "pnpm paperclipai onboard --yes --bind lan" +if [[ ! -f /opt/paperclip-data/instances/default/config.json ]] && grep -q "unknown option '--bind'" "$PAPERCLIP_ONBOARD_LOG"; then + msg_info "Retrying Paperclip Onboarding" + run_paperclip_onboard "pnpm paperclipai onboard --yes" +fi + +if [[ ! -f /opt/paperclip-data/instances/default/config.json ]]; then + msg_error "Failed to bootstrap Paperclip" + exit 1 +fi + +if grep -q 'authenticated' /opt/paperclip-data/instances/default/config.json; then + pnpm paperclipai auth bootstrap-ceo >"$PAPERCLIP_BOOTSTRAP_LOG" 2>&1 || true + PAPERCLIP_INVITE_URL=$(awk -F'Invite URL: ' '/Invite URL:/ {print $2; exit}' "$PAPERCLIP_BOOTSTRAP_LOG") + PAPERCLIP_INVITE_EXPIRY=$(awk -F'Expires: ' '/Expires:/ {print $2; exit}' "$PAPERCLIP_BOOTSTRAP_LOG") + if [[ -n "$PAPERCLIP_INVITE_URL" ]]; then + cat <>~/paperclip.creds + +Paperclip Admin Invite +Invite URL: ${PAPERCLIP_INVITE_URL} +Expires: ${PAPERCLIP_INVITE_EXPIRY} +EOF + msg_ok "Generated Paperclip CEO Invite" + echo -e "${INFO}${YW} Open this invite URL to finish Paperclip admin setup:${CL}" + echo -e "${TAB}${GATEWAY}${BGN}${PAPERCLIP_INVITE_URL}${CL}" + [[ -n "$PAPERCLIP_INVITE_EXPIRY" ]] && echo -e "${TAB}${INFO}${YW}Invite expires: ${PAPERCLIP_INVITE_EXPIRY}${CL}" + else + msg_warn "Paperclip authenticated mode is enabled, but no CEO invite was generated automatically" + fi +else + msg_info "Paperclip Bootstrapped in Local Trusted Mode" +fi +rm -f "$PAPERCLIP_ONBOARD_LOG" "$PAPERCLIP_BOOTSTRAP_LOG" +msg_ok "Bootstrapped Paperclip" + +msg_info "Creating Service" +cat </etc/systemd/system/paperclip.service +[Unit] +Description=Paperclip +After=network.target postgresql.service +Requires=postgresql.service + +[Service] +Type=simple +User=root +WorkingDirectory=/opt/paperclip +EnvironmentFile=/opt/paperclip/.env +Environment=HOME=/root +Environment=CODEX_HOME=/root/.codex +Environment=PATH=/root/.local/bin:/usr/local/bin:/usr/bin:/bin +Environment=DISABLE_AUTOUPDATER=1 +ExecStart=/usr/bin/env pnpm paperclipai run +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now paperclip +msg_ok "Created Service" + +motd_ssh +customize +cleanup_lxc From dee76eaf92a1043ff501e793bb54399ee369e3be Mon Sep 17 00:00:00 2001 From: fpulch <31630392+fpulch@users.noreply.github.com> Date: Fri, 17 Apr 2026 13:57:33 +0200 Subject: [PATCH 3/6] fix: persist Paperclip bootstrap invite when available --- json/paperclip.json | 68 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 json/paperclip.json diff --git a/json/paperclip.json b/json/paperclip.json new file mode 100644 index 00000000..8a0068af --- /dev/null +++ b/json/paperclip.json @@ -0,0 +1,68 @@ +{ + "name": "Paperclip", + "slug": "paperclip", + "categories": [ + 20 + ], + "date_created": "2026-04-15", + "type": "ct", + "updateable": true, + "privileged": false, + "interface_port": 3100, + "documentation": "https://docs.paperclip.ing/", + "website": "https://paperclip.ing/", + "logo": "https://github.com/paperclipai.png", + "description": "Paperclip is an open-source orchestration platform for managing autonomous AI agent teams with goals, routines, governance, and a browser-based control plane.", + "install_methods": [ + { + "type": "default", + "script": "ct/paperclip.sh", + "config_path": "/opt/paperclip/.env", + "resources": { + "cpu": 4, + "ram": 8192, + "hdd": 20, + "os": "Debian", + "version": "13" + } + } + ], + "default_credentials": { + "username": null, + "password": null + }, + "notes": [ + { + "text": "The installer attempts Paperclip authenticated/private onboarding for LAN access. If a Paperclip release falls back to local quickstart behavior, first access will not require login and you can switch modes later with `pnpm paperclipai configure --section server`.", + "type": "info" + }, + { + "text": "Persistent Paperclip runtime data is stored in `/opt/paperclip-data`, while the application code lives in `/opt/paperclip`.", + "type": "info" + }, + { + "text": "Database credentials are stored in `~/paperclip.creds`. These are PostgreSQL credentials generated by the shared helper, not the Paperclip web login or Codex/Claude authentication.", + "type": "info" + }, + { + "text": "If authenticated mode is active, the installer saves the current CEO bootstrap invite in `~/paperclip.creds`. Open that invite to finish the initial admin setup. You can generate a fresh invite later with `cd /opt/paperclip && set -a && source /opt/paperclip/.env && set +a && pnpm paperclipai auth bootstrap-ceo`.", + "type": "info" + }, + { + "text": "If you access Paperclip from a different hostname, update `PAPERCLIP_PUBLIC_URL` in `/opt/paperclip/.env` and restart the `paperclip` service. For authenticated/private hostname access, run `cd /opt/paperclip && set -a && source /opt/paperclip/.env && set +a && pnpm paperclipai allowed-hostname ` after the first startup.", + "type": "info" + }, + { + "text": "If you want to change Paperclip's deployment mode later, run `cd /opt/paperclip && set -a && source /opt/paperclip/.env && set +a && pnpm paperclipai configure --section server`.", + "type": "info" + }, + { + "text": "Codex and Claude Code are preinstalled. Because the Paperclip service runs as root, authenticate them as root inside the container so Paperclip can reuse those credentials.", + "type": "info" + }, + { + "text": "For Codex, run `codex` and choose ChatGPT login for interactive use, or use API-key authentication for more programmatic workflows. Claude Code can be authenticated by running `claude` and using `/login`, or by providing Anthropic API credentials.", + "type": "info" + } + ] +} From d3d2ce78020e8e3a1fe908d96c15c02c7e21fdb9 Mon Sep 17 00:00:00 2001 From: Fabian Pulch Date: Sat, 18 Apr 2026 17:02:12 +0200 Subject: [PATCH 4/6] refactor: address review on Paperclip helper flow --- install/paperclip-install.sh | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/install/paperclip-install.sh b/install/paperclip-install.sh index 1358b98b..d9086965 100644 --- a/install/paperclip-install.sh +++ b/install/paperclip-install.sh @@ -14,7 +14,7 @@ network_check update_os msg_info "Installing Dependencies" -install_packages_with_retry \ +$STD apt install -y \ build-essential \ git \ python3 \ @@ -69,9 +69,11 @@ msg_info "Bootstrapping Paperclip" PAPERCLIP_ONBOARD_LOG=/opt/paperclip/paperclip-onboard.log PAPERCLIP_BOOTSTRAP_LOG=/opt/paperclip/paperclip-bootstrap.log -run_paperclip_onboard() { +for PAPERCLIP_ONBOARD_CMD in \ + "pnpm paperclipai onboard --yes --bind lan" \ + "pnpm paperclipai onboard --yes"; do rm -f "$PAPERCLIP_ONBOARD_LOG" - setsid bash -c "cd /opt/paperclip && $1" >"$PAPERCLIP_ONBOARD_LOG" 2>&1 & + setsid bash -c "cd /opt/paperclip && ${PAPERCLIP_ONBOARD_CMD}" >"$PAPERCLIP_ONBOARD_LOG" 2>&1 & PAPERCLIP_ONBOARD_PID=$! for _ in {1..60}; do if [[ -f /opt/paperclip-data/instances/default/config.json ]]; then @@ -86,13 +88,12 @@ run_paperclip_onboard() { kill -- -"${PAPERCLIP_ONBOARD_PID}" >/dev/null 2>&1 || true wait "$PAPERCLIP_ONBOARD_PID" 2>/dev/null || true fi -} - -run_paperclip_onboard "pnpm paperclipai onboard --yes --bind lan" -if [[ ! -f /opt/paperclip-data/instances/default/config.json ]] && grep -q "unknown option '--bind'" "$PAPERCLIP_ONBOARD_LOG"; then + [[ -f /opt/paperclip-data/instances/default/config.json ]] && break + if ! grep -q "unknown option '--bind'" "$PAPERCLIP_ONBOARD_LOG"; then + break + fi msg_info "Retrying Paperclip Onboarding" - run_paperclip_onboard "pnpm paperclipai onboard --yes" -fi +done if [[ ! -f /opt/paperclip-data/instances/default/config.json ]]; then msg_error "Failed to bootstrap Paperclip" From ddb8b877c6bcc93b1a871e231e3154bfe474d42d Mon Sep 17 00:00:00 2001 From: Fabian Pulch Date: Tue, 21 Apr 2026 17:21:30 +0200 Subject: [PATCH 5/6] chore: use selfh.st icon for Paperclip --- json/paperclip.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/json/paperclip.json b/json/paperclip.json index 8a0068af..cb30f71c 100644 --- a/json/paperclip.json +++ b/json/paperclip.json @@ -11,7 +11,7 @@ "interface_port": 3100, "documentation": "https://docs.paperclip.ing/", "website": "https://paperclip.ing/", - "logo": "https://github.com/paperclipai.png", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/paperclip-ai-light.webp", "description": "Paperclip is an open-source orchestration platform for managing autonomous AI agent teams with goals, routines, governance, and a browser-based control plane.", "install_methods": [ { From 03968d705ddb500c63e707569194ff7cefd92c5d Mon Sep 17 00:00:00 2001 From: Fabian Pulch Date: Tue, 21 Apr 2026 17:29:51 +0200 Subject: [PATCH 6/6] chore: use final selfh.st icon for Paperclip --- json/paperclip.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/json/paperclip.json b/json/paperclip.json index cb30f71c..0ec825a7 100644 --- a/json/paperclip.json +++ b/json/paperclip.json @@ -11,7 +11,7 @@ "interface_port": 3100, "documentation": "https://docs.paperclip.ing/", "website": "https://paperclip.ing/", - "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/paperclip-ai-light.webp", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/paperclip-ai.webp", "description": "Paperclip is an open-source orchestration platform for managing autonomous AI agent teams with goals, routines, governance, and a browser-based control plane.", "install_methods": [ {