multimodal/websites/tarko/docs/en/guide/deployment/server.mdx
Tarko Agent Server is a production-ready server component built on top of Tarko Agent Core. It provides session management, storage capabilities, and a standardized HTTP/WebSocket API for agent interactions.
npm install @tarko/agent-server
The easiest way to start a server:
npx tarko serve my-agent.ts
import { AgentServer } from '@tarko/agent-server';
import myAgent from './my-agent';
const server = new AgentServer({
agent: myAgent,
port: 8888,
storage: {
type: 'sqlite',
path: '~/.tarko'
}
});
await server.start();
console.log('Server running on http://localhost:8888');
Represents a complete agent interaction context, containing:
A single request executed within a session:
interface ServerConfig {
agent: Agent;
port?: number;
host?: string;
basePath?: string; // Default: '/api/v1'
cors?: CorsOptions;
storage?: StorageConfig;
auth?: AuthConfig;
sharing?: SharingConfig;
}
interface StorageConfig {
type: 'memory' | 'file' | 'sqlite' | 'redis';
path?: string; // For file/sqlite storage
connectionString?: string; // For redis storage
options?: Record<string, any>;
}
const server = new AgentServer({
agent: myAgent,
port: 8888,
storage: {
type: 'sqlite',
path: '~/.tarko/sessions.db'
},
cors: {
origin: ['http://localhost:3000'],
credentials: true
},
auth: {
enabled: true,
provider: 'jwt',
secret: process.env.JWT_SECRET
}
});
POST /api/v1/sessions/create
Response:
{
"sessionId": "unique-session-id"
}
GET /api/v1/sessions
Response:
{
"sessions": [
{
"id": "session-id-1",
"createdAt": 1622548800000,
"updatedAt": 1622548800000,
"name": "Session Name",
"workspace": "/path/to/workspace",
"tags": ["tag1", "tag2"]
}
]
}
GET /api/v1/sessions/details?sessionId=session-id
POST /api/v1/sessions/update
Request:
{
"sessionId": "session-id",
"name": "New Session Name",
"tags": ["updated", "tags"]
}
POST /api/v1/sessions/delete
Request:
{
"sessionId": "session-id"
}
POST /api/v1/sessions/query
Text Query:
{
"sessionId": "session-id",
"query": "Hello, how can you help me?"
}
Multimodal Query:
{
"sessionId": "session-id",
"query": [
{ "type": "text", "text": "What's in this image?" },
{
"type": "image_url",
"image_url": {
"url": "data:image/jpeg;base64,..."
}
}
]
}
POST /api/v1/sessions/query/stream
Returns Server-Sent Events (SSE) stream with real-time agent responses.
POST /api/v1/sessions/abort
Request:
{
"sessionId": "session-id"
}
For simple use cases, execute queries without explicit session management:
POST /api/v1/oneshot/query
Request:
{
"query": "What's the weather like?",
"sessionName": "Weather Check",
"sessionTags": ["weather", "oneshot"]
}
POST /api/v1/oneshot/query/stream
For real-time bidirectional communication:
import { io } from 'socket.io-client';
const socket = io('http://localhost:8888');
// Join a session
socket.emit('join-session', 'session-id');
// Listen for agent events
socket.on('agent-event', (event) => {
console.log('Agent event:', event);
});
// Send a query
socket.emit('send-query', {
sessionId: 'session-id',
query: 'Hello!'
});
// Abort query
socket.emit('abort-query', { sessionId: 'session-id' });
Tarko Server uses structured event streams following the Agent Protocol:
interface AgentEvent {
id: string;
type: string;
timestamp: number;
sessionId: string;
data: any;
}
Example Event Stream:
[
{
"id": "evt-1",
"type": "user_message",
"timestamp": 1622548800000,
"sessionId": "session-1",
"data": { "content": "Hello!" }
},
{
"id": "evt-2",
"type": "assistant_message_start",
"timestamp": 1622548800100,
"sessionId": "session-1",
"data": {}
},
{
"id": "evt-3",
"type": "assistant_message_delta",
"timestamp": 1622548800150,
"sessionId": "session-1",
"data": { "delta": "Hello! How" }
},
{
"id": "evt-4",
"type": "tool_call",
"timestamp": 1622548800200,
"sessionId": "session-1",
"data": {
"name": "get_weather",
"arguments": { "location": "San Francisco" }
}
}
]
storage: {
type: 'memory'
// Data lost on server restart
}
storage: {
type: 'file',
path: '~/.tarko/sessions'
}
storage: {
type: 'sqlite',
path: '~/.tarko/sessions.db'
}
storage: {
type: 'redis',
connectionString: 'redis://localhost:6379',
options: {
keyPrefix: 'tarko:',
db: 0
}
}
const server = new AgentServer({
auth: {
enabled: true,
provider: 'jwt',
secret: process.env.JWT_SECRET,
expiresIn: '24h'
}
});
const server = new AgentServer({
auth: {
enabled: true,
provider: 'custom',
authenticate: async (req) => {
const token = req.headers.authorization;
// Custom authentication logic
return { userId: 'user-123', permissions: ['read', 'write'] };
}
}
});
Extend server functionality with custom middleware:
import express from 'express';
const server = new AgentServer(config);
const app = server.getApp();
// Add custom routes
app.get('/custom/health', (req, res) => {
res.json({ status: 'custom-ok', timestamp: Date.now() });
});
// Add middleware
app.use('/api/v1', express.json({ limit: '50mb' }));
// Custom error handling
app.use((error, req, res, next) => {
console.error('Server error:', error);
res.status(500).json({ error: 'Internal server error' });
});
await server.start();
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
EXPOSE 8888
CMD ["npx", "tarko", "serve", "agent.ts", "--port", "8888"]
# .env
PORT=8888
NODE_ENV=production
JWT_SECRET=your-secret-key
STORAGE_TYPE=sqlite
STORAGE_PATH=/data/sessions.db
OPENAI_API_KEY=your-api-key
// production.config.ts
export default {
server: {
port: process.env.PORT || 8888,
storage: {
type: 'sqlite',
path: process.env.STORAGE_PATH || '/data/sessions.db'
},
auth: {
enabled: true,
provider: 'jwt',
secret: process.env.JWT_SECRET
},
cors: {
origin: process.env.ALLOWED_ORIGINS?.split(',') || ['https://your-domain.com'],
credentials: true
}
}
};
GET /api/v1/health
Response:
{
"status": "ok",
"timestamp": 1622548800000,
"uptime": 3600,
"memory": {
"used": 123456789,
"total": 1073741824
}
}
const server = new AgentServer({
logging: {
level: 'info',
format: 'json',
transports: [
{ type: 'console' },
{ type: 'file', filename: 'tarko-server.log' }
]
}
});