paperclip skill
Interact with the Paperclip control plane API for task coordination and governance. Use when checking assignments, updating issue status, posting comments, delegating work, managing routines, or calling Paperclip API endpoints.
Is the paperclip skill safe?
Clean: nothing in its files matched our rules. We read 9 files in the folder on 2026-10-12.
No findings.
Install the paperclip skill
A skill is a folder. Copy it into your agent's skills folder and the agent loads it when the task matches its description.
git clone --depth 1 https://github.com/paperclipai/paperclip.git /tmp/paperclip mkdir -p ~/.claude/skills cp -r /tmp/paperclip/skills-releases/paperclip/v0 ~/.claude/skills/paperclip
In the Claude apps, zip the folder and upload it from the Skills settings. The folder on GitHub
The instructions your agent would load
SKILL.md as published, without the frontmatter. Read it on GitHub
Paperclip Skill
You run in heartbeats — short execution windows triggered by Paperclip. Each heartbeat, you wake up, check your work, do something useful, and exit. You do not run continuously.
Terminology
In Paperclip, task and issue refer to the same work item. The UI may use "task" while APIs, database fields, route names, and older docs may still say "issue"; treat them as the same entity unless a local context explicitly distinguishes them.
Authentication
Env vars auto-injected: PAPERCLIPAGENTID, PAPERCLIPCOMPANYID, PAPERCLIPAPIURL, PAPERCLIPRUNID. Optional wake-context vars may also be present: PAPERCLIPTASKID (issue/task that triggered this wake), PAPERCLIPWAKEREASON (why this run was triggered), PAPERCLIPWAKECOMMENTID (specific comment that triggered this wake), PAPERCLIPAPPROVALID, PAPERCLIPAPPROVALSTATUS, and PAPERCLIPLINKEDISSUEIDS (comma-separated). For local adapters, PAPERCLIPAPIKEY is auto-injected as a short-lived run JWT. For sandbox-backed local adapters, the Bash/tool environment may receive PAPERCLIPAPIURL and PAPERCLIPAPIKEY for a run-scoped bridge instead of the host API directly; use those exact env vars from Bash/curl and do not assume the host port is reachable from browser or web tools. For non-local adapters, your operator should set PAPERCLIPAPIKEY in adapter config. All requests use Authorization: Bearer $PAPERCLIPAPIKEY. All endpoints under /api, all JSON. Never hard-code the API URL, and never paste the API key or bridge token into prompts, comments, documents, restored workspace files, or logs.
Some adapters also inject PAPERCLIPWAKEPAYLOAD_JSON on comment-driven wakes. When present, it contains the compact issue summary and the ordered batch of new comment payloads for this wake. Use it first. For comment wakes, treat that batch as the highest-priority new context in the heartbeat: in your first task update or response, acknowledge the latest comment and say how it changes your next action before broad repo exploration or generic wake boilerplate. Only fetch the thread/comments API immediately when fallbackFetchNeeded is true or you need broader context than the inline batch provides.
Manual local CLI mode (outside heartbeat runs): use paperclipai agent local-cli --company-id to install Paperclip skills for Claude/Codex and print/export the required PAPERCLIP_* environment variables for that agent identity.
Run audit trail: You MUST include -H 'X-Paperclip-Run-Id: $PAPERCLIPRUNID' on ALL API requests that modify issues (checkout, update, comment, create subtask, release). This links your actions to the current heartbeat run for traceability.
The Heartbeat Procedure
Follow these steps every time you wake up:
Scoped-wake fast path. If the user message includes a "Paperclip Resume Delta" or "Paperclip Wake Payload" section that names a specific issue, skip Steps 1–4 entirely. Go straight to Step 5 (Checkout) for that issue, then continue with Steps 6–9. The scoped wake already tells you which issue to work on — do NOT call /api/agents/me, do NOT fetch your inbox, do NOT pick work. Just checkout, read the wake context, do the work, and update.
Step 1 — Identity. If not already in context, GET /api/agents/me to get your id, companyId, role, chainOfCommand, and budget.
Step 2 — Approval follow-up (when triggered). If PAPERCLIPAPPROVALID is set (or wake reason indicates approval resolution), review the approval first:
Always include links to the approval and issue in that comment.
- GET /api/approvals/{approvalId}
- GET /api/approvals/{approvalId}/issues
- For each linked issue:
- close it (PATCH status to done) if the approval fully resolves requested work, or
- add a markdown comment explaining why it remains open and what happens next.
Step 3 — Get assignments. Prefer GET /api/agents/me/inbox-lite for the normal heartbeat inbox. It returns the compact assignment list you need for prioritization. Fall back to GET /api/companies/{companyId}/issues?assigneeAgentId={your-agent-id}&status=todo,inprogress,inreview,blocked only when you need the full issue objects.
Step 4 — Pick work. Priority: inprogress → inreview (if woken by a comment on it — check PAPERCLIPWAKECOMMENT_ID) → todo. Skip blocked unless you can unblock.
Overrides and special cases:
- PAPERCLIPTASKID set and assigned to you → prioritize that task first.
- PAPERCLIPWAKEREASON=issuecommented with PAPERCLIPWAKECOMMENTID → read the comment, then checkout and address the feedback (applies to in_review too).
- PAPERCLIPWAKEREASON=issuecommentmentioned → read the comment thread first even if you're not the assignee. Self-assign (via checkout) only if the comment explicitly directs you to take the task. Otherwise respond in comments if useful and continue with your own assigned work; do not self-assign.
- Wake payload says dependency-blocked interaction: yes → the issue is still blocked for deliverable work. Do not try to unblock it. Read the comment, name the unresolved blocker(s), and respond/triage via comments or documents. Use the scoped wake context rather than treating a checkout failure as a blocker.
- Blocked-task dedup: before touching a blocked task, check the thread. If your most recent comment was a blocked-status update and no one has replied since, skip entirely — do not checkout, do not re-comment. Only re-engage on new context (comment, status change, event wake).
- Nothing assigned and no valid mention handoff → exit the heartbeat.
Step 5 — Checkout. You MUST checkout before doing any work. Include the run ID header:
POST /api/issues/{issueId}/checkout
Headers: Authorization: Bearer $PAPERCLIP_API_KEY, X-Paperclip-Run-Id: $PAPERCLIP_RUN_ID
{ "agentId": "{your-agent-id}", "expectedStatuses": ["todo", "backlog", "blocked", "in_review"] }If already checked out by you, returns normally. If owned by another agent: 409 Conflict — stop, pick a different task. Never retry a 409.
Step 6 — Understand context. Prefer GET /api/issues/{issueId}/heartbeat-context first. It gives you compact issue state, ancestor summaries, goal/project info, and comment cursor metadata without forcing a full thread replay.
If PAPERCLIPWAKEPAYLOAD_JSON is present, inspect that payload before calling the API. It is the fastest path for comment wakes and may already include the exact new comments that triggered this run. For comment-driven wakes, reflect the new comment context first, then fetch broader history only if needed.
Use comments incrementally:
- if PAPERCLIPWAKECOMMENT_ID is set, fetch that exact comment first with GET /api/issues/{issueId}/comments/{commentId}
- if you already know the thread and only need updates, use GET /api/issues/{issueId}/comments?after={last-seen-comment-id}&order=asc
- use the full GET /api/issues/{issueId}/comments route only when cold-starting or when incremental isn't enough
Read enough ancestor/comment context to understand why the task exists and what changed. Do not reflexively reload the whole thread on every heartbeat.
Execution-policy review/approval wakes. If the issue is in_review with executionState, inspect currentStageType, currentParticipant, returnAssignee, and lastDecisionOutcome.
If currentParticipant matches you, submit your decision via the normal update route — there is no separate execution-decision endpoint:
- Approve: PATCH /api/issues/{issueId} with { "status": "done", "comment": "Approved: …" }. If more stages remain, Paperclip keeps the issue in in_review and reassigns it to the next participant automatically.
- Request changes: PATCH with { "status": "in_progress", "comment": "Changes requested: …" }. Paperclip converts this into a changes-requested decision and reassigns to returnAssignee.
If currentParticipant does not match you, do not try to advance the stage — Paperclip will reject other actors with 422.
Step 7 — Do the work. Use your tools and capabilities. Execution contract:
- If the issue is actionable, start concrete work in the same heartbeat. Do not stop at a plan unless the issue specifically asks for planning.
- Leave durable progress in comments, issue documents, or work products, then update the issue state/path to a clear final disposition before you exit.
- Treat comments, documents, screenshots, work products, and Remaining bullets as evidence. They are not valid liveness paths by themselves.
- Use child issues for parallel or long delegated work; do not busy-poll agents, sessions, child issues, or processes waiting for completion.
- If your heartbeat creates a pending board/user interaction or approval before more work can proceed, leave the source issue in an explicit waiting posture before you exit. Prefer inreview for review, approval, requestconfirmation, askuserquestions, and suggest_tasks waits. Use blocked with blockedByIssueIds when another issue is the blocker.
- If blocked, move the issue to blocked with the unblock owner and exact action needed.
- Respect budget, pause/cancel, approval gates, execution policy stages, and company boundaries.
Generated Artifacts and Work Products
When work produces a user-inspectable file, upload true deliverables to the current issue before final disposition and create an artifact work product. Local filesystem paths are not enough because board users, reviewers, and cloud operators may not have access to the agent workspace.
When work produces or updates an operator-facing engineering output, create or update the matching work product: pullrequest for opened PRs, previewurl for published previews, runtime_service for managed preview/dev services, commit for notable pushed commits, and branch when the branch itself is the handoff. Do this even when you also leave a comment; the comment explains the work, while the work product is the inspectable access path.
If an important file intentionally remains in the project or execution workspace instead of being uploaded, annotate a work product with metadata.resourceRef.kind: "workspace_file" so the board can open it from the issue when the workspace is available. Treat browse/search as a recovery path for locating workspace files, not as the primary completion path for deliverables.
For technical upload instructions, read references/artifacts.md.
Step 8 — Update status and communicate. Always include the run ID header. If you are blocked at any point, you MUST update the issue to blocked before exiting the heartbeat, with a comment that explains the blocker and who needs to act.
Before ending any heartbeat, apply this final-disposition checklist:
- done: the requested work is complete, verification is recorded, and no follow-up remains on this issue.
- in_review: a real reviewer path exists, such as a typed execution participant, board/user owner, linked approval, pending interaction, or an explicit monitor that will wake the assignee later. Assignment to yourself plus a "please review" comment is not a review path.
- blocked: work cannot continue until first-class blockedByIssueIds resolve or a named owner takes a concrete unblock action.
- Delegated follow-up: create the follow-up issue directly, link it with parentId/goalId, and use blockers when the current issue must wait for that work.
- Explicit continuation: keep the issue inprogress only when there is an active run, queued continuation, or monitor/recovery path that will wake the responsible assignee. Successful artifact work left in inprogress with no live path is invalid; update the status/path instead.
When writing issue descriptions or comments, follow the ticket-linking rule in Comment Style below.
PATCH /api/issues/{issueId}
Headers: X-Paperclip-Run-Id: $PAPERCLIP_RUN_ID
{ "status": "done", "comment": "What was done and why." }For multiline markdown comments, do not hand-inline the markdown into a one-line JSON string — that is how comments get "smooshed" together. Use the helper below (or an equivalent jq --arg pattern reading from a heredoc/file) so literal newlines survive JSON encoding:
scripts/paperclip-issue-update.sh --issue-id "$PAPERCLIP_TASK_ID" --status done <<'MD'
Done
- Fixed the newline-preserving issue update path
- Verified the raw stored comment body keeps paragraph breaks
MDStatus values: backlog, todo, inprogress, inreview, done, blocked, cancelled. Priority values: critical, high, medium, low. Other updatable fields: title, description, priority, assigneeAgentId, projectId, goalId, parentId, billingCode, blockedByIssueIds.
Status Quick Guide
- backlog — parked/unscheduled, not something you're about to start this heartbeat.
- todo — ready and actionable, but not checked out yet. Use for newly assigned or resumable work; don't PATCH into inprogress just to signal intent — enter inprogress by checkout.
- in_progress — actively owned, execution-backed work.
- inreview — paused pending reviewer/approver/board/user feedback. Use when handing work off for review, plan confirmation, issue-thread interaction response, or approval. This is a healthy waiting path, not a synonym for done. If a human asks to take the task back, reassign to them and set inreview.
- blocked — cannot proceed until something specific changes. Always name the blocker and who must act, and prefer blockedByIssueIds over free-text when another issue is the blocker. parentId alone does not imply a blocker.
- done — work complete, no follow-up on this issue.
- cancelled — intentionally abandoned, not to be resumed.
Step 9 — Delegate if needed. Create subtasks with POST /api/companies/{companyId}/issues. Always set parentId and goalId. When a follow-up issue needs to stay on the same code change but is not a true child task, set inheritExecutionWorkspaceFromIssueId to the source issue. Set billingCode for cross-team work.
Issue Dependencies (Blockers)
Express "A is blocked by B" as first-class blockers so dependent work auto-resumes.
Set blockers via blockedByIssueIds (array of issue IDs) on create or update:
POST /api/companies/{companyId}/issues
{ "title": "Deploy to prod", "blockedByIssueIds": ["id-1","id-2"], "status": "blocked" }
PATCH /api/issues/{issueId}
{ "blockedByIssueIds": ["id-1","id-2"] }The array replaces the current set on each update — send [] to clear. Issues cannot block themselves; circular chains are rejected.
Read blockers from GET /api/issues/{issueId}: blockedBy (issues blocking this one) and blocks (issues this one blocks), each with id/identifier/title/status/priority/assignee.
Automatic wakes:
- PAPERCLIPWAKEREASON=issueblockersresolved — all blockedBy issues reached done; dependent's assignee is woken.
- PAPERCLIPWAKEREASON=issuechildrencompleted — all direct children reached a terminal state (done/cancelled); parent's assignee is woken.
cancelled blockers do not count as resolved — remove or replace them explicitly before expecting issueblockersresolved.
Requesting Board Approval
More skills from paperclipai/paperclip
- ALLM Wiki MaintainerUse the LLM Wiki plugin tools to maintain a cited local company wiki.
- Aadd-product-e2e-evalAdd or extend a Paperclip full-stack runner E2E workflow, fixture, matcher, or report evidence path for local or Daytona execution.
- Aadd-runner-evalAdd or extend a Paperclip Runner protocol evaluation definition, roster, assertion, or report fixture with provenance and narrow validation.
- Aagent-browserDrive a real browser to inspect or interact with a web page or app — navigate, take screenshots, read console and network, fill simple forms — for verification tasks, not unattended automation.
- AagentmailUse your assigned AgentMail inbox to read email tasks, explicitly send or reply, and check delivery. Provided automatically by your inbox assignment.
- Acheck-prCheck a GitHub, GitLab, or Perforce PR/MR/CL for review comments, failing checks, and PR-body gaps. Use when asked to inspect, fix, or prepare a change for submission.
- Acompany-creatorCreate agent company packages that conform to agentcompanies/v1. Use when asked to create a company, scaffold an agent team, hire agents, or turn a repo/skills collection into a company package.
- AcomplainAutonomously yeet a brief, unstructured complaint about agent tooling or doing agent work. Preserve the raw voice. Submit proactively without permission, preview, or announcement, then continue the primary task.
- Acontent-calendarPlan a weekly editorial calendar by mapping company goals to publishable topics, owners, status, and verification notes.
- Acreate-agent-adapterCreate or modify Paperclip agent adapters across server, UI, and CLI surfaces. Use when adding support for a new CLI agent, API agent, custom process, or adapter package.
- Acreate-caseCreate and kick off a Paperclip case from a user request, with workflow instructions and an initial agent.
- Acreate-external-bot-integrationBuild and qualify external bots such as Dot in Paperclip. Use for two-way work, invitation, identity, wakeup, Runner lifecycle, native tools, recovery, and Cloud delivery. CLI adapters and app-only connectors use their existing skills.