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

@agentveins/mcp

v0.7.0

Published

MCP server for AgentVeins: governed payments as a tool any agent can call.

Readme

@agentveins/mcp

Governed payments as a tool any MCP-capable agent can call. The agent asks to pay; the guard decides; the wallet key never leaves this process.

npm install @agentveins/mcp

Write a policy — the rules are the product, so this is the one thing that cannot have a default:

{
  "budgets": [
    { "period": "per_tx", "limit": "1.00",  "currency": "USDC" },
    { "period": "daily",  "limit": "10.00", "currency": "USDC" }
  ],
  "vendors": { "mode": "allowlist", "entries": ["api.weather.com"] },
  "killSwitch": { "frozen": false }
}

Then point any MCP-capable agent at it. Two variables:

{
  "mcpServers": {
    "agentveins": {
      "command": "npx",
      "args": ["-y", "@agentveins/mcp"],
      "env": {
        "AGENTVEINS_POLICY": "/absolute/path/to/policy.json",
        "AGENTVEINS_RAIL": "mock"
      }
    }
  }
}

The audit log, its anchor, the approval store and the signing key all live beside the policy file unless you name them. The key is created on the first run and kept; the public half is written next to it, so veins --verify has something to check the log against.

Tools

| | | | --- | --- | | pay | attempts a payment. Settles, or is refused with the rule that refused it | | check | answers whether a payment would pass, moving nothing | | spend_state | every budget, what is spent, what remains, and whether the agent is frozen |

Nothing here can loosen a rule. There is no grant and no unfreeze: an agent may spend what it was allowed and ask what it is allowed, and may not widen either.

A blocked payment is a tool result, not a tool error. A denial is the policy working, and reporting it as an error teaches an agent to treat governance as a malfunction and retry against it. Only a rail failure is an error.

Configuration

| Variable | Meaning | | --- | --- | | AGENTVEINS_RAIL | solana, or mock to govern payments that never move money. Inferred as solana when SOLANA_KEYPAIR_PATH is set | | AGENTVEINS_POLICY | path to the policy JSON | | AGENTVEINS_SIGNING_KEY | ed25519 private key, PEM. Defaults to operator.key.pem beside the policy, created on first run | | AGENTVEINS_AUDIT | the audit log, which holds the spend counter. Defaults to audit.jsonl beside the policy | | AGENTVEINS_ANCHOR | detects a deleted log. Defaults to audit.anchor.json beside the policy | | AGENTVEINS_APPROVALS | approval store, used when the policy sets a threshold. Defaults beside the policy | | AGENTVEINS_AGENT / _LOG_ID | identity recorded on every entry | | SOLANA_KEYPAIR_PATH / SOLANA_RPC_URL | when the rail is solana | | SOLANA_MODE | direct or x402; defaults to direct |

Only AGENTVEINS_POLICY and AGENTVEINS_RAIL are required, and the rail is inferred as solana when SOLANA_KEYPAIR_PATH is set. Nothing is ever inferred as mock — a server that reported settlements while moving nothing is the one guess this must not make.

Everything else defaults beside the policy file, which is a location you chose. The alternative is the process's working directory, which an MCP client picks and you never see — and since a missing audit log reads as a first run rather than an error, a path that wanders would hand back the whole daily budget on every launch from somewhere new.

The signing key is generated once and reused. A guard replays its audit log at startup and refuses one it cannot verify, so a key that changed between launches would work exactly once; that argument calls for a key that persists, not one you have to produce by hand. A key file that exists but cannot be read is an error rather than a reason to write a new one, because replacing it would orphan every entry the old key signed.

Every diagnostic, including that refusal, goes to stderr: stdout is the MCP protocol, and writing anything else there would corrupt the session.

Mounting your own guard

import { serveGuard } from "@agentveins/mcp";

await serveGuard(myGuard, "solana");

serveGuard reads no environment and no files, so an operator with their own guard — a database-backed approval store, a custom adapter — mounts it directly.

Full documentation: docs.agentveins.com