Creating an Adapter
Build a custom adapter to connect Paperclip to any agent runtime.
Package Structure
Section titled “Package Structure”packages/adapters/<name>/ package.json tsconfig.json src/ index.ts # Shared metadata server/ index.ts # Server exports execute.ts # Core execution logic parse.ts # Output parsing test.ts # Environment diagnostics ui/ index.ts # UI exports parse-stdout.ts # Transcript parser build-config.ts # Config builder cli/ index.ts # CLI exports format-event.ts # Terminal formatterStep 1: Root Metadata
Section titled “Step 1: Root Metadata”src/index.ts is imported by all three consumers. Keep it dependency-free.
export const type = "my_agent"; // snake_case, globally uniqueexport const label = "My Agent (local)";export const models = [ { id: "model-a", label: "Model A" },];export const agentConfigurationDoc = `# my_agent configurationUse when: ...Don't use when: ...Core fields: ...`;Step 2: Server Execute
Section titled “Step 2: Server Execute”src/server/execute.ts is the core. It receives an AdapterExecutionContext and returns an AdapterExecutionResult.
Key responsibilities:
- Read config using safe helpers (
asString,asNumber, etc.) - Build environment with
buildPaperclipEnv(agent)plus context vars - Resolve session state from
runtime.sessionParams - Render prompt with
renderTemplate(template, data) - Spawn the process with
runChildProcess()or call viafetch() - Parse output for usage, costs, session state, errors
- Handle unknown session errors (retry fresh, set
clearSession: true)
Step 3: Environment Test
Section titled “Step 3: Environment Test”src/server/test.ts validates the adapter config before running.
Return structured diagnostics:
errorfor invalid/unusable setupwarnfor non-blocking issuesinfofor successful checks
Step 4: UI Module
Section titled “Step 4: UI Module”parse-stdout.ts— converts stdout lines toTranscriptEntry[]for the run viewerbuild-config.ts— converts form values toadapterConfigJSON- Config fields React component in
ui/src/adapters/<name>/config-fields.tsx
Step 5: CLI Module
Section titled “Step 5: CLI Module”format-event.ts — pretty-prints stdout for paperclipai run --watch using picocolors.
Step 6: Register
Section titled “Step 6: Register”Add the adapter to all three registries:
server/src/adapters/registry.tsui/src/adapters/registry.tscli/src/adapters/registry.ts
Skills Injection
Section titled “Skills Injection”Make Paperclip skills discoverable to your agent runtime without writing to the agent’s working directory:
- Best: tmpdir + flag — create tmpdir, symlink skills, pass via CLI flag, clean up after
- Acceptable: global config dir — symlink to the runtime’s global plugins directory
- Acceptable: env var — point a skills path env var at the repo’s
skills/directory - Last resort: prompt injection — include skill content in the prompt template
Security
Section titled “Security”- Treat agent output as untrusted (parse defensively, never execute)
- Inject secrets via environment variables, not prompts
- Configure network access controls if the runtime supports them
- Always enforce timeout and grace period