npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@farhoodliquor/paperclip-adapter-hermes-k8s

v0.4.2

Published

Paperclip adapter plugin that runs Hermes agents as Kubernetes Jobs or as perpetual gateway deployments

Readme

@farhoodliquor/paperclip-adapter-hermes-k8s

Paperclip adapter that runs Hermes agents as isolated Kubernetes Jobs instead of inside the main Paperclip process.

Features

  • Spawns agent runs as K8s Jobs with full pod isolation
  • Inherits container image, secrets, DNS, and PVC from the Paperclip Deployment automatically
  • Real-time log streaming from Job pods back to the Paperclip UI
  • Session resume via shared RWX PVC
  • Per-agent concurrency guard
  • Configurable resources, namespace, node selectors, tolerations
  • Multi-model support (Claude, OpenAI, Gemini, etc.)

Requirements

ReadWriteMany (RWX) PersistentVolumeClaim

This is the most important requirement. Paperclip must be deployed with a PVC that supports ReadWriteMany access mode, mounted at /paperclip on the Paperclip Deployment. The adapter automatically discovers this PVC from the running pod and re-mounts it into every agent Job pod at the same path.

The RWX access mode is required because the Paperclip Deployment pod and agent Job pods run concurrently on potentially different nodes, all reading and writing to the same volume. Common storage backends that support RWX include:

  • EFS (AWS) via the EFS CSI driver
  • Filestore (GCP) via the Filestore CSI driver
  • Azure Files (Azure) via the Azure File CSI driver
  • NFS provisioners (on-prem)
  • Longhorn with NFS export

Example PVC:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: paperclip-data
  namespace: paperclip
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 50Gi
  storageClassName: efs-sc   # adjust to your cluster's RWX-capable StorageClass

Kubernetes RBAC

The Paperclip Deployment's service account needs permissions to create and manage Jobs, list Pods, and stream logs. The adapter also runs a health check on startup that performs a self-subject access review and verifies the PVC and namespace exist.

Below is a complete RBAC example using deployment paperclip in namespace paperclip:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: paperclip
  namespace: paperclip
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: paperclip-adapter
  namespace: paperclip
rules:
  # Core: create and manage agent Jobs
  - apiGroups: ["batch"]
    resources: ["jobs"]
    verbs: ["create", "get", "list", "delete"]

  # Core: find Job pods and read their status/exit codes
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list"]

  # Core: stream real-time logs from agent containers
  - apiGroups: [""]
    resources: ["pods/log"]
    verbs: ["get"]

  # Health check: verify PVC exists and is RWX
  - apiGroups: [""]
    resources: ["persistentvolumeclaims"]
    verbs: ["get"]

  # Health check: verify provider API key secret exists
  - apiGroups: [""]
    resources: ["secrets"]
    verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: paperclip-adapter
  namespace: paperclip
subjects:
  - kind: ServiceAccount
    name: paperclip
    namespace: paperclip
roleRef:
  kind: Role
  name: paperclip-adapter
  apiGroup: rbac.authorization.k8s.io

If the adapter needs to create Jobs in a different namespace than the one Paperclip runs in (via the namespace config option), you will also need a ClusterRole or an additional Role/RoleBinding in that target namespace, plus permission to read namespace objects:

# Only required when running Jobs in a different namespace
- apiGroups: [""]
  resources: ["namespaces"]
  verbs: ["get"]

The adapter also uses SelfSubjectAccessReview during health checks to verify its own RBAC permissions. This is typically allowed by default for all authenticated service accounts and does not require an explicit rule.

API Key Secret

The adapter expects a Kubernetes Secret (default name: paperclip-secrets) in the same namespace, containing the API keys for your chosen AI provider:

apiVersion: v1
kind: Secret
metadata:
  name: paperclip-secrets
  namespace: paperclip
type: Opaque
stringData:
  ANTHROPIC_API_KEY: "sk-ant-..."
  # or for AWS Bedrock:
  # AWS_BEARER_TOKEN_BEDROCK: "..."
  # or for other providers:
  # OPENAI_API_KEY: "sk-..."
  # GOOGLE_GENERATIVE_AI_API_KEY: "..."

Mount this secret as a volume on the Paperclip Deployment; the adapter automatically propagates all secret-backed volumes to agent Job pods.

Paperclip Deployment Example

A minimal Deployment spec showing the required volume mounts:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: paperclip
  namespace: paperclip
spec:
  replicas: 1
  selector:
    matchLabels:
      app: paperclip
  template:
    metadata:
      labels:
        app: paperclip
    spec:
      serviceAccountName: paperclip
      containers:
        - name: paperclip
          image: your-registry/paperclip:latest
          volumeMounts:
            - name: data
              mountPath: /paperclip
            - name: secrets
              mountPath: /etc/paperclip/secrets
              readOnly: true
          env:
            - name: ANTHROPIC_API_KEY
              valueFrom:
                secretKeyRef:
                  name: paperclip-secrets
                  key: ANTHROPIC_API_KEY
      volumes:
        - name: data
          persistentVolumeClaim:
            claimName: paperclip-data
        - name: secrets
          secret:
            secretName: paperclip-secrets

Software Dependencies

  • @paperclipai/adapter-utils >= 0.3.0
  • Kubernetes cluster v1.21+

Installation

Via Paperclip Adapter Manager

curl -X POST http://localhost:3100/api/adapters \
  -H "Content-Type: application/json" \
  -d '{"packageName": "@farhoodliquor/paperclip-adapter-hermes-k8s"}'

Local Development

curl -X POST http://localhost:3100/api/adapters \
  -H "Content-Type: application/json" \
  -d '{"localPath": "/path/to/paperclip-adapter-hermes-k8s"}'

Configuration

All fields are configurable per-agent in the Paperclip UI or via the agent config API.

Core

| Field | Type | Required | Description | |-------|------|----------|-------------| | model | string | yes | Hermes model in provider/model format (e.g. anthropic/claude-sonnet-4-6) | | provider | string | no | AI provider (anthropic, openai, google, openrouter, nous). Auto-detected from model name if omitted | | variant | string | no | Provider-specific reasoning variant | | promptTemplate | string | no | Prompt template with {{agent.id}}, {{runId}}, etc. | | bootstrapPromptTemplate | string | no | First-run prompt template (used only when no existing session) | | extraArgs | string | no | Additional CLI args appended to the hermes run command | | env | JSON | no | Environment variable overrides as {"KEY": "VALUE"} pairs | | dangerouslySkipPermissions | bool | no | Inject runtime config with permission.external_directory=allow (default: true) |

Kubernetes

| Field | Type | Default | Description | |-------|------|---------|-------------| | namespace | string | auto-detected | K8s namespace for agent Jobs | | image | string | Deployment image | Override container image for Job pods | | imagePullPolicy | string | IfNotPresent | IfNotPresent, Always, or Never | | serviceAccountName | string | namespace default | Service account for Job pods | | kubeconfig | string | in-cluster | Path to kubeconfig file | | cwd | string | /paperclip | Working directory inside the container | | resources | JSON | see below | CPU/memory requests and limits | | nodeSelector | JSON | — | Node selector labels | | tolerations | JSON | — | Pod tolerations | | labels | JSON | — | Extra labels applied to Job and Pod | | ttlSecondsAfterFinished | number | 300 | Seconds to retain completed Jobs | | retainJobs | bool | false | Keep completed Jobs for debugging |

Default resource allocation for agent Job containers:

resources:
  requests:
    cpu: "1000m"
    memory: "2Gi"
  limits:
    cpu: "4000m"
    memory: "8Gi"

Operational

| Field | Type | Default | Description | |-------|------|---------|-------------| | timeoutSec | number | 0 | Run timeout in seconds (0 = no timeout) | | graceSec | number | 60 | Grace period in seconds before force-killing |

Security

Agent Job pods run with a hardened security context:

  • runAsNonRoot: true (UID 1000, GID 1000)
  • All Linux capabilities dropped
  • Privilege escalation disabled
  • Secret volumes mounted read-only

License

MIT