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

@agentcreds/sdk

v0.2.0

Published

Verifiable, attenuable delegation for AI agents - org-rooted and verified offline

Readme

@agentcreds/sdk (Node.js / TypeScript)

Node.js bindings for AgentCreds - verifiable, attenuable delegation for autonomous AI agents, verified offline.

Scope. This SDK is at parity with the Python core binding - identities, credentials, tokens, presentations, revocation, key history, ADRs including accountability and R10 verdicts. The runtime enforcement layer is different: @agentcreds/runtime is A2A-only by design and is not an MCP policy enforcement point. R10 execution-time gates, step-up approval and the MCP enforcer are Python-only. A Node agent can talk to a Python PEP over the wire; a Node service cannot host one.

These bindings wrap the agentcreds-core Rust engine via napi-rs.

A note on async

Every operation in this SDK is synchronous - there is no Promise/ async/await anywhere in this API. The underlying Rust operations (DID generation, credential issuance/verification, token minting/attenuation/ verification, revocation checks) all complete in well under a millisecond, so wrapping them in promises would add overhead without benefit. This is a deliberate deviation from async-styled quickstarts you may see elsewhere in the AgentCreds docs.

Installation

npm install @agentcreds/sdk

(or, building from source: npm run build, which invokes napi build --platform --release)

Quick start

import * as ac from "@agentcreds/sdk";

// 1. Org trust anchor (in production: keys live in an HSM)
const anchor = ac.TrustAnchor.generate();

// 2. Agent enrolled at deploy time
const agent = ac.AgentIdentity.createDidKey();

// 3. Issue a capability credential
const claims = new ac.CapabilityClaims({
  tools: ["tool:search", "tool:email"],
  maxDelegationDepth: 3,
  validForSecs: 3600, // valid for 1 hour
});
const vc = ac.CapabilityCredential.issue(anchor, agent.did, claims);

// 4. Mint a short-lived runtime token (valid 5 minutes)
const scope = new ac.Scope({ tools: ["tool:search"], budgetUsd: 100, maxDepth: 2 });
const token = ac.DelegationToken.mint(vc, scope, 300, agent);

// 5. Verify at every tool call boundary (<1ms)
const action = new ac.Action("tool:search", "q=agentcreds");
token.verify(action);

// 6. Delegate to a sub-agent (scope can only narrow)
const subAgent = ac.AgentIdentity.createDidKey();
const narrow = new ac.Scope({ tools: ["tool:search"], budgetUsd: 10, maxDepth: 1 });
const childToken = token.attenuate(narrow, 60, subAgent);

Cross-org verification

import * as ac from "@agentcreds/sdk";

// Org B registers Org A's trust anchor (resolved from a TRAIL registry in production)
const registry = new ac.TrustRegistry();
registry.register(new ac.TrustEntry(
  orgAAnchor.did,
  "Organization A",
  orgAAnchor.publicKey,
  "verified",
));

// Verify Org A's credential WITHOUT calling back to Org A
const entry = registry.verifyCredential(vcFromOrgA);
console.log(`Verified by ${entry.orgName} (${entry.trustLevel})`);

Revocation

import * as ac from "@agentcreds/sdk";

// Create an OAuth Token Status List (131,072 entries by default)
const revocationList = new ac.RevocationList("https://registry.example.com/status/1", anchor);

// Revoke credential at index 42 (propagates in <30s in production)
revocationList.revoke(42, anchor);

// Check revocation status (<0.1ms, no network call)
console.assert(revocationList.isRevoked(42));

Error handling

Every error thrown by this SDK is a JS Error whose message is prefixed with an error kind, mirroring the exception hierarchy of the Python bindings (agentcreds.AgentCredsError and its subclasses). Branch on the prefix with error.message.startsWith(...):

import * as ac from "@agentcreds/sdk";

try {
  token.verify(new ac.Action("tool:delete-everything", ""));
} catch (e) {
  const message = e instanceof Error ? e.message : String(e);
  if (message.startsWith("ActionDeniedError")) {
    console.log(`denied: ${message}`);
  } else if (message.startsWith("TokenExpiredError")) {
    console.log(`expired: ${message}`);
  } else {
    console.log(`other agentcreds error: ${message}`);
  }
}

| Message prefix | Raised when | |---|---| | DidError | DID resolution, signature, or key-material problems | | CredentialError | Malformed claims, issuer mismatch, invalid proof | | CredentialExpiredError | A credential's expirationDate has passed | | CredentialRevokedError | A credential's index is set in a revocation list | | DelegationError | Token chain integrity / depth-limit problems | | ScopeWideningError | An attenuation attempt would widen scope | | TokenExpiredError | A delegation token (or one of its blocks) has expired | | ActionDeniedError | The requested tool is not in the leaf block's scope | | RevocationError | Revocation list index out of bounds / bad signature | | SerializationError | JSON / CBOR / base64 (de)serialization failure | | ValidationError | A field value is missing, out of bounds, or of the wrong sign (e.g. a negative index) |

Arguments rejected directly by the binding layer (e.g. a negative validForSecs) throw with error.code === "InvalidArg"; errors propagated from agentcreds-core throw with error.code === "GenericFailure". In both cases the message prefix table above applies.

Type declarations

A hand-written index.d.ts ships with this package for editor/IDE autocomplete and TypeScript type checking. Running napi build regenerates this file directly from the Rust #[napi] annotations in src/.

Building

npm run build              # napi build --platform --release
cargo test --manifest-path ../agentcreds-core/Cargo.toml

License

Apache-2.0