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

@lucid-agents/catalog

v1.0.2

Published

YAML/CSV catalog-driven route generation for Lucid Agents

Downloads

79

Readme

@lucid-agents/catalog

YAML/CSV catalog-driven route generation for Lucid Agents.

Overview

When your agent exposes a large product catalog -- hundreds or thousands of items -- manually calling addEntrypoint() for each one becomes unmanageable. Writing 400 entrypoint definitions by hand is tedious, error-prone, and hard to keep in sync with your actual inventory.

@lucid-agents/catalog solves this by letting you define your catalog in a YAML or CSV file and automatically generating typed entrypoints at build time. A single .use(catalog(...)) call replaces hundreds of manual addEntrypoint() calls.

Key features:

  • YAML and CSV parsing -- Define products in the format that fits your workflow
  • Automatic entrypoint generation -- Each catalog item becomes a discoverable, invocable route
  • Price support -- Flat prices or separate invoke/stream prices per item
  • Network tagging -- Per-item or global network assignment in CAIP-2 format
  • Custom metadata -- Attach arbitrary key-value pairs to catalog items
  • Handler factories -- Generate route handlers dynamically from catalog data
  • Key prefixing -- Namespace catalog routes to avoid collisions

Installation

bun add @lucid-agents/catalog

The root entrypoint contains portable YAML/CSV parsing, schemas, and entrypoint generation. File-backed loading uses Node's filesystem APIs and is therefore explicitly exported from @lucid-agents/catalog/node.

Quick Start

Define a catalog file (products.yaml):

products:
  - key: weather
    name: Weather Lookup
    description: Get current weather for a city
    price: '0.001'
  - key: translate
    name: Translation
    description: Translate text between languages
    price: '0.002'

Wire it into your agent:

import { createAgent } from '@lucid-agents/core';
import { http } from '@lucid-agents/http';
import { catalog } from '@lucid-agents/catalog/node';
import { createAgentApp } from '@lucid-agents/hono';

const agent = await createAgent({
  name: 'catalog-agent',
  version: '1.0.0',
  description: 'Agent with catalog-driven routes',
})
  .use(http())
  .use(catalog({ file: './products.yaml' }))
  .build();

const { app } = await createAgentApp(agent);
export default app;

Each item in products.yaml is now a discoverable entrypoint on your agent.

YAML Format

YAML catalogs support either a top-level array or an object with a products key:

products:
  - key: sentiment
    name: Sentiment Analysis
    description: Analyze text sentiment
    price: '0.001'
    network: 'eip155:8453'
    paymentProtocol: x402
    metadata:
      category: nlp
      model: gpt-4o-mini

Supported Fields

| Field | Type | Required | Description | | ----------------- | -------------------- | -------- | ---------------------------------------------------------------------------------------------------- | | key | string | Yes | Unique route identifier. Becomes the entrypoint key. | | name | string | Yes | Human-readable display name. | | description | string | No | Description shown in the agent manifest. | | price | string or object | No | Flat price as a string, or an object with invoke and/or stream prices. | | network | string | No | CAIP-2 network identifier (e.g., eip155:8453). | | paymentProtocol | "x402" or "mpp" | No | Payment rail for a priced item. Required when both rails are installed unless a default is supplied. | | metadata | object | No | Arbitrary key-value pairs attached to the entrypoint. |

Price Variants

Flat price:

- key: summarize
  name: Summarize
  price: '0.005'

Separate invoke and stream prices:

- key: generate
  name: Generate Text
  price:
    invoke: '0.01'
    stream: '0.002'

CSV Format

CSV catalogs use a header row with the standard fields. Metadata is supported via the meta_ column prefix convention.

key,name,description,price,network,paymentProtocol,meta_category,meta_model
weather,Weather Lookup,Get current weather,0.001,eip155:8453,x402,utility,gpt-4o-mini
translate,Translation,Translate text,0.002,,mpp,nlp,gpt-4o
sentiment,Sentiment Analysis,Analyze sentiment,0.001,,x402,nlp,gpt-4o-mini

Column Reference

| Column | Required | Description | | ----------------- | -------- | -------------------------------------------------------------------------------------------------- | | key | Yes | Unique route identifier. | | name | Yes | Display name. | | description | No | Route description. | | price | No | Price as a string value. | | network | No | CAIP-2 network identifier. | | paymentProtocol | No | x402 or mpp. | | meta_* | No | Any column prefixed with meta_ is collected into the metadata object with the prefix stripped. |

For example, a column named meta_category with value nlp results in metadata: { category: "nlp" }.

Note: CSV does not support the invoke/stream price object syntax. Use YAML if you need separate prices per method.

API Reference

catalog(options)

Extension factory that reads a catalog file and registers entrypoints at build time.

import { catalog } from '@lucid-agents/catalog/node';

agent.use(
  catalog({
    file: './products.yaml',
    keyPrefix: 'store/',
    network: 'eip155:8453',
    paymentProtocol: 'x402',
    handlerFactory:
      item =>
      async ({ input }) => {
        return { output: { product: item.key } };
      },
  })
);

CatalogExtensionOptions

| Option | Type | Required | Description | | ----------------- | ----------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------- | | file | string | Yes | Path to the .yaml, .yml, or .csv catalog file. | | keyPrefix | string | No | Prefix prepended to every item key (e.g., "store/" turns "widget" into "store/widget"). | | network | string | No | Default CAIP-2 network for items that do not specify their own. | | paymentProtocol | "x402" \| "mpp" | No | Default payment rail for items that do not specify their own. | | handlerFactory | HandlerFactory | No | Function that receives a CatalogItem and returns a handler function. | | inputSchema | z.ZodTypeAny | No | Zod schema applied to all generated entrypoints. Defaults to z.object({ params: z.record(z.string(), z.unknown()).optional() }). |

parseCatalogYaml(content)

Parses a YAML string into an array of validated CatalogItem objects.

import { parseCatalogYaml } from '@lucid-agents/catalog';

const items = parseCatalogYaml(`
products:
  - key: weather
    name: Weather Lookup
    price: "0.001"
`);
// items: CatalogItem[]

Accepts either a top-level array or an object with a products key. Throws if any item fails validation.

parseCatalogCsv(content)

Parses a CSV string into an array of validated CatalogItem objects.

import { parseCatalogCsv } from '@lucid-agents/catalog';

const items = parseCatalogCsv(`key,name,price
weather,Weather Lookup,0.001
translate,Translation,0.002`);
// items: CatalogItem[]

Requires a key column. Columns prefixed with meta_ are collected into the metadata field. Throws if any row fails validation.

generateEntrypoints(items, options?)

Converts an array of CatalogItem objects into EntrypointDef objects ready for registration.

import { generateEntrypoints } from '@lucid-agents/catalog';

const entrypoints = generateEntrypoints(items, {
  keyPrefix: 'api/',
  network: 'eip155:8453',
  paymentProtocol: 'x402',
  handlerFactory:
    item =>
    async ({ input }) => {
      return { output: { result: item.name } };
    },
});

for (const ep of entrypoints) {
  runtime.entrypoints.add(ep);
}

GenerateOptions

| Option | Type | Description | | ----------------- | ----------------- | ------------------------------------------- | | keyPrefix | string | Prefix prepended to each item key. | | network | string | Default network for items without one. | | paymentProtocol | "x402" \| "mpp" | Default payment rail for items without one. | | handlerFactory | HandlerFactory | Generates a handler for each item. | | inputSchema | z.ZodTypeAny | Input schema for all entrypoints. |

CatalogItemSchema

Zod schema used to validate catalog items. Useful for custom parsing or validation pipelines.

import { CatalogItemSchema } from '@lucid-agents/catalog';

const result = CatalogItemSchema.safeParse({
  key: 'test',
  name: 'Test Item',
  price: '0.01',
});

CatalogItem

TypeScript type inferred from CatalogItemSchema:

type CatalogItem = {
  key: string;
  name: string;
  description?: string;
  price?: string | { invoke?: string; stream?: string };
  network?: string;
  paymentProtocol?: 'x402' | 'mpp';
  metadata?: Record<string, unknown>;
};

Integration Examples

With x402 Payments

Combine catalog routes with x402 payment gating:

import { createAgent } from '@lucid-agents/core';
import { http } from '@lucid-agents/http';
import { payments, paymentsFromEnv } from '@lucid-agents/payments';
import { catalog } from '@lucid-agents/catalog/node';
import { createAgentApp } from '@lucid-agents/hono';

const agent = await createAgent({
  name: 'paid-catalog-agent',
  version: '1.0.0',
  description: 'Catalog agent with x402 payments',
})
  .use(http())
  .use(payments({ config: paymentsFromEnv() }))
  .use(
    catalog({
      file: './products.yaml',
      paymentProtocol: 'x402',
      handlerFactory:
        item =>
        async ({ input }) => {
          return { output: { product: item.name, data: 'processed' } };
        },
    })
  )
  .build();

const { app } = await createAgentApp(agent);
export default app;

Each catalog item with a price field will automatically require x402 payment.

With MPP (Machine Payments Protocol)

import { createAgent } from '@lucid-agents/core';
import { http } from '@lucid-agents/http';
import { mpp, tempo } from '@lucid-agents/mpp';
import { catalog } from '@lucid-agents/catalog/node';
import { createAgentApp } from '@lucid-agents/hono';

const agent = await createAgent({
  name: 'mpp-catalog-agent',
  version: '1.0.0',
  description: 'Catalog agent with MPP payments',
})
  .use(http())
  .use(
    mpp({
      config: {
        methods: [tempo.server({ currency: '0x...', recipient: '0x...' })],
        currency: 'usd',
        secretKey: process.env.MPP_SECRET_KEY,
      },
    })
  )
  .use(
    catalog({
      file: './services.yaml',
      network: 'eip155:8453',
      paymentProtocol: 'mpp',
      handlerFactory:
        item =>
        async ({ input }) => {
          return { output: { service: item.name } };
        },
    })
  )
  .build();

const { app } = await createAgentApp(agent);
export default app;

See packages/examples/src/catalog/catalog-mpp-store.ts for a full working example.

Custom Handler Factory

The handler factory receives the full CatalogItem, giving you access to metadata for dynamic behavior:

import type { CatalogItem } from '@lucid-agents/catalog';

const handlerFactory =
  (item: CatalogItem) =>
  async ({ input }) => {
    const model = (item.metadata?.model as string) ?? 'gpt-4o-mini';
    const category = (item.metadata?.category as string) ?? 'general';

    // Route to different backends based on metadata
    const result = await processWithModel(model, category, input);

    return { output: result };
  };

agent.use(
  catalog({
    file: './products.yaml',
    handlerFactory,
  })
);

When both x402 and MPP are installed, every priced generated entrypoint needs an explicit rail. Set paymentProtocol on each YAML/CSV item or provide a catalog-wide default; an item-level value wins.

Key Prefix for Namespacing

Use keyPrefix to namespace catalog routes, avoiding collisions when loading multiple catalogs:

const agent = await createAgent({
  name: 'multi-catalog-agent',
  version: '1.0.0',
})
  .use(http())
  .use(catalog({ file: './nlp-services.yaml', keyPrefix: 'nlp/' }))
  .use(catalog({ file: './vision-services.csv', keyPrefix: 'vision/' }))
  .build();

This produces routes like nlp/sentiment, nlp/translate, vision/classify, etc.

Network Support

Network identifiers follow the CAIP-2 format. Common values:

| Network | CAIP-2 ID | | -------------- | ----------------------------------------- | | Base | eip155:8453 | | Base Sepolia | eip155:84532 | | Ethereum | eip155:1 | | Solana Mainnet | solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp | | Solana Devnet | solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1 |

solana:mainnet and solana:devnet are legacy payment aliases rather than canonical CAIP-2 identifiers. Use the values above in new catalog data.

Set a default network for all items via the network option, or override per item in your catalog file.

Related Packages

| Package | Description | | --------------------------------------- | ------------------------------------------------------ | | @lucid-agents/core | Core runtime with extension system and createAgent() | | @lucid-agents/http | HTTP extension for request handling | | @lucid-agents/payments | x402 payment tracking and policy enforcement | | @lucid-agents/mpp | Machine Payments Protocol integration | | @lucid-agents/hono | Hono adapter for serving agents over HTTP |