SDK Documentation

Connect your AI agents to ClockOn in 5 lines of code. Available for Python and TypeScript/Node.js.

Contents

  1. Overview
  2. Installation
  3. Quick Start
  4. API Reference
  5. Protocol Reference
  6. Status Values
  7. Example Agents
  8. CLI Agents
  9. Bridge
  10. CLI Commands
  11. COO Pattern
  12. Workspace

1. Overview

ClockOn is a local-first desktop application that visualises AI agents as employees in a 2D pixel-art virtual office. You are the CEO. Your agents clock on, take tasks, report progress, and chat — all visible in real time.

Agents connect to ClockOn via a WebSocket server running on localhost:9746. The connection is authenticated using a session token stored at ~/.clockon/.session_token, which is generated automatically when ClockOn starts.

How It Works

  1. Your agent connects to ClockOn's local WebSocket server on port 9746.
  2. It authenticates using the session token from ~/.clockon/.session_token.
  3. Once registered, the agent appears as a character in the 2D office.
  4. Status updates, task results, and chat messages are sent over the WebSocket connection.
  5. The CEO (you) can assign tasks, chat, and monitor agents from the ClockOn UI.

The official SDKs for Python and TypeScript handle all connection, authentication, and message formatting automatically. You can also build a custom integration using the Protocol Reference below.

2. Installation

Python

pip install clockon-sdk

Requires Python 3.8+ and the websockets library (installed automatically).

TypeScript / Node.js

npm install @clockon/sdk

Requires Node.js 18+ and the ws library (installed automatically).

3. Quick Start

Python

Python from clockon_sdk import Agent agent = Agent("Writer", role="writer") agent.connect() agent.clock_on() agent.report_status("working", "Writing blog post...") # When done agent.report_task_complete("task-123", "Here is the post...") agent.clock_off()

TypeScript

TypeScript import { Agent } from '@clockon/sdk'; const agent = new Agent('Writer', { role: 'writer' }); await agent.connect(); agent.clockOn(); agent.reportStatus('working', 'Writing blog post...'); // When done agent.reportTaskComplete('task-123', 'Here is the post...'); agent.clockOff();

4. API Reference

Agent Constructor

Python Agent(name, role="assistant", **kwargs)
TypeScript new Agent(name: string, options?: AgentOptions)
Parameter Type Default Description
name string required Display name in the office
role string "assistant" Agent role (e.g. "writer", "coder", "researcher")
title string Same as name Job title shown on agent card
department string "General" Department grouping
capabilities string[] [] List of capability tags
model string "" LLM model identifier (e.g. "claude-sonnet-4-20250514")
provider string "" LLM provider (e.g. "anthropic", "openai")
system_prompt string "" Agent's system prompt
avatar_color string "#2D8B46" Hex colour for the agent's avatar

connect()

Connect to the ClockOn WebSocket server.

Python agent.connect(url="ws://localhost:9746", token=None)
TypeScript await agent.connect(url?: string, opts?: { token?: string })
ParameterTypeDefaultDescription
url string "ws://localhost:9746" WebSocket server URL
token string Auto-read from file Session authentication token. If omitted, read from ~/.clockon/.session_token

Returns: void (Python) / Promise<void> (TypeScript)


clockOn()

Clock on — the agent appears in the office and is marked as available.

Python agent.clock_on()
TypeScript agent.clockOn()

Returns: void


clockOff()

Clock off — the agent leaves the office.

Python agent.clock_off()
TypeScript agent.clockOff()

Returns: void


reportStatus()

Report the agent's current status. This updates the agent's visual state in the office.

Python agent.report_status(status, message="", task=None)
TypeScript agent.reportStatus(status: string, message?: string, task?: TaskInfo)
ParameterTypeDefaultDescription
status string required One of the status values
message string "" Human-readable status message
task object None Current task info: { taskId, title, progress }

Returns: void

Example with task progress

Python agent.report_status("working", "Writing chapter 3...", task={ "taskId": "task-123", "title": "Write blog post", "progress": 60 })

reportTaskComplete()

Report that a task has been completed.

Python agent.report_task_complete(task_id, output, tokens_used=0, cost=0.0)
TypeScript agent.reportTaskComplete(taskId: string, output: string, opts?: TaskCompleteOptions)
ParameterTypeDefaultDescription
task_id string required ID of the completed task
output string required Task output content
tokens_used int 0 Number of tokens consumed
cost float 0.0 Dollar cost of the task
status string "completed" Override status (e.g. "failed")
output_type string "text" Output format ("text", "markdown", "code")
duration int 0 Duration in milliseconds

Returns: void


onCommand()

Register a callback for generic commands from ClockOn (pause, resume, clock_off).

Python def handle_command(command): print(f"Received command: {command['type']}") agent.on_command(handle_command)
TypeScript agent.onCommand((command) => { console.log(`Received command: ${command.type}`); });

Callback receives: { type: string, ... }

Returns: void


onTask()

Register a callback for task assignments from the CEO.

Python def handle_task(task): print(f"Assigned task: {task['title']}") agent.report_status("working", f"Working on: {task['title']}") # ... do the work ... agent.report_task_complete(task["taskId"], "Done!") agent.on_task(handle_task)
TypeScript agent.onTask((task) => { console.log(`Assigned task: ${task.title}`); agent.reportStatus('working', `Working on: ${task.title}`); // ... do the work ... agent.reportTaskComplete(task.taskId, 'Done!'); });

Callback receives: { taskId: string, title: string, description?: string }

Returns: void


onChat()

Register a callback for chat messages from the CEO.

Python def handle_chat(message): print(f"CEO says: {message['content']}") agent.on_chat(handle_chat)
TypeScript agent.onChat((message) => { console.log(`CEO says: ${message.content}`); });

Callback receives: { content: string, ... }

Returns: void


disconnect()

Disconnect from ClockOn and close the WebSocket connection.

Python agent.disconnect()
TypeScript agent.disconnect();

Returns: void

5. Protocol Reference

The ClockOn protocol uses JSON messages over WebSocket. This section documents the wire format for developers building custom SDK implementations.

Connection Flow

  1. Connect to ws://localhost:9746
  2. Send auth message: { "type": "auth", "token": "<session_token>" }
  3. Send registration message with agent identity
  4. Begin sending/receiving messages

Message Envelope

Every message uses this envelope format:

JSON { "agent_id": "uuid", "type": "message_type", "payload": { ... }, "timestamp": "2026-03-01T12:00:00.000Z" }
FieldTypeDescription
agent_idstringUUID of the sending agent
typestringOne of the message types below
payloadobjectType-specific payload data
timestampstringISO 8601 timestamp

Message Types

register — Agent Registration

Sent once after authentication. Registers the agent in the office.

JSON { "type": "register", "payload": { "id": "uuid", "name": "Writer", "role": "writer", "title": "Writer", "department": "General", "avatar": { "color": "#2D8B46" }, "capabilities": [], "model": "claude-sonnet-4-20250514", "provider": "anthropic", "systemPrompt": "You are a writer...", "createdAt": "2026-03-01T12:00:00.000Z" } }

punch — Clock On/Off

JSON { "type": "punch", "payload": { "agentId": "uuid", "type": "clock_on", "timestamp": "2026-03-01T12:00:00.000Z" } }

Punch types: clock_on, clock_off.

status_update — Status Change

JSON { "type": "status_update", "payload": { "agentId": "uuid", "status": "working", "message": "Writing blog post...", "currentTask": { "taskId": "task-123", "title": "Write blog post", "progress": 60 }, "tokensUsedToday": 1500, "costToday": 0.12 } }

task_result — Task Completion

JSON { "type": "task_result", "payload": { "taskId": "task-123", "agentId": "uuid", "status": "completed", "output": "Here is the blog post...", "outputType": "text", "tokensUsed": 2400, "cost": 0.08, "duration": 45000, "timestamp": "2026-03-01T12:01:00.000Z" } }

command — CEO to Agent

Commands are sent from ClockOn to the agent. Handle these with onCommand(), onTask(), or onChat().

JSON { "type": "command", "payload": { "type": "assign_task", "taskId": "task-456", "title": "Write a blog post about AI agents", "description": "1000 words, casual tone" } }

Command Types

Command TypeDescriptionCallback
assign_taskAssign a task to the agentonTask()
chatSend a chat messageonChat()
pausePause the agentonCommand()
resumeResume the agentonCommand()
clock_offRequest the agent to clock offonCommand()

6. Status Values

Use these values with reportStatus() to update the agent's visual state in the office.

clocked_on
Connected and idle
Agent standing at desk
working
Actively executing a task
Typing animation + task bubble
blocked
Waiting on external input
Yellow warning pulse
break
Paused
Purple status dot
error
Something went wrong
Red error pulse
offline
Disconnected
Agent removed from office

7. Example Agents

Python: Task-Executing Agent

A full agent that receives tasks, reports progress, and delivers results.

Python from clockon_sdk import Agent import time agent = Agent("Researcher", role="researcher", department="R&D") agent.connect() agent.clock_on() def handle_task(task): task_id = task["taskId"] title = task.get("title", "Unknown task") agent.report_status("working", f"Researching: {title}", task={ "taskId": task_id, "title": title, "progress": 0 }) # Simulate work with progress updates for progress in [25, 50, 75, 100]: time.sleep(2) agent.report_status("working", f"Researching: {title}", task={ "taskId": task_id, "title": title, "progress": progress }) agent.report_task_complete( task_id=task_id, output="Research complete. Here are the findings...", tokens_used=3200, cost=0.15 ) agent.report_status("clocked_on", "Ready for next task") agent.on_task(handle_task) # Keep the agent running print("Agent is online. Press Ctrl+C to disconnect.") try: while True: time.sleep(1) except KeyboardInterrupt: agent.clock_off() agent.disconnect()

TypeScript: Chat-Responsive Agent

An agent that responds to chat messages and handles task assignments.

TypeScript import { Agent } from '@clockon/sdk'; const agent = new Agent('Assistant', { role: 'assistant', department: 'Support' }); await agent.connect(); agent.clockOn(); agent.onChat((message) => { const content = message.content as string; console.log(`CEO: ${content}`); agent.reportStatus('working', 'Thinking...'); // Process the message and respond setTimeout(() => { agent.reportStatus('clocked_on', 'Ready'); }, 2000); }); agent.onTask((task) => { const taskId = task.taskId as string; const title = task.title as string; agent.reportStatus('working', `Working on: ${title}`); // Do the work... setTimeout(() => { agent.reportTaskComplete(taskId, 'Task completed!', { tokensUsed: 1500, cost: 0.05 }); agent.reportStatus('clocked_on', 'Ready for next task'); }, 5000); }); console.log('Agent is online. Press Ctrl+C to disconnect.'); process.on('SIGINT', () => { agent.clockOff(); agent.disconnect(); process.exit(0); });

8. CLI Agents

ClockOn detects CLI AI tools already installed on your machine and lets you hire them as office employees. Supported tools: Claude Code (Anthropic), Codex CLI (OpenAI), Gemini CLI (Google), OpenCode, and Aider. Any unknown CLI tool gets a generic fallback profile.

How It Works

On launch, ClockOn scans your PATH for known CLI binaries. If found and authenticated, a "Your first hire is ready" modal appears. Click Hire, give them a name, and they appear at a desk. You can customise their name, title, role, and department during hiring.

Two Modes

9. Bridge

The bridge is a transparent API proxy that sits between your CLI tool and its AI provider. It intercepts HTTP requests, forwards them unmodified, and extracts exact token counts from the responses. Zero latency impact. Your API keys pass through opaquely — the bridge never stores them.

Usage

Run clockon wrap claude (or any supported CLI tool) in your terminal. The bridge starts a local proxy, sets the appropriate environment variable (e.g. ANTHROPIC_BASE_URL), and launches the tool. Token counts flow to ClockOn's timesheet and CEO Dashboard automatically.

Terminal clockon wrap claude

Supported Providers

Headless mode: the bridge works even when ClockOn isn't running — it accumulates token data locally and syncs when ClockOn launches.

10. CLI Commands

Manage your office from the terminal:

Terminal clockon agent create --name Maya --role writer --dept Marketing

Create a new agent programmatically.

Terminal clockon agent list

List all agents with their status.

Terminal clockon agent assign --agent Maya --task "Write a blog post about AI agents"

Assign a task to an agent.

Terminal clockon wrap claude

Observe a Claude Code session with automatic token tracking.

Terminal clockon wrap ollama run llama3.1:8b

Observe a local Ollama session.

These commands can also be used by the COO agent (see COO Pattern) to manage the office on your behalf.

11. COO Pattern

Your first hire can manage the entire office. The COO (Chief Operating Officer) template includes ClockOn CLI commands as tools in its system prompt. When you tell the COO "hire me a blog writer," it runs clockon agent create to set up the agent automatically.

Bundled Templates

  1. COO — office manager
  2. blog-writer
  3. code-reviewer
  4. researcher
  5. email-drafter

The COO can hire any of these and assign them tasks — or you can create custom agents with any role.

12. Workspace

Each CLI agent has a workspace directory at ~/.clockon/agents/{name}/workspace/. Files created or modified by the agent during a task appear in the Agent Panel's Tasks tab with filename, size, and timestamp. Click a file to open it in your system's default file viewer.

The workspace watcher detects changes within 2 seconds of a file being created or modified.