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

@cdot65/prisma-airs-cursor-hooks

v0.3.0

Published

Cursor IDE hooks integrating Prisma AIRS scanning into the developer workflow

Readme

Prisma AIRS Cursor Hooks

Cursor IDE hooks that scan prompts, tool activity, file reads, and AI responses in real-time using Prisma AI Runtime Security (AIRS). Blocks prompts, shell commands, MCP tool calls, file reads, and subagent spawns before they execute; audits everything else for prompt injections, malicious code, sensitive data leakage, and policy violations. Four core hooks install by default; six more are available opt-in.

Built on the @cdot65/prisma-airs-sdk.

How It Works

Developer prompt → beforeSubmitPrompt hook → AIRS Sync API → allow/block
                                                  ↓
                        Cursor AI Agent (if allowed)
                                                  ↓
               MCP Tool Call → beforeMCPExecution hook → AIRS Sync API (tool_event) → allow/block
                                                  ↓
               Tool Output → postToolUse hook → AIRS Sync API → log/warn (observe-only)
                                                  ↓
AI response → afterAgentResponse hook → code extractor → AIRS Sync API → log/warn (observe-only)

All hooks use Cursor's native hooks.json system. They receive structured JSON on stdin and scan via the AIRS API. Blocking hooks: beforeSubmitPrompt, beforeMCPExecution, plus optional beforeShellExecution, beforeReadFile, beforeTabFileRead, and subagentStart. Observe-only: postToolUse (unless MCP output sanitization is enabled), afterAgentResponse, and optional afterShellExecution / afterMCPExecution (see Cursor Limitation).

Prerequisites

  • Node.js 18+ (native fetch, crypto.randomUUID)
  • Cursor IDE (with hooks support)
  • Prisma AIRS API key and regional endpoint URL
  • AIRS security profile configured in Strata Cloud Manager

Install

npm install -g @cdot65/prisma-airs-cursor-hooks

From source? See the Development section below.

Set Environment Variables

Add to your shell profile (~/.zshrc, ~/.bashrc, etc.):

export PRISMA_AIRS_API_KEY=<your-x-pan-token>
export PRISMA_AIRS_PROFILE_NAME="Cursor IDE - Hooks"                                 # recommended
export PRISMA_AIRS_API_ENDPOINT=https://service.api.aisecurity.paloaltonetworks.com  # optional, defaults to US

Note: Cursor inherits your shell environment, so hooks automatically have access to these variables. Only PRISMA_AIRS_API_KEY is required — endpoint defaults to US and PRISMA_AIRS_PROFILE_NAME defaults to Cursor IDE - Hooks. For per-direction overrides, set PRISMA_AIRS_PROMPT_PROFILE, PRISMA_AIRS_RESPONSE_PROFILE, or PRISMA_AIRS_TOOL_PROFILE.

Available regional endpoints: | Region | Endpoint | |--------|----------| | US (default) | https://service.api.aisecurity.paloaltonetworks.com | | EU | https://service-de.api.aisecurity.paloaltonetworks.com | | India | https://service-in.api.aisecurity.paloaltonetworks.com | | Singapore | https://service-sg.api.aisecurity.paloaltonetworks.com |

Validate Connectivity

prisma-airs-hooks validate-connection
prisma-airs-hooks validate-detection

Register Hooks in Cursor

prisma-airs-hooks install --global

This writes hooks.json registering four hooks pointing at precompiled JS:

  • beforeSubmitPrompt — scans every prompt before it reaches the AI agent (can block)
  • beforeMCPExecution — scans MCP tool inputs before execution via tool_event content type (can block)
  • postToolUse — scans MCP, Shell, Write, and Edit tool outputs for DLP and violations (observe-only)
  • afterAgentResponse — scans every AI response (with code extraction) for audit/logging (observe-only, see limitation)

It also copies airs-config.json to the hooks config directory.

Optional Hooks

Six additional hooks ship opt-in via --optional <names|all>:

prisma-airs-hooks install --global --optional all
# or a subset:
prisma-airs-hooks install --global --optional beforeShellExecution,beforeReadFile

| Hook | Blocks? | Scans | |------|---------|-------| | beforeShellExecution | Yes | Shell command text before execution | | afterShellExecution | No | Terminal output (DLP) after execution | | beforeReadFile | Yes | File contents before the Agent reads them (DLP gate) | | beforeTabFileRead | Yes | File contents before Tab completions read them | | subagentStart | Yes | Subagent task text (injection) before spawn | | afterMCPExecution | No | MCP tool input + result JSON after execution |

There is also a config flag, sanitize_mcp_output (default false): in enforce mode, postToolUse replaces flagged MCP tool output with a redaction notice via Cursor's updated_mcp_tool_output, keeping flagged content out of model context. See the Optional Hooks docs for details.

Restart Cursor

Cursor reads hooks.json at startup. Restart Cursor to activate the hooks.

Verify

prisma-airs-hooks verify

Configuration

Runtime config lives at ~/.cursor/hooks/airs-config.json:

{
  "endpoint": "${PRISMA_AIRS_API_ENDPOINT}",
  "apiKeyEnvVar": "PRISMA_AIRS_API_KEY",
  "profiles": {
    "prompt": "cursor-ide-prompt-profile",
    "response": "cursor-ide-response-profile",
    "tool": "cursor-ide-tool-profile"
  },
  "mode": "observe",
  "timeout_ms": 3000,
  "retry": {
    "enabled": true,
    "max_attempts": 1,
    "backoff_base_ms": 200
  },
  "logging": {
    "path": ".cursor/hooks/airs-scan.log",
    "include_content": false
  },
  "enforcement": {
    "prompt_injection": "block",
    "dlp": "block",
    "malicious_code": "block",
    "url_categorization": "block",
    "toxicity": "block",
    "custom_topic": "block"
  },
  "circuit_breaker": {
    "enabled": true,
    "failure_threshold": 5,
    "cooldown_ms": 60000
  },
  "content_limits": {
    "max_scan_bytes": 51200,
    "truncate_bytes": 20480
  }
}

Modes

| Mode | Behavior | |------|----------| | observe | Log scan results, never block (default — start here) | | enforce | Block prompts that AIRS flags; log and warn on flagged responses (observe-only) | | bypass | Skip scanning entirely |

Enforcement actions

When mode is enforce, each detection service can be configured independently:

| Action | Behavior | |--------|----------| | block | Prevent the prompt/response from passing through | | mask | Log a warning and allow through (DLP masking) | | allow | Log but allow through |

Circuit breaker

After failure_threshold consecutive AIRS API failures, scanning is temporarily bypassed for cooldown_ms milliseconds. A probe request is sent after cooldown — if it succeeds, scanning resumes normally.

CLI Commands

| Command | Description | |---------|-------------| | prisma-airs-hooks install [--global] | Register hooks in Cursor | | prisma-airs-hooks uninstall [--global] | Remove AIRS hooks from Cursor | | prisma-airs-hooks verify | Check hooks registration and env vars | | prisma-airs-hooks validate-connection | Test AIRS API connectivity | | prisma-airs-hooks validate-detection | Verify prompt injection detection | | prisma-airs-hooks stats [--since 7d] [--json] | Show scan statistics | | prisma-airs-hooks logs [--n 10] [--json] | Show recent scan log entries | | prisma-airs-hooks rotate-log | Rotate the scan log now | | prisma-airs-hooks validate-config | Validate the AIRS configuration | | prisma-airs-hooks doctor | Diagnose and repair the installation |

Uninstall

prisma-airs-hooks uninstall --global

Removes AIRS entries from hooks.json while preserving other hooks, config, and logs. Restart Cursor after uninstalling.

Cursor Limitation: Response Scanning is Observe-Only

Cursor's afterAgentResponse hook is observe-only. The AI response streams directly to the user, and the hook fires after it is already visible. There is no beforeAgentResponse or equivalent hook that can intercept the response before display.

The blocking hooks that exist all cover actions, not the response text itself. This project implements every one of them (some as optional hooks):

| Hook | What it gates | In this project | |------|---------------|-----------------| | beforeSubmitPrompt | User prompt → AI | Core | | beforeMCPExecution | MCP tool calls | Core | | beforeShellExecution | Shell commands | Optional | | beforeReadFile | File reads | Optional | | beforeTabFileRead | Tab file reads | Optional | | subagentStart | Sub-agent spawning | Optional |

None of these intercept the AI's natural language or code response before display. This is a gap in Cursor's hook API.

What this means:

  • Prompt scanning (beforeSubmitPrompt) can block. If AIRS detects DLP, injection, or policy violations in the prompt, it is stopped before reaching the AI.
  • Response scanning (afterAgentResponse) can only log and warn. The response is already visible to the developer. Violations are recorded in the audit log and a warning is surfaced in the Hooks output panel, but the content cannot be retracted.

Recommendations:

  • Lean on prompt-side blocking — if AIRS catches sensitive data going in, the AI never sees it to echo back
  • Use response scanning for audit trails, compliance evidence, and security team alerting
  • Request a beforeAgentResponse hook from Cursor via their community forum

Development

For contributors or those who want to run from source:

git clone https://github.com/cdot65/prisma-airs-cursor-hooks.git
cd prisma-airs-cursor-hooks
npm install
npm run build

Development commands

| Command | Description | |---------|-------------| | npm run build | Compile hooks to dist/ | | npm test | Run all tests (66 tests across 9 suites) | | npm run typecheck | TypeScript type checking | | npm run test:watch | Run tests in watch mode | | npm run validate-connection | Test AIRS API connectivity | | npm run validate-detection | Verify prompt injection detection | | npm run install-hooks | Write AIRS entries to .cursor/hooks.json | | npm run install-hooks -- --global | Write AIRS entries to ~/.cursor/hooks.json | | npm run uninstall-hooks -- --global | Remove AIRS entries from global hooks.json | | npm run verify-hooks | Check hooks are installed and env vars set | | npm run stats | Show scan statistics from log file | | npm run logs | Show recent scan log entries | | npm run rotate-log | Rotate the scan log now | | npm run validate-config | Validate the AIRS configuration | | npm run doctor | Diagnose and repair the installation |

Development mode

During development you can run hooks directly from TypeScript source without a build step:

{
  "command": "npx tsx \"/path/to/prisma-airs-cursor-hooks/src/hooks/before-submit-prompt.ts\""
}

This adds ~1.5s per hook invocation compared to compiled JS, so switch back to node dist/... for production use.

Project structure

src/                           TypeScript source
  hooks/
    run-hook.ts                Shared hook harness (stdin/parse/config/fail-open)
    before-submit-prompt.ts    Cursor beforeSubmitPrompt entry point (core)
    before-mcp-execution.ts    Cursor beforeMCPExecution entry point (core)
    post-tool-use.ts           Cursor postToolUse entry point (core, optional MCP sanitization)
    after-agent-response.ts    Cursor afterAgentResponse entry point (core)
    before-shell-execution.ts  Cursor beforeShellExecution entry point (optional)
    after-shell-execution.ts   Cursor afterShellExecution entry point (optional)
    before-read-file.ts        Cursor beforeReadFile entry point (optional)
    before-tab-file-read.ts    Cursor beforeTabFileRead entry point (optional)
    subagent-start.ts          Cursor subagentStart entry point (optional)
    after-mcp-execution.ts     Cursor afterMCPExecution entry point (optional)
  cli.ts                       CLI entry point (prisma-airs-hooks command)
  config.ts                    Config loader (project → global fallback)
  airs-client.ts               executeScan seam: SDK transport + circuit breaker
  scanner.ts                   Scan orchestration, content limits, UX messages
  tool-routing.ts              postToolUse routing (which scan per tool)
  code-extractor.ts            Separates code from natural language
  logger.ts                    JSON Lines logging with rotation
  circuit-breaker.ts           Failure tracking with cooldown bypass
  dlp-masking.ts               Per-service enforcement actions
  log-rotation.ts              Rotate logs at 10MB
  types.ts                     TypeScript interfaces
dist/                          Compiled JS (production hooks point here)
scripts/
  lib/hook-registry.ts         Registry of all hooks (core + optional) driving the scripts below
  install-hooks.ts             Write .cursor/hooks.json (points at dist/, --optional for extras)
  uninstall-hooks.ts           Remove AIRS entries from hooks.json
  verify-hooks.ts              Tamper detection
  validate-connection.ts       Test AIRS connectivity
  validate-detection.ts        Verify detection works
  airs-stats.ts                Scan statistics CLI
test/
  19 test suites, 184 tests (incl. compiled JS integration tests against a mock AIRS server)

License

MIT