Featured

Deploy OpenClaw in 60 seconds — 20% off logoDeploy OpenClaw in 60 seconds — 20% off

Launch OpenClaw on Hostinger in about 60 seconds and keep your agent live 24/7. Our referral link gives you 20% off, no coupon code needed.

Launch on Hostinger
Run your Hermes agent on Hostinger, fully managed logoRun your Hermes agent on Hostinger, fully managed

Launch Hermes on Hostinger in one click, fully managed, no VPS knowledge needed. Use code ZACAARON10 for 10% off.

Launch on Hostinger
Crawl and scrape any site into clean data, 10% off logoCrawl and scrape any site into clean data, 10% off

Firecrawl crawls and scrapes any site into clean markdown for your agent. Get 1,000 free credits, and new users get 10% off their first purchase.

Try Firecrawl free
Your own AI agent, running 24/7 with QwikClaw logoYour own AI agent, running 24/7 with QwikClaw

QwikClaw sets up and runs an always-on OpenClaw agent for you. One click, no config files, no server setup.

Deploy now
One API to scrape, enrich, and extract the internet. logoOne API to scrape, enrich, and extract the internet.

Context.dev gives your agents a single API to scrape, enrich, and extract live web data — no proxies, no parsers, no maintenance.

Start building free
SetupClaw: done-for-you OpenClaw for founders & exec teams logoSetupClaw: done-for-you OpenClaw for founders & exec teams

White-glove OpenClaw for founders and exec teams (4–50+ employees): we install, harden, integrate your tools, and maintain it — secured from day one.

Get it set up for you
SEO data APIs for your agent, $1 free credit logoSEO data APIs for your agent, $1 free credit

DataForSEO gives your agent live access to SERP results, keyword data, backlinks, and on-page SEO data through one API. New accounts get a $1 credit, good for up to 20,000 keyword or backlink lookups.

Try DataForSEO free
Reach 47,000+ AI builders

A flat monthly placement in front of developers actively installing AI tools. No lock-in, cancel anytime.

Advertise here

Summary

Claude Code security monitoring plugin — emits OTLP spans for hook events and fail-closes on missing Pinta identity.

Install to Claude Code

/plugin install pinta-cc@pinta-ai

Run in Claude Code. Add the marketplace first with /plugin marketplace add pinta-ai/pinta-cc if you haven't already.

README.md

pinta-cc — Generic OTLP forwarder for Claude Code hook events

Converts Claude Code hook events into OTLP/HTTP spans and forwards them to any OpenTelemetry-compatible collector. No Pinta CLI dependency. No identity check at plugin time. Vendor-neutral.

Features

  • OTLP transport: converts 11 hook event types into OTLP/HTTP resourceSpans and sends them via POST {endpoint}/traces
  • Bronze flattening: every top-level field of a hook event is flattened into cc.<key> span attributes
  • ULID per-turn traceId: UserPromptSubmit starts a new ULID-based trace; all subsequent hooks in the same turn share it
  • Retry queue: on transport failure, payloads are appended to .plugin-data/failed-spans.jsonl (cap 1000) and flushed on the next hook invocation
  • Vendor-neutral: any OTel-compatible collector works. Pinta Manager auto-configures the endpoint and token
  • Identity at relay: member.identity.* attributes are no longer attached at plugin time. Pinta Manager (or your own pipeline) attaches identity at the forwarding layer

Channels

| Channel | Install path | Auto-update | |---------|-------------|-------------| | Pinta Manager v0.2+ | Manager installs and configures automatically | Yes — on manager reconcile | | Marketplace pinta-cc@pinta-ai | /plugin marketplace add pinta-ai/pinta-cc then /plugin install pinta-cc@pinta-ai | Yes — on Claude Code startup |

Installation

Pinta Manager (recommended for enterprise)

Pinta Manager v0.2+ handles installation and configuration automatically. No manual steps required.

Marketplace

/plugin marketplace add pinta-ai/pinta-cc
/plugin install pinta-cc@pinta-ai

After installation, Claude Code automatically pulls new versions from the marketplace on every startup.

Direct from GitHub

claude plugin install github:pinta-ai/pinta-cc

Local development

git clone https://github.com/pinta-ai/pinta-cc.git
cd pinta-cc
npm install && npm run build
claude --plugin-dir .

Configuration

userConfig (Claude Code plugin settings)

| Setting | Description | Required | |---------|-------------|----------| | endpoint | OTLP/HTTP traces endpoint. Pinta Manager auto-fills. OSS: any OTel collector URL | Yes | | api_key | Token sent as x-pinta-relay-token header. Pinta Manager auto-fills | Conditional |

Pinta Manager scenario

Pinta Manager v0.2+ injects CLAUDE_PLUGIN_OPTION_ENDPOINT and CLAUDE_PLUGIN_OPTION_API_KEY automatically via Claude Code's settings.json. No manual configuration needed.

OSS / direct scenario

Set endpoint to your OTLP collector URL (e.g. http://localhost:4318) and api_key to whatever token your collector expects. The token is sent as x-pinta-relay-token.

For collectors that need a different auth header, set OTEL_EXPORTER_OTLP_HEADERS directly in your environment — this overrides the api_key userConfig:

export OTEL_EXPORTER_OTLP_ENDPOINT=https://collector.example.com
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer <token>"

OTel env var precedence

The plugin reads OTel env vars directly. CLAUDE_PLUGIN_OPTION_ env vars (set by Claude Code from userConfig) are bridged to their OTEL_EXPORTER_OTLP_ equivalents only when the OTel var is not already set. Explicit OTEL_EXPORTER_OTLP_* always win.

| Plugin userConfig | Bridged to | |------------------|-| | CLAUDE_PLUGIN_OPTION_ENDPOINT | OTEL_EXPORTER_OTLP_ENDPOINT | | CLAUDE_PLUGIN_OPTION_API_KEY | OTEL_EXPORTER_OTLP_HEADERS=x-pinta-relay-token=<key> |

Span attribute conventions

Resource attributes

| Attribute | Value | |-----------|-------| | service.name | "claude-code" | | service.version | Claude Code CLI version | | telemetry.sdk.name | "pinta-cc" | | telemetry.sdk.version | Plugin version | | process.pid | Hook process PID | | process.owner | OS username | | host.name | Machine hostname | | host.arch | CPU architecture |

Note: member.identity.* attributes are not attached at plugin time (moved to relay layer).

Span attributes

| Attribute | Value | |-----------|-------| | ingest.type | "cc" (discriminator for aware-backend parser) | | cc.hook | Hook event name (e.g. PreToolUse) | | cc.<key> | All other top-level hook event fields (Bronze flattening) |

Architecture

src/
├── index.ts              # Entry point: env-bridge → stdin parse → handler routing
├── core/
│   ├── env-bridge.ts     # CLAUDE_PLUGIN_OPTION_* → OTEL_EXPORTER_OTLP_* alias
│   ├── types.ts          # Hook event types, type guards, skip-list
│   ├── config.ts         # loadConfig() + hasOtlpEndpoint()
│   ├── otlp.ts           # OTLP payload builder + Bronze flattening + ULID→traceId
│   ├── transport.ts      # POST {endpoint}/traces (5s timeout, reads OTel env at call time)
│   ├── retry-queue.ts    # File-based JSONL queue (cap 1000, 30s stale lock TTL)
│   ├── trace.ts          # traceId management (ULID, file-based sharing)
│   ├── identity.ts       # Empty stub (identity attribution moved to relay)
│   └── redact.ts         # Tier-1 redaction + Tier-3 truncation
└── handlers/
    ├── pre-tool-use.ts   # flush → currentTrace → buildOtlpPayload → send → exit 0
    ├── post-tool-use.ts
    ├── user-prompt.ts    # flush → newTrace → buildOtlpPayload → send → exit 0
    ├── session.ts
    ├── subagent.ts
    ├── stop.ts
    ├── permission.ts
    └── default.ts        # Notification, TaskCreated, TaskCompleted → exit 0 immediately

Event flow

UserPromptSubmit (newTrace() → POST /traces)
  → PreToolUse (currentTrace() → POST /traces)
  → PostToolUse (currentTrace() → POST /traces)
  → ...
UserPromptSubmit (next turn, new traceId)
  → ...

Each hook invocation spawns a fresh Node process. One hook = one OTLP span = one resourceSpans entry. Retry queue flush batches multiple spans into a single body.

Captured events (11)

PreToolUse, PostToolUse, PostToolUseFailure, UserPromptSubmit, SessionStart, SessionEnd, PermissionRequest, PermissionDenied, SubagentStart, SubagentStop, Stop

Skipped events (3, exit 0 immediately)

Notification, TaskCreated, TaskCompleted

Development

npm install
npm run build         # tsc → dist/
npm test              # vitest run
npm run mock-server   # Generic OTLP collector at http://localhost:3000

Local integration test

# Terminal 1: start the mock OTLP collector
npm run mock-server

# Terminal 2: run Claude Code with the plugin
CLAUDE_PLUGIN_OPTION_ENDPOINT=http://localhost:3000 \
CLAUDE_PLUGIN_OPTION_API_KEY=test-token \
claude --plugin-dir .

Open http://localhost:3000 to inspect captured spans.

BREAKING CHANGES from 1.1.x

| What changed | 1.1.x | 1.2.x | Migration | |---|---|---|---| | Pinta CLI dependency | Required (pinta login) | Removed | Nothing; Pinta Manager or direct OTel env | | endpoint meaning | Pinta backend URL | Any OTLP collector URL | Update to your collector's /v1/traces or equivalent | | api_key meaning | Pinta backend API key (x-api-key header) | Relay token (x-pinta-relay-token header) | Pinta Manager: automatic. Standalone: update token | | Identity attributes | member.identity.id/email in resource attrs | Removed | Attach at your collector/forwarder layer | | PreToolUse fail-close | Exit 2 (deny) when identity unresolved | Removed — always exit 0 | No action needed | | src/enterprise/ | Present | Removed | No action needed |

Pinta Manager users: No action required. Manager v0.2 auto-injects config on next reconcile.

Marketplace users: Auto-updated on next Claude Code startup. Update endpoint userConfig to your OTLP collector URL if you manage your own pipeline.

Direct env var users: Replace CLAUDE_PLUGIN_OPTION_API_KEY token semantics and ensure your collector accepts x-pinta-relay-token, or set OTEL_EXPORTER_OTLP_HEADERS=Authorization=Bearer <token> directly.

License

PolyForm Noncommercial 1.0.0 — see LICENSE.

Commercial use is not permitted under this license. Noncommercial use (personal projects, research, educational institutions, nonprofits, government) is allowed. For a commercial license, please contact Pinta AI.

Related plugins

Browse all →