Deployment
Express / Node.js server
Section titled “Express / Node.js server”The most common deployment — an HTTP server that handles chat requests:
import express from 'express';import { Agent, anthropic, defineTool } from 'agentfootprint';import { agentObservability } from 'agentfootprint/observe';import { SSEFormatter } from 'agentfootprint/stream';
const app = express();app.use(express.json());
const provider = anthropic('claude-sonnet-4-20250514');
// Define tools once — shared across requestsconst lookupOrder = defineTool({ /* ... */ });
app.post('/chat', async (req, res) => { const { message, sessionId } = req.body;
// Create a NEW agent per request for isolation const obs = agentObservability(); const agent = Agent.create({ provider }) .system('You are a support agent.') .tool(lookupOrder) .recorder(obs) .streaming(true) .build();
// SSE streaming response res.setHeader('Content-Type', 'text/event-stream'); res.setHeader('Cache-Control', 'no-cache'); res.setHeader('Connection', 'keep-alive');
await agent.run(message, { onEvent: (event) => { res.write(SSEFormatter.format(event)); }, });
res.end();});
app.listen(3000);Concurrency
Section titled “Concurrency”Create a new agent instance per request. The Agent.create().build() call is lightweight — it builds an internal flowchart but doesn’t allocate heavy resources. The provider (LLM adapter) can be shared across requests.
// GOOD: shared provider, per-request agentconst provider = anthropic('claude-sonnet-4-20250514');
app.post('/chat', async (req, res) => { const agent = Agent.create({ provider }) // lightweight — new per request .system('You are helpful.') .build();
const result = await agent.run(req.body.message); res.json({ content: result.content });});// BAD: shared agent across requests — narrative and state will bleedconst agent = Agent.create({ provider }).build(); // DON'T share this
app.post('/chat', async (req, res) => { const result = await agent.run(req.body.message); // race conditions});Docker
Section titled “Docker”FROM node:22-slimWORKDIR /appCOPY package*.json ./RUN npm ci --productionCOPY . .EXPOSE 3000CMD ["node", "dist/server.js"]docker build -t my-agent .docker run -p 3000:3000 -e ANTHROPIC_API_KEY=sk-ant-... my-agentEnvironment variables
Section titled “Environment variables”| Variable | Description |
|---|---|
ANTHROPIC_API_KEY | Anthropic API key (for AnthropicAdapter) |
OPENAI_API_KEY | OpenAI API key (for OpenAIAdapter) |
AWS_REGION | AWS region (for BedrockAdapter) |
AWS_ACCESS_KEY_ID | AWS credentials (or use IAM roles) |
Never hardcode API keys — use environment variables or a secrets manager.
Serverless (AWS Lambda)
Section titled “Serverless (AWS Lambda)”import { Agent, bedrock } from 'agentfootprint';
const provider = bedrock('anthropic.claude-sonnet-4-20250514-v1:0');
export const handler = async (event: any) => { const { message } = JSON.parse(event.body);
const agent = Agent.create({ provider }) .system('You are helpful.') .build();
const result = await agent.run(message);
return { statusCode: 200, body: JSON.stringify({ content: result.content }), };};For AWS AgentCore (managed serverless with VM isolation), see the AgentCore integration.
Health check
Section titled “Health check”Add a health endpoint for Kubernetes, ECS, or load balancer probes:
app.get('/health', (_req, res) => { res.json({ status: 'ok', uptime: process.uptime() });});Graceful shutdown
Section titled “Graceful shutdown”Drain in-flight requests before stopping. Use AbortController to cancel running agents:
const activeControllers = new Set<AbortController>();
app.post('/chat', async (req, res) => { const controller = new AbortController(); activeControllers.add(controller);
try { const agent = Agent.create({ provider }).build(); const result = await agent.run(req.body.message, { signal: controller.signal, // agent respects AbortSignal }); res.json({ content: result.content }); } finally { activeControllers.delete(controller); }});
// On SIGTERM: cancel all running agents, then exitprocess.on('SIGTERM', () => { for (const c of activeControllers) c.abort(); server.close(() => process.exit(0));});Production checklist
Section titled “Production checklist”- API keys in environment variables (not in code)
-
agentObservability()attached to every agent - Error handling with
withRetry/withFallback - Per-request agent instances (not shared)
- Token/cost monitoring via CloudWatch or your observability stack
-
maxIterationsset to prevent runaway loops - Streaming enabled for user-facing agents
- Tests with
mock()in CI pipeline