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

ardkit-ai

v0.1.0

Published

Plug-and-play ARD (Agentic Resource Discovery) publisher & registry middleware for Next.js and MCP/A2A backends.

Downloads

52

Readme

ardkit (TypeScript)

CI npm License Spec: ai-catalog 1.0

Plug-and-play ARD (Agentic Resource Discovery) publisher & registry middleware for Next.js and MCP / A2A backends.

ARD lets AI clients discover your agents, MCP servers and skills before they invoke them — instead of every tool description being crammed into the model's context window. ardkit turns any Next.js App-Router backend into an ARD publisher (and, optionally, a search registry) in a few lines.

npm install ardkit-ai       # or pnpm add ardkit-ai / yarn add ardkit-ai

The npm package is ardkit-ai (the bare name ardkit was already taken); import from ardkit-ai (and ardkit-ai/next, ardkit-ai/adapters).

Quickstart — publish

// lib/catalog.ts
import { Catalog } from "ardkit-ai";

export const catalog = new Catalog({
  host: "Acme AI",
  publisher: "acme.com",
  identifier: "did:web:acme.com",
});
catalog.addMcpServer({
  name: "Billing",
  url: "https://acme.com/mcp",
  capabilities: ["create_invoice", "list_invoices"],
  representativeQueries: ["create an invoice", "show unpaid invoices"],
});

Define your handlers once with createArd, then each App-Router route file is a single re-export (App Router needs the files; no CLI, no codegen):

// lib/ard.ts
import { createArd } from "ardkit-ai/next";
import { catalog } from "@/lib/catalog";

export const ard = createArd({ catalog /*, registry */ });
// app/.well-known/ai-catalog.json/route.ts
import { ard } from "@/lib/ard";
export const { GET } = ard.wellKnown;
// app/robots.txt/route.ts
import { ard } from "@/lib/ard";
export const { GET } = ard.robots; // emits an `Agentmap:` directive
// app/api/ard/[...ard]/route.ts  (only if you pass a registry)
import { ard } from "@/lib/ard";
export const { GET, POST } = ard.registry;

The manifest is served with Content-Type: application/json and Access-Control-Allow-Origin: * so crawlers can fetch it cross-origin. Prefer the individual helpers (ardCatalogRoute, robotsRoute, createRegistryCatchAll)? They're exported too.

Validate a manifest any time from code:

import { validateManifest } from "ardkit-ai";
validateManifest(catalog.toManifest()); // [] when it conforms to ai-catalog v1.0

Auto-derive entries from your frameworks

import { fromMcpServer, fromA2aCard } from "ardkit-ai/adapters";

catalog.add(
  fromMcpServer({
    name: "Billing",
    url: "https://acme.com/mcp",
    publisher: "acme.com",
    tools: ["create_invoice", "list_invoices"], // -> capabilities
  }),
);

catalog.add(fromA2aCard(myAgentCard, { url: "https://acme.com/a2a/agent", publisher: "acme.com" }));

Apex discovery for a backend on another host

When the catalog's source of truth lives on a backend (api.example.com) but discovery must answer on the apex (example.com), use the content-origin / edge-publisher split: the backend serves the catalog document; the apex app publishes /.well-known/ai-catalog.json by consuming it with remoteCatalog — edge-cached via Next.js revalidate, with a timeout and fallback so apex discovery never hard-depends on backend uptime.

// apex app: app/.well-known/ai-catalog.json/route.ts
import { ardCatalogRoute, remoteCatalog } from "ardkit-ai/next";
import { staticManifest } from "@/lib/fallback";

export const revalidate = 300; // route-level ISR
export const GET = ardCatalogRoute(
  remoteCatalog("https://api.example.com/api/ard/ai-catalog.json", {
    fallback: staticManifest,
  }),
);

ardCatalogRoute adds a weak ETag + Cache-Control and answers If-None-Match with 304. Entry urls still point at the backend (api.example.com/...); only the manifest's hosting host and identity are the apex.

Optional: be a registry (bring your own search)

ardkit-ai owns the ARD wire contract (request parsing, filters, pagination, federation, error codes, response shaping). You own ranking by implementing SearchProvider — or use the bundled InMemorySearchProvider.

// app/api/ard/[...ard]/route.ts
import { createRegistryCatchAll } from "ardkit-ai/next";
import { RegistryService, InMemorySearchProvider } from "ardkit-ai";
import { catalog } from "@/lib/catalog";

const service = new RegistryService(
  new InMemorySearchProvider(catalog.entries), // swap for your engine
  { source: "https://acme.com/api/ard/" },
);

export const { GET, POST } = createRegistryCatchAll(service);
// -> POST /api/ard/search, POST /api/ard/explore, GET /api/ard/agents

Your own backend just satisfies the interface:

import type { SearchProvider } from "ardkit-ai";

const provider: SearchProvider = {
  async search(query, { pageSize, pageToken }) {
    const hits = await myVectorDb.query(query.text, { filter: query.filter, k: pageSize });
    return { items: hits.map((h) => ({ entry: h.card, score: h.score })) };
  },
};

explore and listAgents are optional — omit them and those endpoints return HTTP 501 as the spec allows.

Entry points

| Import | Contents | | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | | ardkit-ai | Catalog, schema + types, discovery helpers, validation, registry (RegistryService, InMemorySearchProvider, SearchProvider), errors | | ardkit-ai/next | ardCatalogRoute, robotsRoute, withAgentmap, createRegistryRoutes, createRegistryCatchAll | | ardkit-ai/adapters | fromMcpServer, fromMcpHandler, fromA2aAgent, fromA2aCard |

Ships ESM + CJS + types; the ardkit-ai/next handlers use the Web Request/Response API, so there's no hard dependency on next and they run on the Edge runtime.

Development

pnpm install
pnpm test
pnpm typecheck
pnpm lint && pnpm format:check
pnpm build

License

Apache-2.0 — matching the ARD specification. See LICENSE.