Skip to main content

Prerequisites

Before you begin, make sure you have:
  • Node.js 18+ installed
  • npm package manager
  • An OpenRouter API key (optional - demo mode works without keys)
Don’t have an OpenRouter key? Try demo mode first - it runs with an in-memory backend and sample data, no API keys required.

Create Your Agent

1

Clone the repository

Clone the ClarkOS SDK:
git clone https://github.com/clarkOS/clark my-agent
cd my-agent/example/convex
This gives you a fully-configured project with:
  • Convex backend setup
  • TypeScript configuration
  • Terminal UI (React Ink)
  • 179 passing tests
2

Install dependencies

Install the required packages:
npm install
3

Run the doctor (optional)

Validate your environment:
npm run doctor
This checks Node version, environment variables, and dependencies.
4

Try demo mode (no keys needed)

Start the agent with an in-memory backend:
npm run demo
This runs the terminal UI with sample data. Great for exploring before configuring API keys.
5

Or configure for full mode

Set up your environment variables:
cp .env.example .env.local
Edit .env.local with your API keys:
CONVEX_URL=https://your-project.convex.cloud
OPENROUTER_KEY=your-openrouter-key
GEMINI_API_KEY=your-gemini-key
Then run:
npm run dev

Terminal UI

The SDK includes a terminal-based interface built with React Ink:
┌─────────────────────────────────────────────┐
│  CLARK - Autonomous Agent                    │
│  Mood: curious | Health: 78 | Routine: day  │
├─────────────────────────────────────────────┤
│      ╭──────────╮                           │
│      │  ◉    ◉  │                           │
│      │    ──    │                           │
│      ╰──────────╯                           │
└─────────────────────────────────────────────┘

Keyboard Controls

KeyAction
qQuit
rRefresh data
mToggle radio panel
vToggle view mode
Ctrl+CForce quit

Your First Tick

The tick is the heartbeat of your agent. Every tick, your agent:
  1. Loads its current state and memories
  2. Gathers context (knowledge, recent activity)
  3. Calculates routine from current time
  4. Executes plugin hooks
  5. Updates state (health drift, counters)
To trigger a tick programmatically:
import { Agent, ConvexBackend } from './src';

const agent = new Agent({
  backend: new ConvexBackend({ url: process.env.CONVEX_URL! }),
});

await agent.tick();

Explore the API

Your agent exposes HTTP endpoints via the Convex backend:
EndpointMethodDescription
/healthGETHealth check
/stateGETCurrent agent state
/memoriesGETQuery memories
/memoriesPOSTStore a memory
/memories/coreGETCore memories
/memories/statsGETMemory statistics
/knowledgeGETKnowledge items
/logsGETActivity logs

Add a Plugin

Extend your agent with a plugin:
// plugins/logger.ts
import type { Plugin } from "./src/plugins";

export const loggerPlugin: Plugin = {
  name: "logger",
  version: "1.0.0",
  description: "Logs tick activity",

  init(agent) {
    console.log("Logger plugin initialized");
  },

  onTick(context) {
    console.log(`Tick executed. Mood: ${context.state.mood}, Health: ${context.state.health}`);
    console.log(`Memories loaded: ${context.memories.length}`);
  }
};
Register it in your agent:
import { Agent } from "./src";
import { ConvexBackend } from "./src/backend";
import { loggerPlugin } from "./plugins/logger";

const agent = new Agent({
  backend: new ConvexBackend({ url: process.env.CONVEX_URL! }),
  plugins: [loggerPlugin]
});

await agent.tick();

Run the Tests

The SDK includes 179 tests:
npm test

Next Steps

Need help? Open an issue on GitHub.