Netlify Functions
This guide explains how to run VoltAgent on Netlify Functions by reusing the same Hono-powered HTTP API that the Cloudflare Workers example exposes. The instructions mirror the examples/with-netlify-functions project.
Prerequisites​
- Node.js 20+
pnpmornpm- Netlify account and the
netlifyCLI (npm install -g netlify-cli) - OpenAI API key (VoltOps keys optional)
1. Generate project files​
Option A: VoltAgent CLI​
npm run volt deploy --target netlify
The command scaffolds a netlify.toml file with function defaults. Add netlify/functions/voltagent.ts and a VoltAgent entry file (src/index.ts) following the example below.
Option B: Manual setup​
- Create
netlify.toml(see sample in step 4). - Add
netlify/functions/voltagent.tswith the Netlify handler. - Configure VoltAgent in
src/index.tsand import it from the handler.
2. Environment variables​
Netlify Functions expose secrets through process.env, so you can rely on VoltAgent's default environment detection. Use the CLI to define keys:
netlify secrets:set OPENAI_API_KEY
netlify secrets:set VOLTAGENT_PUBLIC_KEY
netlify secrets:set VOLTAGENT_SECRET_KEY
3. VoltAgent setup​
Create the agent once and reuse it across invocations. The example keeps the serverless Hono provider so the same HTTP routes (agents, workflows, observability) stay available.
import { Agent, VoltAgent } from "@voltagent/core";
import { serverlessHono } from "@voltagent/serverless-hono";
import { openai } from "@ai-sdk/openai";
import { weatherTool } from "./tools";
const assistant = new Agent({
name: "netlify-function-agent",
instructions: "Answer user questions and call tools when needed.",
model: openai("gpt-4o-mini"),
tools: [weatherTool],
});
const voltAgent = new VoltAgent({
agents: { assistant },
serverless: serverlessHono(),
});
export function getVoltAgent() {
return voltAgent;
}
4. Netlify function handler​
Use the helper exported from @voltagent/serverless-hono to convert Lambda events into Fetch requests automatically.
import { createNetlifyFunctionHandler } from "@voltagent/serverless-hono";
import { getVoltAgent } from "../src/index";
const voltAgent = getVoltAgent();
export const handler = createNetlifyFunctionHandler(voltAgent);
5. netlify.toml​
[functions]
node_bundler = "esbuild"
directory = "netlify/functions"
[[redirects]]
from = "/*"
to = "/.netlify/functions/voltagent/:splat"
status = 200
force = true
The redirect sends every HTTP route (/agents, /observability, /workflows, …) to the same function, mimicking the Cloudflare Workers routing behaviour.
6. Run locally​
pnpm install
pnpm netlify dev
Use curl against http://localhost:8888/agents or other routes to validate.
7. Deploy​
pnpm netlify deploy --prod
Netlify prints the production URL when the deploy finishes. If you need build steps (TypeScript, bundling) add them to your Netlify build command.
Observability notes​
- The example keeps the in-memory span/log storage by default, exposed through
/observability/*routes. - When VoltOps credentials are present, OTLP exports run via fetch with retry; the Lambda execution waits for the response, so keep an eye on cold-start durations.
- VoltOps Console still falls back to HTTP polling because WebSockets are not available in the Netlify Function runtime.
Feature limitations​
- Model Context Protocol still requires a Node server. The current Netlify Function runtime does not expose stdio transports.
- libSQL memory adapter needs a TCP socket. For Netlify Functions use the in-memory adapter or an external Postgres/Supabase database.
Memory configuration examples​
- In-memory (default)
- PostgreSQL
- Supabase
import { Memory, InMemoryStorageAdapter } from "@voltagent/core";
const memory = new Memory({
storage: new InMemoryStorageAdapter(),
});
import { Memory } from "@voltagent/core";
import { PostgresMemoryAdapter, PostgresVectorAdapter } from "@voltagent/postgres";
const memory = new Memory({
storage: new PostgresMemoryAdapter({
connectionString: env.POSTGRES_URL,
}),
vector: new PostgresVectorAdapter({
connectionString: env.POSTGRES_URL,
}),
});
import { Memory } from "@voltagent/core";
import { SupabaseMemoryAdapter } from "@voltagent/supabase";
const memory = new Memory({
storage: new SupabaseMemoryAdapter({
url: env.SUPABASE_URL,
serviceRoleKey: env.SUPABASE_SERVICE_ROLE_KEY,
}),
});
Use netlify logs --target=production to tail production logs and confirm your agent runs as expected.