VoltAgent Server Architecture
VoltAgent 1.x introduces a framework-agnostic server architecture that separates core functionality from server implementation. This design allows you to use different server frameworks or create custom implementations.
Architecture Overview
The server system consists of two main packages:
@voltagent/server-core
The core package provides framework-agnostic components:
- Route Definitions - Standardized route specifications (
/packages/server-core/src/routes/definitions.ts
) - Request Handlers - Business logic for all endpoints
- Base Provider - Abstract class for server implementations
- WebSocket Support - Real-time communication infrastructure
- Auth Interface - Pluggable authentication system
@voltagent/server-hono
The official server implementation using Hono:
- Fast, lightweight web framework
- Built-in OpenAPI and Swagger UI support
- TypeScript-first with excellent DX
- Works with Node.js, Bun, Deno, and Edge runtimes
Core Concepts
Server Provider Interface
Every server implementation must satisfy the IServerProvider
interface:
interface IServerProvider {
start(): Promise<{ port: number }>;
stop(): Promise<void>;
isRunning(): boolean;
}
Server Provider Factory
Server providers are created using factory functions:
type ServerProviderFactory = (deps: ServerProviderDeps) => IServerProvider;
The ServerProviderDeps
provides access to:
agentRegistry
- Manage and access agentsworkflowRegistry
- Manage and access workflowslogger
- Logging infrastructurevoltOpsClient
- Telemetry and prompt managementobservability
- OpenTelemetry integration
Base Server Provider
The BaseServerProvider
class handles common server tasks:
abstract class BaseServerProvider implements IServerProvider {
// Manages port allocation
// Sets up WebSocket server
// Handles graceful shutdown
// Prints startup messages
protected abstract startServer(port: number): Promise<Server>;
protected abstract stopServer(): Promise<void>;
}
Using the Hono Server
Basic Setup
import { VoltAgent } from "@voltagent/core";
import { honoServer } from "@voltagent/server-hono";
new VoltAgent({
agents: { myAgent },
server: honoServer({
port: 3141,
enableSwaggerUI: true,
}),
});
Configuration Options
interface HonoServerConfig {
// Port to listen on (default: 3141)
port?: number;
// Enable Swagger UI (default: true in dev, false in prod)
enableSwaggerUI?: boolean;
// Configure the Hono app directly
configureApp?: (app: OpenAPIHono) => void | Promise<void>;
// Authentication provider
auth?: AuthProvider;
}
Advanced Configuration
Access the Hono app directly for custom middleware and routes:
new VoltAgent({
agents: { myAgent },
server: honoServer({
configureApp: (app) => {
// Add custom middleware
app.use("/admin/*", authMiddleware);
// Add custom routes
app.get("/health", (c) => c.json({ status: "ok" }));
// Create route groups
const api = app.basePath("/api/v2");
api.get("/users", getUsersHandler);
// Add rate limiting
app.use("*", rateLimiter());
},
}),
});
Port Management
VoltAgent includes intelligent port management:
- Default Port: 3141
- Fallback Ports: If default is taken, tries 4310, 1337, etc.
- Port Allocation: Central manager prevents conflicts
- Graceful Release: Ports are released on shutdown
WebSocket Support
WebSocket is automatically enabled for real-time features:
- Base path:
/ws
- Endpoints:
/ws
– connection test/echo/ws/logs
– real-time logs (filterable via query params)/ws/observability
– spans and logs for observability (optionalentityId
/entityType
filters)
- Protocol: Standard WebSocket with JSON messages
Note: The Hono server config does not currently expose WebSocket configuration options. WebSockets are on by default and use the /ws
path. If you need to change the path or behavior, implement a custom provider using @voltagent/server-core
.
Route Registration
Routes are defined in a framework-agnostic format:
const AGENT_ROUTES = {
listAgents: {
method: "get" as const,
path: "/agents",
summary: "List all registered agents",
tags: ["Agent Management"],
responses: {
200: { description: "Success" },
500: { description: "Server error" },
},
},
// ... more routes
};
Server implementations use these definitions to:
- Generate OpenAPI documentation
- Register routes with proper handlers
- Ensure consistency across implementations
Middleware and Plugins
The Hono server supports standard middleware:
configureApp: (app) => {
// CORS
app.use("*", cors());
// Logging
app.use("*", logger());
// Compression
app.use("*", compress());
};
Graceful Shutdown
VoltAgent provides comprehensive shutdown handling to ensure clean resource cleanup and compatibility with other frameworks.
How Shutdown Works
When VoltAgent receives a shutdown signal (SIGINT/SIGTERM):
- Server stops first - Prevents new requests from being accepted
- Workflows suspend - All active workflows are gracefully suspended
- Telemetry shuts down - Observability resources are properly closed
- Process exits (conditionally) - Only if VoltAgent is the sole signal handler
Automatic Shutdown Handling
VoltAgent automatically registers SIGINT and SIGTERM handlers that clean up resources:
const voltAgent = new VoltAgent({
agents: { myAgent },
server: honoServer({ port: 3141 }),
});
// When you press Ctrl+C or the process receives SIGTERM:
// 1. Server stops accepting new connections
// 2. Active workflows are suspended
// 3. Telemetry is flushed and closed
// 4. Process exits (if no other handlers exist)
Programmatic Shutdown
Use the shutdown()
method for manual resource cleanup:
const voltAgent = new VoltAgent({
agents: { myAgent },
server: honoServer({ port: 3141 }),
});
// Later in your application
await voltAgent.shutdown();
// All resources are now cleaned up
Framework Integration
VoltAgent respects other frameworks' shutdown handlers. When multiple handlers exist (e.g., from Adonis, NestJS, Express), VoltAgent:
- Performs its cleanup (server, workflows, telemetry)
- Does not call
process.exit()
- Allows other handlers to complete their cleanup
- Lets the framework control the final exit
Example with Express:
import express from "express";
import { VoltAgent } from "@voltagent/core";
import { honoServer } from "@voltagent/server-hono";
const app = express();
const voltAgent = new VoltAgent({
agents: { myAgent },
server: honoServer({ port: 3141 }),
});
// Express graceful shutdown
process.on("SIGTERM", async () => {
console.log("Express: Closing server...");
// VoltAgent already cleaned up its resources
// Now Express can do its cleanup
server.close(() => {
console.log("Express: Server closed");
process.exit(0);
});
});
Server Provider Shutdown
The BaseServerProvider
handles common shutdown tasks:
- Closes WebSocket connections
- Stops the HTTP server
- Releases allocated ports
- Ensures all pending operations complete
Custom server providers should implement proper cleanup:
class CustomServerProvider extends BaseServerProvider {
protected async stopServer(): Promise<void> {
// Close all connections
await this.closeConnections();
// Stop the server
if (this.server) {
await new Promise((resolve) => {
this.server.close(resolve);
});
}
// Clean up any custom resources
await this.cleanupCustomResources();
}
}
Shutdown Order Matters
Resources are cleaned up in a specific order to prevent issues:
- Server first - Stop accepting new work
- Workflows second - Suspend active operations
- Telemetry last - Ensure all events are recorded
This order ensures that:
- No new requests arrive during cleanup
- Active operations can complete or suspend gracefully
- All telemetry data is captured before shutdown
Best Practices
- Use the Official Implementation: Start with
@voltagent/server-hono
unless you have specific requirements - Leverage configureApp: Add custom routes and middleware through the configuration
- Follow Route Definitions: Use the standardized route definitions for consistency
- Handle Errors Properly: Implement proper error handling in custom providers
- Support Graceful Shutdown: Always clean up resources properly
- Test Shutdown Behavior: Verify your application exits cleanly in different scenarios
- Use
shutdown()
in Tests: Ensure proper cleanup in test suites
Next Steps
- Learn about Authentication to secure your API
- Explore Custom Endpoints to extend the API
- Check Agent Endpoints for API usage