worken npm package
The worken package is the official TypeScript SDK for Worken. It includes:
- API client — typed wrappers for all Worken REST endpoints
- MCP server — host your own tools and expose them to Worken agents via the Model Context Protocol
- TUI — connect to any Worken agent from the terminal for interactive sessions and debugging
Installation
# SDK in your app
npm install worken
# or
bun add workenRequirements: Node.js 20+ or Bun 1.1+
For the CLI, install worken globally once:
npm install -g worken
# or
bun add -g workenCLI examples below assume worken is available in your PATH.
API Client
Initialisation
import { WorkenClient } from 'worken'
const worken = new WorkenClient({
apiKey: process.env.WORKEN_API_KEY,
baseUrl: 'https://api.worken.ru', // public REST API base URL
})By default WorkenClient talks to the public REST API at https://api.worken.ru using bearer API keys. Internal Worken services use a separate header-based API; external clients should always use project API keys as described in the API overview.
Bots
// List all bots
const bots = await worken.bots.list()
// Create a bot
const bot = await worken.bots.create({ name: 'Support Bot' })
// Get a bot
const bot = await worken.bots.get(botId)
// Update settings
await worken.bots.settings.update(botId, {
ai: {
instruction: 'You are a helpful assistant.',
model: { id: 'openai/gpt-4o-mini', temperature: 0.5 },
},
})
// Clone a bot (useful for A/B testing)
const clone = await worken.bots.clone(botId)
// Delete
await worken.bots.delete(botId)Chats & Threads
// List chats
const chats = await worken.chats.list()
// List threads in a chat
const threads = await worken.chats.threads.list(chatId)
// Stream a response
const stream = await worken.chats.threads.stream(chatId, threadId, {
messages: [{ role: 'user', content: 'Hello!' }],
})
for await (const chunk of stream) {
process.stdout.write(chunk.textDelta ?? '')
}
// Get messages
const messages = await worken.chats.threads.messages.list(chatId, threadId)
// Set thread mode
await worken.threads.setMode(threadId, 'manual')
// Send an operator message
await worken.threads.send(threadId, { text: 'Escalating to a human agent.' })Real-time events
// Subscribe to all thread events in the project
const stream = worken.threads.events()
for await (const event of stream) {
if (event.type === 'message.created') {
console.log(`New message in thread ${event.thread_id}`)
}
}
// Or for a single thread
const stream = worken.threads.events(threadId)Integrations
// List integrations
const integrations = await worken.integrations.list()
// Create a Telegram integration
const integration = await worken.integrations.create({
name: 'Telegram Support',
vendor: 'telegram',
auth_data: { token: process.env.TELEGRAM_TOKEN },
})
// Check credentials
const profile = await worken.integrations.getProfile(integration.id)
// Create and activate a chat
const chat = await worken.integrations.chats.create(integration.id, {
bot_id: botId,
name: 'Customer Support',
})
await worken.integrations.chats.setStatus(integration.id, chat.id, 'active')Billing
const account = await worken.billing.getAccount()
console.log(`Balance: ${account.credits} credits`)
const transactions = await worken.billing.transactions.list({ limit: 10 })
// Create a top-up invoice
const { payment_url } = await worken.billing.invoices.create({ offer_id: 'starter' })
console.log('Pay here:', payment_url)MCP Tool Hosting
The Model Context Protocol (MCP) lets you expose custom tools to Worken agents. Tools can look up data, call external APIs, write to databases — anything your business logic requires.
How it works
Your server (worken mcp) ←→ Worken agent (via MCP) ←→ User conversationThe Worken agent calls your tools during inference. The MCP server runs in your infrastructure — you control the code and data access.
Worken also exposes a managed MCP catalog for its own agents, covering domains like projects, virts/bots, integrations, billing, threads/messages, and vector stores — all backed by the public REST API (see the API reference).
Creating an MCP server
import { WorkenMcpServer } from 'worken/mcp'
import { z } from 'zod'
const server = new WorkenMcpServer({
name: 'my-tools',
version: '1.0.0',
})
// Register a tool
server.tool(
'get_order_status',
'Look up the status of a customer order by order ID',
{
order_id: z.string().describe('The order ID to look up'),
},
async ({ order_id }) => {
const order = await db.orders.findById(order_id)
if (!order) return { status: 'not_found' }
return {
status: order.status,
estimated_delivery: order.estimatedDelivery,
tracking_url: order.trackingUrl,
}
}
)
server.tool(
'create_support_ticket',
'Create a support ticket for a customer issue',
{
subject: z.string(),
description: z.string(),
priority: z.enum(['low', 'medium', 'high']).default('medium'),
customer_email: z.string().email().optional(),
},
async (params) => {
const ticket = await helpdesk.create(params)
return { ticket_id: ticket.id, url: ticket.url }
}
)
// Start the server (HTTP/SSE transport by default)
await server.listen({ port: 3100 })
console.log('MCP server running on http://localhost:3100/mcp')In production, the MCP HTTP/SSE endpoint is typically hosted by the apps/worken-mcp service and exposed as https://mcp.worken.ru/mcp; use http://localhost:3100/mcp only for local development.
MCP client configuration (hosted Worken catalog)
Most MCP-compatible clients let you register HTTP/SSE servers in a config file. To connect a generic MCP client to your Worken workspace, point it at https://mcp.worken.ru/mcp and pass the same project API key you use for the REST API as a bearer token:
{
"mcpServers": {
"worken": {
"url": "https://mcp.worken.ru/mcp",
"headers": {
"Authorization": "Bearer sk-your-project-api-key"
}
}
}
}Keep the key in your secret store or environment variables and avoid committing it to version control. The MCP server uses this key to call the public REST API on your behalf, so it has the same permissions and rate limits as direct REST calls.
Register the server with your bot
After deploying your MCP server, register its URL in the bot's tool settings:
await worken.bots.settings.update(botId, {
ai: {
tools: {
get_order_status: 'auto', // agent calls automatically
create_support_ticket: 'user_approve', // asks user before calling
},
mcp_servers: [
{ url: 'https://tools.yourcompany.com/mcp' },
],
},
})Tool approval policies
| Policy | Behaviour |
|---|---|
auto | Agent calls the tool without confirmation |
user_approve | Agent shows a confirmation card to the end user |
operator_approve | Agent pauses and notifies the operator for approval |
Running with stdio transport (for local development)
worken mcp --tools ./tools/index.ts --transport stdio// tools/index.ts
import { defineTool } from 'worken/mcp'
import { z } from 'zod'
export const getWeather = defineTool({
name: 'get_weather',
description: 'Get current weather for a city',
input: z.object({ city: z.string() }),
run: async ({ city }) => {
const res = await fetch(`https://wttr.in/${city}?format=j1`)
const data = await res.json()
return { temperature: data.current_condition[0].temp_C, city }
},
})MCP client configuration example
Many MCP clients accept a simple config that points them at the Worken MCP endpoint and sends an API key via headers:
const client = createMcpClient({
server: {
url: 'https://mcp.worken.ru/mcp',
headers: {
Authorization: `Bearer ${process.env.WORKEN_API_KEY!}`,
},
},
})TUI — Terminal UI
The TUI lets you chat with any Worken agent directly from your terminal. It is useful for:
- Debugging agent behaviour during development
- Quick conversations without opening the browser
- Scripting automated test dialogues
Interactive mode
worken chatThe TUI will prompt you to select a project and a bot, then open an interactive chat session:
┌─────────────────────────────────────────────────────┐
│ Worken TUI • Support Bot • thread_01j... │
├─────────────────────────────────────────────────────┤
│ │
│ Assistant: Hello! How can I help you today? │
│ │
│ You: What is your return policy? │
│ │
│ Assistant: Our return policy allows returns │
│ within 30 days of purchase. Items must be in │
│ original condition. Would you like me to start │
│ a return request? │
│ │
├─────────────────────────────────────────────────────┤
│ > Type your message... [Ctrl+C] │
└─────────────────────────────────────────────────────┘Connect to a specific bot
Skip the selection prompts by passing a bot ID:
worken chat --bot bot_01j...Or set the bot as the default for the project:
worken config set default-bot bot_01j...
worken chat # now always opens that botProgrammatic TUI (scripting)
Use the WorkenTui class for automated interactions — integration tests, demo scripts, etc.:
import { WorkenTui } from 'worken/tui'
const tui = new WorkenTui({
apiKey: process.env.WORKEN_API_KEY,
botId: 'bot_01j...',
})
const session = await tui.start()
const reply = await session.send('What is your return policy?')
console.log(reply.text)
await session.send('I want to return an item I bought last week.')
// Prints streamed response to stdout
await session.end()Inspect thread memory
worken memory --thread thread_01j...Prints the agent's working memory for that thread — useful for debugging what the model has retained.
View conversation history
worken history --thread thread_01j... --limit 50CLI reference
All commands accept --api-key to override the environment variable.
worken --helpUsage: worken <command> [options]
Commands:
chat Start an interactive chat session
mcp Start an MCP tool server
history Print thread message history
memory Print working memory for a thread
bots Manage bots (list, create, delete)
config Get/set local configuration
Options:
--api-key Worken API key (default: $WORKEN_API_KEY)
--project Project ID (default: first project)
--bot Bot ID
--thread Thread ID
--format Output format: table | json (default: table)
--version Show version
--help Show helpExamples
# List all bots in the project
worken bots list
# Create a bot and print its ID
worken bots create --name "Demo Bot" --format json | jq .id
# Tail live thread events
worken threads events --follow
# Start MCP server from a tools file
worken mcp --tools ./tools/index.ts --port 3100
# Run a single-turn test from a script
echo "Hello!" | worken chat --bot bot_01j... --no-interactiveConfiguration file
The CLI reads from ~/.config/worken/config.json:
{
"apiKey": "sk-...",
"defaultProject": "proj_01j...",
"defaultBot": "bot_01j...",
"baseUrl": "https://api.worken.ru"
}Or set values interactively:
worken config set api-key sk-...
worken config set default-bot bot_01j...TypeScript types
All types are exported from the root package for use in your own code:
import type {
Bot,
BotSettings,
Chat,
Thread,
Message,
Integration,
IntegrationVendor,
BillingAccount,
Transaction,
} from 'worken'