Skip to main content

Policy framework for Claude Code and Cursor hooks

Project description

AI Agent Policies

Policies turn your Cursor Rules or CLAUDE.md into hard guardrails which an AI Agent cannot simply ignore, or forget. They handle what to do when an agent wants to make a decision, along with other hooks-supported events. Policies can yield both decisions and guidance.

This framework supports Claude Code. Support for Cursor is in beta.

Why Policies

Policies are significantly stronger than rules. Rule files can be forgotten or ignored completely, whereas policies are unavoidable:

def rudimentary_terraform_rule(input_data: ToolUseEvent):
    if not input_data.tool_is_bash:
        return

    command = input_data.command.strip()

    if re.match(r'^terraform\s+apply(?:\s|$)', command):
        yield PolicyDecision(action=PolicyAction.DENY, reason="terraform apply is not allowed. Use `terraform plan` instead.")

    if re.match(r'^terraform\s+(fmt|plan)(?:\s|$)', command):
        yield PolicyDecision(action=PolicyAction.ALLOW)

Aside from denying and allowing automatically, policies can also provide guidance when it seems agents are going off track or missing standards:

def rudimentary_guidance_for_python(input_data: ToolUseEvent):
    if not input_data.tool_is_bash:
        return

    if re.match(r'^python\s+test_', input_data.command):
        yield PolicyGuidance(content="Consider using pytest instead of running test files directly")

Be aware that tool use with bash can contain control operators and separators, moreover, some commands allow execution of others: Consider for example find with -exec. Be careful what you whitelist, and how you parse Bash. At DevLeaps we also have an internal policy set, which is not included in this project. To create your own, refer to the example server which contains a rudimentary bash middleware to demonstrate what is possible with the framework.

Examples

Real World Examples

Policies can prevent Bash dangerous bash commands completely:

Policies can provide guidance to agents when they go off track:

Policies can automatically allow safe commands without interrupting developers:

Usage

Have a look at the example server as a starting point!

It contains:

  • A complete example server with policies and middleware.
  • Rudimentary policies on how to automatically deny, allow and provide guidance.
  • Rudimentary middleware demonstrating how multi-command tool use could be handled.

To run the example server:

devleaps-policy-example-server

This starts a minimal server with just these example policies.

Architecture

graph TB
    subgraph "Developer Machine"
      Editor[Claude Code / Cursor]
        Client[devleaps-policy-client]
    end

    subgraph "Policy Server"
        Server[HTTP API]
        Policies[Your policies<br/>kubectl, terraform, git, python, etc.]
    end

    Editor -->|Hooks| Client
    Client --> Server
    Server -->|Events| Policies
    Policies -->|Decision and Guidance| Server
    Server --> Client
    Client -->|Decision and Guidance| Editor

Quick Start

Installation

Update your local profile with;

# Add the bin directory to $PATH
export PATH="$PATH:/path/to/agent-policies/bin/"

Running an Example Server

devleaps-policy-example-server

The example server runs on port 8338 by default and serves endpoints for both Claude Code and Cursor.

Configure Claude Code

Add devleaps-policy-client to your Claude Code hooks configuration in ~/.claude/settings.json:

Click to expand Claude Code configuration
{
  "hooks": {
    "PreToolUse": [
      {
        "hooks": [
          {
            "matcher": "*",
            "type": "command",
            "command": "devleaps-policy-client claude-code"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "hooks": [
          {
            "matcher": "*",
            "type": "command",
            "command": "devleaps-policy-client claude-code"
          }
        ]
      }
    ],
    "UserPromptSubmit": [
      {
        "hooks": [
          {
            "matcher": "*",
            "type": "command",
            "command": "devleaps-policy-client claude-code"
          }
        ]
      }
    ],
    "Stop": [
      {
        "hooks": [
          {
            "matcher": "*",
            "type": "command",
            "command": "devleaps-policy-client claude-code"
          }
        ]
      }
    ],
    "SubagentStop": [
      {
        "hooks": [
          {
            "matcher": "*",
            "type": "command",
            "command": "devleaps-policy-client claude-code"
          }
        ]
      }
    ],
    "Notification": [
      {
        "hooks": [
          {
            "matcher": "*",
            "type": "command",
            "command": "devleaps-policy-client claude-code"
          }
        ]
      }
    ],
    "PreCompact": [
      {
        "hooks": [
          {
            "matcher": "*",
            "type": "command",
            "command": "devleaps-policy-client claude-code"
          }
        ]
      }
    ],
    "SessionStart": [
      {
        "hooks": [
          {
            "matcher": "*",
            "type": "command",
            "command": "devleaps-policy-client claude-code"
          }
        ]
      }
    ],
    "SessionEnd": [
      {
        "hooks": [
          {
            "matcher": "*",
            "type": "command",
            "command": "devleaps-policy-client claude-code"
          }
        ]
      }
    ]
  }
}

Configure Cursor

Create or edit ~/.cursor/hooks.json:

Click to expand Cursor configuration
{
  "version": 1,
  "hooks": {
    "beforeShellExecution": [
      { "command": "devleaps-policy-client cursor" }
    ],
    "beforeMCPExecution": [
      { "command": "devleaps-policy-client cursor" }
    ],
    "afterFileEdit": [
      { "command": "devleaps-policy-client cursor" }
    ],
    "beforeReadFile": [
      { "command": "devleaps-policy-client cursor" }
    ],
    "beforeSubmitPrompt": [
      { "command": "devleaps-policy-client cursor" }
    ],
    "stop": [
      { "command": "devleaps-policy-client cursor" }
    ]
  }
}

The devleaps-policy-client cursor command will forward hook events to the policy server running on localhost:8338.

Development

This project is built with uv.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

devleaps_agent_policies-1.0.0.tar.gz (44.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

devleaps_agent_policies-1.0.0-py3-none-any.whl (32.0 kB view details)

Uploaded Python 3

File details

Details for the file devleaps_agent_policies-1.0.0.tar.gz.

File metadata

File hashes

Hashes for devleaps_agent_policies-1.0.0.tar.gz
Algorithm Hash digest
SHA256 755ea91c41477c063e00feb21e526d851d39ace7484f2ce67b8f8291b10ad5f3
MD5 17d9348f903df88e34111739e35325d7
BLAKE2b-256 f4a7302a6e7ae7d84cf142510444586f20653bf26010a06f892e879ff33dee69

See more details on using hashes here.

File details

Details for the file devleaps_agent_policies-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for devleaps_agent_policies-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ad2e9acd8e061a88d7c6b5f3c6cf6a5a85d99e797a83af571106d363b8c88e85
MD5 93a1b111fd07a92b5bb473f9a6c5161b
BLAKE2b-256 bddcdc59347c5e9c3be79e534939fe6e3615c6a77b6f0e1adcb899785f739bae

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page