@lucid-agents/agent-kit
v1.4.2
Published
Build typed agent HTTP apps
Readme
@lucid-agents/agent-kit
@lucid-agents/agent-kit is the core runtime for building AI agents with typed entrypoints, discovery endpoints, monetization hooks, and trust metadata. It provides the shared runtime logic used by adapter packages like @lucid-agents/agent-kit-hono and @lucid-agents/agent-kit-tanstack.
Note: For most use cases, you'll want to use one of the adapter packages (agent-kit-hono or agent-kit-tanstack) rather than importing from this core package directly.
Highlights
- Type-safe entrypoints with optional Zod input and output schemas.
- Automatic
/health,/entrypoints, and AgentCard manifest routes. - Built-in Server-Sent Events (SSE) streaming helpers.
- Optional x402 monetization and per-entrypoint pricing/network overrides.
- Shared runtime configuration with environment + runtime overrides.
- ERC-8004 trust and AP2 manifest integration out of the box.
- Utilities for x402-enabled LLM calls, agent wallets, and identity registries.
Install & Import
This is the core runtime package. For building agents, use one of the adapter packages:
Hono Adapter:
import { createAgentApp } from '@lucid-agents/agent-kit-hono';
import type { EntrypointDef, AgentMeta } from '@lucid-agents/agent-kit';TanStack Adapter:
import { createTanStackRuntime } from '@lucid-agents/agent-kit-tanstack';
import type { EntrypointDef, AgentMeta } from '@lucid-agents/agent-kit';Subpath exports (shared across adapters):
@lucid-agents/agent-kit— main exports including types (EntrypointDef, AgentMeta, etc.)@lucid-agents/agent-kit/utils— focused helpers (toJsonSchemaOrUndefined, etc.)@lucid-agents/agent-kit/axllm— AxLLM client integration
Core Concepts
Core Runtime
This package provides the core runtime logic. Adapter packages like agent-kit-hono and agent-kit-tanstack wrap this runtime with framework-specific implementations.
The runtime manages:
meta(AgentMeta) shapes the health check and manifest.options.configapplies runtime overrides for payments and wallet defaults. These overrides merge with environment variables and package defaults viagetAgentKitConfig.options.paymentsforces aPaymentsConfigfor all routes. Passfalseto explicitly disable paywalling even when config/env values exist.options.ap2promotes an Agent Payments Protocol extension entry into the manifest.options.trustpushes ERC-8004 trust metadata into the manifest.options.entrypointspre-registers entrypoints without additional calls.options.useConfigPaymentsinstructs the server to reuse resolved config defaults whenoptions.paymentsis omitted.
The return value exposes:
app— the underlying Hono instance you can serve with Bun, Cloudflare Workers, etc.addEntrypoint(def)— register more entrypoints at runtime.config— the resolvedResolvedAgentKitConfigafter env and runtime overrides.payments— the activePaymentsConfig(if paywalling is enabled) orundefined.
Example with Hono Adapter:
import { z } from 'zod';
import { createAgentApp } from '@lucid-agents/agent-kit-hono';
const { app, addEntrypoint } = createAgentApp({
name: 'hello-agent',
version: '0.1.0',
description: 'Echoes whatever you pass in',
});
addEntrypoint({
key: 'echo',
description: 'Echo a message',
input: z.object({ text: z.string() }),
async handler({ input }) {
return {
output: { text: String(input.text ?? '') },
usage: { total_tokens: String(input.text ?? '').length },
};
},
});
export default app;Example with TanStack Adapter:
import { z } from 'zod';
import { createTanStackRuntime } from '@lucid-agents/agent-kit-tanstack';
const { runtime, handlers } = createTanStackRuntime({
name: 'hello-agent',
version: '0.1.0',
description: 'Echoes whatever you pass in',
});
runtime.addEntrypoint({
key: 'echo',
description: 'Echo a message',
input: z.object({ text: z.string() }),
async handler({ input }) {
return {
output: { text: String(input.text ?? '') },
usage: { total_tokens: String(input.text ?? '').length },
};
},
});
const { agent } = runtime;
export { agent, handlers, runtime };Supported Networks
Lucid-agents supports payment receiving on multiple blockchain networks:
EVM Networks
base- Base mainnet (L2)base-sepolia- Base Sepolia testnetethereum- Ethereum mainnetsepolia- Ethereum Sepolia testnet
Solana Networks
solana- Solana mainnetsolana-devnet- Solana devnet
Address Formats
- EVM: 0x-prefixed hex (42 characters) - e.g.,
0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0 - Solana: Base58 encoding (~44 characters, no prefix) - e.g.,
9yPGxVrYi7C5JLMGjEZhK8qQ4tn7SzMWwQHvz3vGJCKz
Example with Solana
const { app, addEntrypoint } = createAgentApp(
{
name: 'solana-agent',
version: '1.0.0',
description: 'Agent accepting Solana USDC payments',
},
{
config: {
payments: {
payTo: '9yPGxVrYi7C5JLMGjEZhK8qQ4tn7SzMWwQHvz3vGJCKz', // Solana address
network: 'solana-devnet',
facilitatorUrl: 'https://facilitator.daydreams.systems',
defaultPrice: '10000', // 0.01 USDC (6 decimals)
},
},
useConfigPayments: true,
}
);
addEntrypoint({
key: 'translate',
description: 'Translate text',
input: z.object({ text: z.string(), target: z.string() }),
async handler({ input }) {
// Your translation logic
return {
output: { translated: `Translated: ${input.text}` },
};
},
});SPL Token Addresses
For Solana payments, USDC addresses are:
- Mainnet USDC:
EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v - Devnet USDC:
Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr
Entrypoints
EntrypointDef describes a unit of work. Each entrypoint becomes two HTTP endpoints:
POST /entrypoints/:key/invoke— always available; returns JSON{ run_id, status, output?, usage?, model? }.POST /entrypoints/:key/stream— only registered whenstreamingandstreamare provided; streamsrun-start,delta,text,asset,control,error, andrun-endevents over SSE.
Field highlights:
input/outputaccept Zod schemas and automatically drive validation and manifest JSON schema generation.handler(ctx)handles non-streaming invocations.stream(ctx, emit)emitsStreamPushEnvelopes and finishes with aStreamResult.priceaccepts either a single string or{ invoke?, stream? };networkcan override the global payment network per entrypoint.
addEntrypoint({
key: 'stream',
description: 'Streams characters back to the caller',
input: z.object({ prompt: z.string() }),
streaming: true,
price: { stream: '2500' },
async stream({ input }, emit) {
for (const ch of input.prompt ?? '') {
await emit({ kind: 'delta', delta: ch, mime: 'text/plain' });
}
return { output: { done: true } };
},
});HTTP routes
Every agent app exposes the following for free:
GET /health→{ ok: true, version }GET /entrypoints→{ items: Array<{ key, description?, streaming }> }GET /.well-known/agent.jsonand/.well-known/agent-card.json→ full manifest (skills, schemas, pricing, trust metadata, AP2 extension, etc.)POST /entrypoints/:key/invokeand (optional)POST /entrypoints/:key/streamas described above.GET /→ lightweight HTML page that renders the manifest (handy for local inspection).
Configuration & Environment
agent-kit keeps configuration centralized so every helper resolves the same values.
- Defaults live in
src/config.ts(facilitator, pay-to address, network, wallet API). - Environment variables override defaults automatically:
FACILITATOR_URL,PAYMENTS_RECEIVABLE_ADDRESS,NETWORK,DEFAULT_PRICE,LUCID_API_URL/VITE_API_URL,AGENT_WALLET_MAX_PAYMENT_BASE_UNITS, andAGENT_WALLET_MAX_PAYMENT_USDC. configureAgentKit(overrides)merges values at runtime; use it inside tests or before callingcreateAgentApp.getAgentKitConfig()returns the resolved values;resetAgentKitConfigForTesting()clears overrides.
The helper paymentsFromEnv({ defaultPrice? }) returns the currently resolved PaymentsConfig, honouring inline config and environment values.
import {
configureAgentKit,
getAgentKitConfig,
paymentsFromEnv,
} from '@lucid-agents/agent-kit';
configureAgentKit({
payments: { defaultPrice: '750' },
wallet: { walletApiUrl: 'https://wallets.example' },
});
const config = getAgentKitConfig();
console.log(config.payments.facilitatorUrl); // resolved facilitator
console.log(config.wallet.walletApiUrl); // resolved wallet API base URL
console.log(paymentsFromEnv({ defaultPrice: '1000' })); // reuse inside handlersPayments & Monetization
When a PaymentsConfig is active, createAgentApp automatically wraps invoke/stream routes with the x402-hono middleware via withPayments. Pricing resolution order:
entrypoint.price(string or object).PaymentsConfig.defaultPrice(from inline config/env).- No paywall if neither is defined.
resolveEntrypointPrice(entrypoint, payments, kind) encapsulates the merge logic.
For authenticated wallet access, pair your agent with
@lucid-agents/agent-auth and reuse the generated SDK surface:
import { AgentRuntime } from '@lucid-agents/agent-auth';
import { createRuntimePaymentContext } from '@lucid-agents/agent-kit';
const { runtime } = await AgentRuntime.load({
wallet: {
signer: {
async signChallenge(challenge) {
// sign however your environment requires
return `signed:${challenge.id}`;
},
},
},
loader: {
overrides: {
baseUrl: process.env.LUCID_API_URL,
agentRef: process.env.AGENT_REF,
credentialId: process.env.CREDENTIAL_ID,
scopes: ['agents.read'],
},
},
});
const token = await runtime.ensureAccessToken();
const agents = await runtime.api.listAgents();
console.log('active bearer token', token.slice(0, 12), agents.items.length);
// Wrap fetch with x402 payments using the runtime-managed wallet
const { fetchWithPayment } = await createRuntimePaymentContext({
runtime,
});
const paidResponse = await fetchWithPayment?.('https://paid.endpoint/api', {
method: 'POST',
body: JSON.stringify({ prompt: 'charge me' }),
headers: { 'content-type': 'application/json' },
});
console.log('paid response', await paidResponse?.json());Manifest, AP2, and Discovery
buildManifest({ meta, registry, origin, payments, ap2, trust }) powers the well-known endpoints. It produces an A2A-compatible AgentCard that includes:
skills[]mirroring entrypoints and their schemas.capabilities.streamingwhen any entrypoint offers SSE.payments[]with x402 metadata when monetization is active.- AP2 extension entries when
ap2is supplied or when payments are enabled (defaults to a required merchant role). - Trust metadata (
registrations,trustModels, validation URIs) fromTrustConfig.
You rarely need to call buildManifest directly; createAgentApp handles it automatically, but the function is exported when you want to generate manifests for static hosts.
Trust & Identity (ERC-8004)
Trust metadata is modelled by TrustConfig. For ERC-8004 identity management, use the dedicated @lucid-agents/agent-kit-identity package:
import {
createAgentIdentity,
getTrustConfig,
} from '@lucid-agents/agent-kit-identity';
// Register agent identity with auto-registration
const identity = await createAgentIdentity({
domain: 'agent.example.com',
autoRegister: true,
chainId: 84532,
trustModels: ['feedback', 'inference-validation'],
});
// Use in your agent app
const { app } = createAgentApp(
{ name: 'my-agent', version: '1.0.0' },
{ trust: getTrustConfig(identity) }
);
console.log(`Agent ID: ${identity.record?.agentId}`);
console.log(`Status: ${identity.status}`);The package also exports lower-level helpers for advanced use cases:
createIdentityRegistryClient({ address, chainId, publicClient, walletClient })— direct registry access for advanced workflows.signAgentDomainProof({ domain, address, chainId, signer })— manually sign domain ownership proofs.buildTrustConfigFromIdentity(record, { signature, chainId, namespace, trustOverrides })— convert registry records intoTrustConfig.
See @lucid-agents/agent-kit-identity documentation for complete examples and API reference.
x402 + AxFlow utilities
For downstream components that need to call LLMs with paid fetches, the utils folder exposes:
createX402Fetch({ account, fetchImpl })andaccountFromPrivateKey(privateKey)— wrap a fetch implementation with x402 payments.createX402LLM(options)— compose a paid fetch with@ax-llm/ax.createAxLLMClient({ provider, model, apiKey, temperature, x402, logger })— ergonomic wrapper that reads env defaults (OPENAI_API_KEY,AX_*,AXLLM_*) and falls back to gpt-5/OpenAI. It returns{ ax, isConfigured }.
Miscellaneous utilities
toJsonSchemaOrUndefined(zodSchema)— safe JSON-schema conversion.normalizeAddress,sanitizeAddress,toCaip10— address manipulation helpers used by the trust layer.defaults— exported constants describing the built-in facilitator URL, pay-to address, network, and API base URL.
