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

anvil-sdk

v1.0.2

Published

Express for humans. Anvil for agents. Node backend framework with file-based routing, compile-time validation, and a native agentic layer (MCP, tools, tracing).

Downloads

466

Readme

Anvil JS

Express for humans. Anvil for agents.

Anvil is a Node.js backend framework for AI & GenAI developers. It's Express-level flexible, with Next.js-style file-based routing and full compile-time schema validation — and every route is automatically type-safe, MCP-usable, A2A-usable, traced, cost-governed, and crash-resumable, with zero extra code.

Not a chatbot template. Not an AI SDK wrapper. It's a general-purpose HTTP framework where the agentic layer — MCP exposure, tool registry, agent orchestration, observability, durability, guardrails — is built into the framework core instead of hand-wired on top of Express.

// server/routes/users/[id]/get.ts
export const meta = { mcp: { expose: true, description: 'Fetch a user by ID' } };
export const paramsSchema = z.object({ id: z.string() });

export default function handler(ctx) {
  return findUser(ctx.params.id);
}

That one file is now GET /users/:id, an MCP tool (anvil mcp), and an A2A skill — the same handler, the same schema, checked at build time, no duplication.

Core routing, MCP/A2A exposure, agent runtime, observability, durability, evals, memory/RAG, and background agents are all implemented and covered by 200+ tests.


Quick start

mkdir my-api && cd my-api
npm init -y
npm install anvil-sdk zod
npx anvil init      # scaffolds package.json scripts, tsconfig, and a starter route
npm install
npx anvil dev       # dev server, hot reload

anvil init prompts for a starting point (basic API / MCP server / agent route), or skip the prompt with --template <name> / -y.

Or try a working example in under a minute:

cd examples/basic-api && npm install && npx anvil dev

What's in the box

| Layer | What you get | |---|---| | Routing | File-based routes ([id], [...catchall], (groups), scoped _middleware.ts), Express-parity static files/CORS, radix-tree matching | | Compile-time validation | anvil lint — params match schemas, MCP-exposed schemas serialize losslessly, structural route conflicts fail the build (not the request) | | MCP & A2A | anvil mcp (Streamable HTTP + stdio), anvil/a2a — one route/tool definition, three protocols | | Agents | defineAgent, tool-calling loop with iteration caps, Vercel AI SDK streaming, abort-on-disconnect | | Model client | LlmClient over Anthropic / OpenAI / Gemini (lazy, optional peer deps), fallback chains, retries, cost tracking, structured output | | Observability | Trace tree per run, bundled /_anvil dashboard, cost governor, OpenTelemetry GenAI export | | Durability & safety | Crash-resumable checkpointing (no double side-effects), human-in-the-loop approval, guardrails, prompt-injection taint layer | | Evals & replay | anvil eval (deterministic + LLM-as-judge), versioned prompt registry, anvil replay <traceId> with zero live calls | | Memory & RAG | ctx.memory, chunking + embeddings + vector store + traced retrieval, embedding-similarity semantic cache | | Background & multi-agent | Scheduled (cron) and event-triggered agents, AgentRegistry/callAgent delegation | | Sandbox | worker_threads + vm-isolated code execution for agent-written code (documented threat model) |

Full docs: docs/. Working examples: basic-api · mcp-server · agent-hitl.

File-based routing

server/routes/
  get.ts                  → GET /
  users/
    _middleware.ts        → scoped middleware for /users/**
    get.ts                → GET /users
    post.ts                → POST /users
    [id]/
      get.ts              → GET /users/:id
  files/
    [...path]/
      get.ts              → GET /files/* (catch-all)
  (admin)/                → route group, not part of the URL
    dashboard/
      get.ts              → GET /dashboard
  chat/
    agent.ts              → POST /chat, an agent route (see below)
import type { Context } from 'anvil-sdk';

export default async function handler(ctx: Context) {
  return { id: ctx.params.id }; // plain objects auto-serialize to JSON
}

CLI

| Command | Does | |---|---| | anvil init [dir] | Scaffolds package.json, tsconfig, and starter routes (basic API / MCP server / agent route) | | anvil dev | Dev server, hot reload, TypeScript routes loaded on the fly | | anvil build | Static route manifest + production bundle | | anvil start | Runs the production bundle | | anvil lint | Params/schema validation; MCP-schema serializability (--strict fails on warnings too) | | anvil mcp [--stdio] | Serves exposed routes + server/tools/ as an MCP server | | anvil eval <file> | Runs an eval suite against an agent; non-zero exit on failure | | anvil replay <traceId> | Re-runs a captured trace with mocked model responses |

Agent routes

// server/routes/chat/agent.ts
import { defineAgent } from 'anvil-sdk/agent';
import { LlmClient, AnthropicDriver } from 'anvil-sdk/llm';
import { z } from 'zod';

const client = new LlmClient({
  drivers: [new AnthropicDriver({ apiKey: process.env.ANTHROPIC_API_KEY })],
  defaultModel: 'claude-opus-4-8',
  fallback: ['gpt-4o'], // add an OpenAIDriver (or 'gemini-2.5-flash' + GeminiDriver)
});

export default defineAgent({
  client,
  system: 'You are a helpful assistant.',
  tools: [
    { name: 'get_weather', description: 'Get weather for a city', zodSchema: z.object({ city: z.string() }), execute: ({ city }) => fetchWeather(city) },
  ],
});

Served over POST, streaming the Vercel AI SDK data-stream protocol (useChat works against it directly). The runtime runs the model↔tool loop with an iteration cap, validates each tool's input against its Zod schema, tracks usage/cost, and aborts the whole run — model call and tool execution — on client disconnect.

Add durability, human approval, and policy with a few more options — see docs/agents.md and docs/durability-safety.md.

Why not just Express + an MCP SDK + LangChain?

Because then you're maintaining three schemas for one endpoint (REST validation, tool-calling schema, MCP tool definition), a hand-rolled trace format, your own crash-recovery for agent loops, and a bespoke approval flow for anything that touches money or PII. Anvil's bet: this is framework-layer work, done once, the way Next.js did routing once instead of every app reinventing it.

Roadmap

A few areas are actively being hardened: deeper static-analysis lint rules for handler bodies, true token-level streaming from the model drivers (currently chunked), an ANN-backed vector store adapter for large corpora, and a container-based sandbox adapter for untrusted code execution.