Swagger UI
Automatic OpenAPI documentation with interactive Swagger UI.
Overview
The agent server automatically generates OpenAPI documentation and provides an interactive Swagger UI for testing your API.
Enabling Swagger
const agentServer = createAgentServer({
basePath: '/api/agents',
storage,
swagger: {
enabled: true,
path: '/docs', // Default: '/docs'
title: 'My Agent API', // API title
version: '1.0.0', // API version
description: 'AI Agent REST API documentation',
},
});Accessing Documentation
Once enabled, you can access:
- Swagger UI:
{basePath}/docs - OpenAPI JSON:
{basePath}/docs/openapi.json
For example:
http://localhost:3000/api/agents/docshttp://localhost:3000/api/agents/docs/openapi.json
Configuration Options
interface SwaggerConfig {
// Enable/disable Swagger UI and the OpenAPI document
enabled: boolean;
// Path of the Swagger UI, relative to basePath (default: '/docs')
path?: string;
// API title (default: 'Agent Server API')
title?: string;
// API version (default: '1.0.0')
version?: string;
// API description (default: 'REST API for AI agents - manage conversations and messages')
description?: string;
}The document has one server entry, your basePath. For contact, license or other servers, take the document from generateOpenAPISpec and add them yourself (Programmatic access).
Example Configuration
const agentServer = createAgentServer({
basePath: '/api/agents',
storage,
swagger: {
enabled: true,
path: '/docs',
title: 'My AI Agent API',
version: '1.0.0',
description: 'REST API for AI agents built with @cognipeer/agent-server',
},
});Generated Endpoints
The OpenAPI document lists every route of the server - agents, conversations (including messages, runs, events, actions, remembered tools, feedback, export and bulk delete), files and tasks. A test holds server.getRoutes() and the document to each other, so a route cannot exist without an entry. The same routes, with request and response examples, are in REST Endpoints.
Authentication in Swagger
When auth.enabled is true, the document declares a BearerAuth scheme and applies it to every operation:
securitySchemes:
BearerAuth:
type: http
scheme: bearer
bearerFormat: JWTUse the "Authorize" button in Swagger UI to set your token. (The scheme describes a bearer header; if you changed auth.headerName, the UI's "Try it out" still sends Authorization.)
Schemas
components.schemas describes the request and response bodies of every route: Agent, Conversation, ConversationRuntime, Message, SendMessageRequest / SendMessageResponse, PendingAction, ResolveActionRequest, ListEventsResponse and WireEvent, CancelConversationResponse, FileRecord, AttachmentsCapability, SessionBudget, Task and its request and response types, the Stream*Event family, and Error. The Error schema lists every machine-readable error.code in its description.
Excluding Routes
Exclude routes from authentication while keeping them in docs:
auth: {
enabled: true,
provider: authProvider,
excludeRoutes: ['/docs', '/docs/*'], // Public access to docs
}Production Considerations
Disable in Production
You might want to disable Swagger in production:
swagger: {
enabled: process.env.NODE_ENV !== 'production',
}Or Use Authentication
Keep it enabled but require authentication:
auth: {
enabled: true,
provider: authProvider,
// Don't exclude /docs routes
excludeRoutes: [],
}What the spec covers
The spec lists every route of the server (a test holds server.getRoutes() and the document to each other), the request and response schemas, and the machine-readable error.codes in the description of the Error schema. It is generated from the configuration: auth.enabled adds the bearer scheme, title, version and description come from swagger, and the one server entry is your basePath. The document the server itself serves at <basePath>/docs/openapi.json is built from the statically registered agents; agents that config.agents(ctx) resolves per request are not part of it.
The UI loads from a CDN
The built-in page loads Swagger UI's script and stylesheet from unpkg.com (swagger-ui-dist@5). A server with no outbound internet access, or a page served with a strict Content-Security-Policy, needs its own copy: set swagger.enabled: false and serve your own page next to generateOpenAPISpec (Customizing the UI).
Customizing the UI
The generated Swagger UI uses the default SwaggerUI theme. For custom styling, you can:
- Serve your own Swagger UI:
// Disable built-in Swagger
swagger: { enabled: false }
// Serve custom Swagger UI
app.get('/docs', (req, res) => {
res.send(customSwaggerHTML);
});
// Serve OpenAPI spec
app.get('/docs/openapi.json', async (req, res) => {
res.json(generateOpenAPISpec(agentServer.getConfig(), await agentServer.getAgentsFor()));
});- Use a different documentation tool:
// Generate OpenAPI spec
import { generateOpenAPISpec } from '@cognipeer/agent-server';
const spec = generateOpenAPISpec(agentServer.getConfig(), await agentServer.getAgentsFor());
// Use with Redoc, Rapidoc, etc.Programmatic Access
Access the OpenAPI spec programmatically:
// Get the OpenAPI specification
import { generateOpenAPISpec } from '@cognipeer/agent-server';
const spec = generateOpenAPISpec(agentServer.getConfig(), await agentServer.getAgentsFor());
// Save to file
fs.writeFileSync('openapi.json', JSON.stringify(spec, null, 2));
// Use for code generation
generateClient(spec);Troubleshooting
| Symptom | Cause and fix |
|---|---|
/docs answers 401 | Token auth covers the docs routes unless they are excluded: add /docs and /docs/* to auth.excludeRoutes (the routes skip resolveContext on their own). |
/docs is a blank page | The Swagger UI assets could not be loaded from unpkg.com (offline, firewall or CSP). See The UI loads from a CDN. |
| "Try it out" calls the wrong URL | The document's one server is basePath as the server knows it. If a proxy adds a prefix, post-process the spec from generateOpenAPISpec and serve it yourself. |
| An agent of mine is missing in the document | It is resolved per request (config.agents(ctx)); only statically registered agents are in the served document. |

