Lucid Agents
Packages

@lucid-agents/hono

Hono framework adapter for running agents.

The Hono adapter creates a Hono application from an agent runtime, exposing all entrypoints as HTTP routes.

Installation

bun add @lucid-agents/hono hono

For payments support:

bun add x402-hono

Basic usage

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

const agent = await createAgent({
  name: 'my-agent',
  version: '1.0.0',
})
  .use(http())
  .build();

const { app, addEntrypoint } = await createAgentApp(agent);

addEntrypoint({
  key: 'greet',
  input: z.object({ name: z.string() }),
  async handler({ input }) {
    return { output: { message: `Hello, ${input.name}!` } };
  },
});

export default {
  port: 3000,
  fetch: app.fetch,
};

API reference

createAgentApp(agent, options?)

Creates a Hono app from an agent runtime.

function createAgentApp(
  agent: AgentRuntime,
  options?: CreateAgentAppOptions
): Promise<{
  app: Hono;
  addEntrypoint: (def: EntrypointDef) => void;
}>

Parameters:

ParameterTypeDescription
agentAgentRuntimeBuilt agent runtime
optionsCreateAgentAppOptionsOptional configuration

Returns:

PropertyTypeDescription
appHonoConfigured Hono application
addEntrypointFunctionAdd entrypoints after app creation

CreateAgentAppOptions

type CreateAgentAppOptions = {
  beforeMount?: (app: Hono) => void;
  afterMount?: (app: Hono) => void;
};

Hooks:

HookWhen calledUse case
beforeMountBefore agent routes are addedAdd middleware, custom routes
afterMountAfter agent routes are addedAdd additional routes, error handlers

Example with hooks

const { app, addEntrypoint } = await createAgentApp(agent, {
  beforeMount: (app) => {
    // Add CORS middleware
    app.use('*', cors());

    // Add authentication middleware
    app.use('/entrypoints/*', async (c, next) => {
      const token = c.req.header('Authorization');
      if (!token) {
        return c.json({ error: 'Unauthorized' }, 401);
      }
      await next();
    });
  },
  afterMount: (app) => {
    // Add custom routes
    app.get('/custom', (c) => c.json({ custom: true }));

    // Add error handler
    app.onError((err, c) => {
      console.error(err);
      return c.json({ error: 'Internal error' }, 500);
    });
  },
});

Routes

The adapter registers these routes:

RouteMethodDescription
/GETLanding page (if enabled)
/.well-known/agent.jsonGETAgent Card manifest
/healthGETHealth check endpoint
/entrypointsGETList available entrypoints
/entrypoints/:key/invokePOSTInvoke an entrypoint
/entrypoints/:key/streamPOSTStream from an entrypoint (SSE)
/tasksGETList tasks
/tasks/:idGETGet task by ID
/tasks/:id/cancelPOSTCancel a task
/tasks/:id/subscribeGETSubscribe to task updates (SSE)
/favicon.icoGETFavicon

Payment middleware

Add x402 payment middleware for paid entrypoints:

import { createAgentApp, withPayments } from '@lucid-agents/hono';

const agent = await createAgent(meta)
  .use(http())
  .use(payments({ config: paymentsFromEnv() }))
  .build();

const { app, addEntrypoint } = await createAgentApp(agent);

// Add paid entrypoint
addEntrypoint({
  key: 'premium',
  price: { invoke: '$0.01' },
  async handler({ input }) {
    return { output: { result: 'premium content' } };
  },
});

// Wrap app with payment middleware
const appWithPayments = withPayments(app, agent);

export default {
  port: 3000,
  fetch: appWithPayments.fetch,
};

withPayments(app, agent)

Adds x402 payment verification middleware.

function withPayments(app: Hono, agent: AgentRuntime): Hono

The middleware:

  1. Checks if the entrypoint has a price
  2. Validates the X-Payment header
  3. Returns 402 Payment Required if invalid/missing
  4. Allows the request through if payment is valid

Running the server

With Bun

export default {
  port: Number(process.env.PORT ?? 3000),
  fetch: app.fetch,
};

With Node.js

import { serve } from '@hono/node-server';

serve({
  fetch: app.fetch,
  port: Number(process.env.PORT ?? 3000),
});

With Cloudflare Workers

export default {
  fetch: app.fetch,
};

Full example

import { z } from 'zod';
import { createAgent } from '@lucid-agents/core';
import { http } from '@lucid-agents/http';
import { payments, paymentsFromEnv } from '@lucid-agents/payments';
import { createAgentApp, withPayments } from '@lucid-agents/hono';

const agent = await createAgent({
  name: 'my-agent',
  version: '1.0.0',
  description: 'An AI-powered assistant',
})
  .use(http())
  .use(payments({ config: paymentsFromEnv() }))
  .build();

const { app, addEntrypoint } = await createAgentApp(agent);

// Free entrypoint
addEntrypoint({
  key: 'echo',
  input: z.object({ text: z.string() }),
  async handler({ input }) {
    return { output: { echoed: input.text } };
  },
});

// Paid entrypoint
addEntrypoint({
  key: 'analyze',
  input: z.object({ text: z.string() }),
  price: { invoke: '$0.01' },
  async handler({ input }) {
    return { output: { analysis: 'AI analysis...' } };
  },
});

// Add payment middleware
const appWithPayments = withPayments(app, agent);

export default {
  port: 3000,
  fetch: appWithPayments.fetch,
};

Exports

// Main API
export { createAgentApp, withPayments } from '@lucid-agents/hono';

// Types
export type { CreateAgentAppOptions } from '@lucid-agents/hono';

On this page