How Paperclip AI Loads Skills and Injects Them into Agent Contexts

Paperclip AI discovers skills from the catalog, resolves versioned bundles at runtime, and injects them into agent prompts as JSON metadata while mounting source files into the execution sandbox.

Paperclip AI treats a skill as a reusable TypeScript module that agents invoke during task execution. The platform implements a three-stage pipeline—discovery, runtime loading, and prompt injection—to dynamically load skills and inject them into agent contexts on every heartbeat. This architecture keeps skill definitions declarative while enabling dynamic, version-specific execution.

Skill Discovery and Catalog Registration

When administrators create or install a skill, the skills catalog (@paperclipai/skills-catalog) processes the module to extract its public API and store metadata for runtime retrieval.

Parsing skill.yaml and package.json

The catalog builder (packages/skills-catalog/src/catalog-builder.ts) reads the skill's declarative configuration. It parses skill.yaml and package.json to identify exported functions, parameters, and entry points.

Generating the SkillDescriptor

The builder generates a SkillDescriptor—a JSON object containing the skill's name, description, and function signatures. This descriptor is persisted to the company_skills table in the database, making the skill available for assignment to specific agents and runs.

Runtime Loading During Heartbeat

On every heartbeat, the server resolves which skills the current agent run requires and prepares their execution bundles for immediate injection.

Version Resolution with loadSkillTestRunAssignmentScope

The server-side helper loadSkillTestRunAssignmentScope (defined in server/src/routes/company-skills.ts) validates company permissions and resolves the specific version to load. The function accepts companyId, skillId, and runId parameters. If no version is pinned, it defaults to the latest available version automatically.

Fetching Source Bundles

The function calls the skill loader (packages/adapter-utils/src/skill-loader.ts) to retrieve source files from their storage location—whether local filesystem, GitHub repository, or catalog ZIP. It returns a SkillRuntimeInfo object containing the bundlePath, descriptor, env bindings, and versionId.

// Server-side: Resolve skill for current heartbeat
import { loadSkillTestRunAssignmentScope } from "./company-skills";

async function resolveSkillRuntime(
  companyId: string,
  skillId: string,
  runId: string,
) {
  // Returns SkillRuntimeInfo with bundle and descriptor
  const skillInfo = await loadSkillTestRunAssignmentScope(
    companyId,
    skillId,
    runId,
  );
  return skillInfo; // { bundlePath, descriptor, env, versionId }
}

Prompt Injection and Sandbox Setup

The agent runtime converts the SkillRuntimeInfo into LLM-visible context and prepares the execution environment for safe skill invocation.

Injecting Metadata into Prompts

The sandbox-managed runtime (packages/adapter-utils/src/sandbox-managed-runtime.ts) replaces the {{skillMetadata}} placeholder in the prompt template with a JSON-serialized SkillDescriptor. This allows the LLM to see available function names, parameters, and descriptions according to the runtime specification in doc/spec/agents-runtime.md.

Mounting Skills into the Sandbox

The injectSkillBundle function copies the skill's source files from bundlePath into the sandbox directory. This enables the agent to dynamically import and execute the skill code when the model decides to invoke it.

// Runtime-side: Inject into prompt and sandbox
import { injectSkillBundle } from "./sandbox-managed-runtime";

async function prepareAgentContext(
  baseTemplate: string,
  skillInfo: SkillRuntimeInfo,
) {
  // Replace placeholder with skill API description
  const prompt = baseTemplate.replace(
    "{{skillMetadata}}",
    JSON.stringify(skillInfo.descriptor),
  );

  // Mount source files for execution
  await injectSkillBundle(skillInfo.bundlePath);
  return prompt;
}

SkillDescriptor Structure

The injected metadata follows a standardized schema that describes the skill's public interface:

{
  "name": "review",
  "description": "Automated code-review helper",
  "functions": [
    {
      "name": "suggestChanges",
      "parameters": {
        "type": "object",
        "properties": {
          "diff": { "type": "string" }
        },
        "required": ["diff"]
      }
    }
  ]
}

Summary

Frequently Asked Questions

What file format defines a Paperclip AI skill?

Skills are defined by a skill.yaml file that declares the module's public API, alongside a standard package.json for dependency management. The catalog builder parses both files to generate the SkillDescriptor stored in the database.

How does Paperclip AI handle skill versioning?

The loadSkillTestRunAssignmentScope function checks for pinned versions in the run configuration. If none is specified, it automatically resolves to the latest version available in the catalog, ensuring agents use the most current skill iterations while supporting explicit version locking when needed.

Where are skill files stored during agent execution?

The injectSkillBundle function copies source files into the execution sandbox directory managed by packages/adapter-utils/src/sandbox-managed-runtime.ts. This sandboxed approach isolates skill code while making it available for dynamic import during the agent's runtime session.

Can skills be loaded from external repositories?

Yes. The skill loader supports multiple storage backends including local filesystem paths, GitHub repositories, and catalog ZIP bundles. The system resolves the appropriate source based on the skill's registration configuration in the skills catalog, allowing teams to distribute skills via version control or the centralized catalog.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →