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

@limits/openclaw

v0.0.11

Published

Delegates policy enforcement to the Limits platform before and after every tool call.

Readme

@limits/openclaw

npm version License: MIT TypeScript Node.js GitHub

Official OpenClaw plugin for the Limits platform. Delegates policy enforcement via HTTP. Every decision is made by calling POST {baseUrl}/openclaw/enforce before and after each tool call. Optional policy-generator tools let the agent create and update policies from natural language.


Table of Contents


Installation

npm install @limits/openclaw
yarn add @limits/openclaw
pnpm add @limits/openclaw

Then register the plugin with OpenClaw:

openclaw plugins install ./node_modules/@limits/openclaw
openclaw gateway restart
openclaw plugins enable "@limits/openclaw"

Quick Start

  1. Install the plugin (see Installation).
  2. Configure your API token (required for enforcement and policy-generator tools):
openclaw limits configure

If you see error: unknown command 'limits', the OpenClaw CLI may not load plugin commands in your environment. Run the configure script directly (from a directory where the package is installed):

node node_modules/@limits/openclaw/scripts/configure.js

Or set config manually:

{
  "plugins": {
    "entries": {
      "@limits/openclaw": {
        "enabled": true,
        "config": {
          "apiToken": "sk_your_organization_api_key"
        }
      }
    }
  }
}
  1. Allow the plugin in your agent's tool list so the agent can use policy-generator tools (optional). Edit ~/.openclaw/openclaw.json:
{
  "agents": {
    "list": [
      {
        "id": "main",
        "tools": { "allow": ["@limits/openclaw"] }
      }
    ]
  }
}
  1. Run your agent. Before and after each tool call, the plugin calls the Limits backend. No code changes required.

How it works

flowchart LR
  subgraph pre [Before tool call]
    A[Tool invoked] --> B["POST /openclaw/enforce phase=pre"]
    B --> C{Action?}
    C -->|ALLOW| D[Run tool]
    C -->|BLOCK| E[Block call]
    C -->|REWRITE| F[Replace args, then run]
  end
  subgraph post [After tool call]
    D --> G["POST /openclaw/enforce phase=post"]
    G --> H{Action?}
    H -->|ALLOW| I[Return result]
    H -->|BLOCK| J[Safe blocked message]
    H -->|REDACT| K[Redacted result]
    H -->|REWRITE| L[Rewritten result]
  end
  1. Before each tool call (before_tool_call): the plugin POSTs phase: "pre" with tool name and args. Limits returns ALLOW, BLOCK, or REWRITE (with rewriteArgs). The plugin blocks the call, allows it, or replaces the tool arguments accordingly.
  2. After each tool call (after_tool_call): the plugin POSTs phase: "post" with tool name, args, and result. Limits returns ALLOW, BLOCK, REDACT, or REWRITE (with redactedResult or rewrittenResult). The plugin leaves the result unchanged, replaces it with a safe blocked response, or replaces it with the redacted/rewritten value.

Compatibility: This plugin requires an OpenClaw build where tool hooks are wired into the execution path. If you see [@limits/openclaw] before_tool_call observed in logs once after a tool runs, hooks are working. See OpenClaw #6535 if hooks never fire.


Policy-generator tools

When apiToken is set, the plugin registers two optional tools and loads the limits-policy-generator skill:

| Tool | Description | |------|-------------| | limits_generate_create_policy | Generate a new policy from natural language and create it on the Limits backend (POST /api/policies/generatecreate). | | limits_generate_update_policy | Generate updates from natural language and apply to an existing policy (POST /api/policies/:id/generateupdate). |

The agent can then fulfill requests like “create a policy that blocks payment tools” or “update my policy to also block stripe_*” by calling these tools.

Add the skill to the workspace

When you run openclaw limits configure (or npm run configure), you can choose to add the limits-policy-generator skill to your OpenClaw workspace when prompted.

Optionally, you can copy it manually. The example below is for Unix; on Windows use the wizard or PowerShell equivalents (e.g. New-Item -ItemType Directory -Force and Copy-Item -Recurse).

mkdir -p ~/.openclaw/workspace/skills/limits-policy-generator
cp -r ./node_modules/@limits/openclaw/skills/limits-policy-generator/. ~/.openclaw/workspace/skills/limits-policy-generator/

Expose tools to the agent

The plugin registers these tools as optional. Add the plugin to the agent's tool allowlist (see Quick Start) so the agent can call them. Use "@limits/openclaw" to allow all tools from this plugin, or allow by name: ["limits_generate_create_policy", "limits_generate_update_policy"].

Sandboxed agents

If the agent runs in a sandbox, add "@limits/openclaw" (or the tool names) to tools.sandbox.tools.allow as well so the sandboxed agent can call the policy tools. Otherwise the agent can have the skill but cannot invoke the tools from inside the sandbox.


Configuration

| Key | Required | Default | Description | |-----|----------|---------|-------------| | baseUrl | — | Fixed in plugin | Base URL for POST /openclaw/enforce and policy-generator API calls. Optional in config for compatibility. | | apiToken | No | — | Organization API key for /openclaw/enforce and policy-generator tools. Fallback when event/context don't provide a token. Store securely or use LIMITS_ENFORCER_API_TOKEN env. | | timeoutMs | No | 2500 | Request timeout in milliseconds. | | failMode | No | "allow" | When Limits is unreachable or errors: Pre: "allow" → let the call proceed; "block" → block the call. Post: "allow" → keep original result; "block" → replace result with a safe blocked message. | | tokenSource | No | "event.metadata.apiToken" | Dot-separated path to the API token. The plugin uses this first; if missing, it falls back to apiToken. | | redactLogs | No | true | Whether to avoid logging sensitive data (token/args are never logged). |

Environment overrides

| Variable | Maps to | |----------|---------| | LIMITS_ENFORCER_TIMEOUT_MS | timeoutMs | | LIMITS_ENFORCER_FAIL_MODE | allow or block | | LIMITS_ENFORCER_TOKEN_SOURCE | token path | | LIMITS_ENFORCER_REDACT_LOGS | true / 1 for true | | LIMITS_ENFORCER_API_TOKEN | apiToken |

Gateway config example

{
  "plugins": {
    "entries": {
      "@limits/openclaw": {
        "enabled": true,
        "config": {
          "apiToken": "sk_your_organization_api_key",
          "timeoutMs": 2500,
          "failMode": "allow",
          "tokenSource": "event.metadata.apiToken"
        }
      }
    }
  }
}

Policy tag convention (Limits backend)

Policies are scoped to OpenClaw tool calls using tags in the Limits dashboard:

| Tag | Meaning | |-----|---------| | openclaw:phase:pre | Apply only in the pre phase (before the tool runs). | | openclaw:phase:post | Apply only in the post phase (after the tool runs, e.g. guardrails on output). | | (no openclaw:phase tag) | Apply to both phases. | | openclaw:tool:stripe.charge | Apply only to the tool named stripe.charge. | | openclaw:tool:stripe.* | Apply to all tools whose name starts with stripe.. | | (no openclaw:tool tag) | Apply to all tools. | | openclaw:scope:all | Explicit scope: policy applies to all tools (required when OPENCLAW_REQUIRE_SCOPE_TAGS is set). | | openclaw:scope:tools | Explicit scope: policy applies to specific tools (required when scope tags are enforced). |

Example: To block Stripe tool calls with amount > 200, create a CONDITIONS policy like input.args.amount > 200 → BLOCK, and tag it with openclaw:phase:pre and openclaw:tool:stripe.*.


Limits API contract

Endpoint: POST {baseUrl}/openclaw/enforce

Request body (JSON) — same shape for pre and post:

| Field | Pre | Post | Description | |-------|-----|------|-------------| | phase | ✓ | ✓ | "pre" or "post". | | apiToken | ✓ | ✓ | String from tokenSource (identifies the org on Limits). | | tool | ✓ | ✓ | Object: name, args, optional toolCallId. For post only, tool also includes result. | | context | ✓ | ✓ | Optional: requestId, runId, sessionKey, agentId, channel, userMessageSummary. |

Response (JSON):

  • Pre: { "action": "ALLOW" } | { "action": "BLOCK", "reason": "..." } | { "action": "REWRITE", "rewriteArgs": { ... } }
  • Post: { "action": "ALLOW" } | { "action": "BLOCK", "reason": "..." } | { "action": "REDACT", "redactedResult": ... } | { "action": "REWRITE", "rewrittenResult": ... }

Decision precedence: Deny wins — any BLOCK overrides ALLOW. Document your own precedence for REWRITE/REDACT if you combine multiple policies.


CLI commands

| Command | Description | |---------|-------------| | openclaw plugins install <path> | Install plugin from path. | | openclaw plugins install -l <path> | Link plugin (no copy, for development). | | openclaw plugins enable "@limits/openclaw" | Enable the plugin. | | openclaw plugins list | List installed plugins. | | openclaw plugins doctor | Check plugin health. | | openclaw limits configure | Interactive wizard to set API token and sandbox allowlist. | | openclaw config get 'plugins.entries["@limits/openclaw"]' | Show plugin config. | | openclaw config set 'plugins.entries["@limits/openclaw"].config.apiToken' "sk_..." | Set apiToken manually. |


Security (OpenClaw ↔ Limits)

  • Use HTTPS in production.
  • For higher assurance (e.g. internal networks), consider mTLS or a shared HMAC header in addition to apiToken.
  • Apply rate limiting and auth on the Limits endpoint.

Development

  • Tests: npm test (Vitest). Unit tests mock the enforcer; the integration test runs a real HTTP server and exercises the full pre/post flow.
  • Retries: The enforcer client retries up to 2 times on HTTP 429 or 5xx with exponential backoff (200 ms, 400 ms). Non-retryable errors trigger failMode immediately.

Migration from limits-enforcer

If you were using the plugin under the old name limits-enforcer, update your config and CLI usage:

| Before | After | |--------|-------| | Plugin ID / allowlist: "limits-enforcer" | "@limits/openclaw" | | Config path: plugins.entries.limits-enforcer | plugins.entries["@limits/openclaw"] | | CLI command: openclaw limits-enforcer configure | openclaw limits configure | | Log prefix: [limits-enforcer] | [@limits/openclaw] |

After renaming, reinstall the plugin and enable "@limits/openclaw".


Troubleshooting

  • Config warning "plugin id mismatch (manifest uses '@limits/openclaw', entry hints 'openclaw')"
    Some OpenClaw gateways install scoped packages under extensions/openclaw instead of extensions/@limits/openclaw. The gateway then infers the plugin id from the folder name (openclaw), which does not match the manifest id @limits/openclaw, so the plugin may not load and openclaw limits configure shows unknown command 'limits'.

    Workaround — install under the scoped path so the gateway matches the config entry:

    # Create the scope directory and install the package there (adjust if you use npm -g or another path)
    mkdir -p ~/.openclaw/extensions/@limits
    cp -r ./node_modules/@limits/openclaw ~/.openclaw/extensions/@limits/
    
    # Tell OpenClaw to load the plugin from that path
    openclaw plugins install ~/.openclaw/extensions/@limits/openclaw
    openclaw plugins enable "@limits/openclaw"
    openclaw gateway restart

    Then run openclaw limits configure.

  • error: unknown command 'limits'
    The plugin did not load (often due to the id mismatch above). Use the workaround above, or run the configure wizard without the OpenClaw CLI:

    node node_modules/@limits/openclaw/scripts/configure.js

    Or from the plugin repo: npm run configure.


License

MIT — LimitsGitHub