npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@misbahsy/clawkit-lite

v0.1.0

Published

Minimal agent kit — any provider, any channel, any skills

Readme

ClawKit Lite

Minimal agent kit — any provider, any channel, any skills.

ClawKit Lite is a ~1,000-line kit for building conversational AI agents. Clone it, pick your channel (Telegram, WhatsApp, ...), pick your provider (Claude, OpenAI Codex, Pi, ...), add skills, and run. No Docker, no framework overhead — just a message bus with pluggable parts.

[Channel] → message in → [Runtime] → [Provider] → response → [Channel]
                              ↑
                          [Skills]
                     (instructions + MCP tools)

Quick Start

git clone https://github.com/misbahsy/ClawKit-lite.git
cd ClawKit-lite
npm install

# Option A: Interactive setup via Claude Code
claude
# then type: /setup

# Option B: Manual setup
cp .env.example .env
# Edit .env with your API keys and tokens
# Edit clawkit.config.ts to pick your channel + provider
npm install grammy                            # for Telegram
npm install @anthropic-ai/claude-agent-sdk    # for Claude
npm run dev

How It Works

Three Pluggable Interfaces

Everything in ClawKit Lite implements one of three interfaces:

// Channel — produces messages, sends responses
interface Channel {
  name: string;
  connect(): Promise<void>;
  disconnect(): Promise<void>;
  onMessage(cb: (msg: IncomingMessage) => void): void;
  sendMessage(to: string, text: string): Promise<void>;
  setTyping?(to: string, isTyping: boolean): Promise<void>;
}

// Provider — takes a prompt, returns streamed responses
interface Provider {
  name: string;
  run(params: {
    prompt: string;
    systemPrompt: string;
    sessionId?: string;
    mcpServers?: Record<string, McpServerConfig>;
  }): AsyncIterable<ProviderEvent>;
}

// Skill — instructions + optional MCP server
interface Skill {
  name: string;
  instructions: string;         // loaded from SKILL.md
  mcpServer?: McpServerConfig;  // optional tool server
}

Configuration

All configuration lives in a single file — clawkit.config.ts:

import { telegram } from "./src/channels/telegram.js";
import { claude } from "./src/providers/claude.js";

export default {
  name: "my-agent",
  channel: telegram({ token: process.env.TELEGRAM_BOT_TOKEN! }),
  provider: claude({ model: "claude-sonnet-4-20250514" }),
  skills: ["./src/skills/scheduler"],
  systemPrompt: "./workspace/CLAUDE.md",
};

To switch to WhatsApp + OpenAI Codex, change two imports:

import { whatsapp } from "./src/channels/whatsapp.js";
import { codex } from "./src/providers/codex.js";

export default {
  name: "my-agent",
  channel: whatsapp({ storePath: "./store/whatsapp-auth" }),
  provider: codex({ model: "codex-mini-latest" }),
  skills: ["./src/skills/scheduler"],
  systemPrompt: "./workspace/CLAUDE.md",
};

Environment Variables

Secrets go in .env (gitignored), never in config files:

# Channel tokens
TELEGRAM_BOT_TOKEN=your-bot-token-here
# WHATSAPP_STORE_PATH=./store

# Provider keys
ANTHROPIC_API_KEY=your-key-here
# OPENAI_API_KEY=your-key-here
# PI_API_KEY=your-key-here
# PI_SERVER_URL=http://localhost:8080

Channels

Telegram

Uses grammy. Requires a bot token from @BotFather.

npm install grammy
import { telegram } from "./src/channels/telegram.js";

telegram({ token: process.env.TELEGRAM_BOT_TOKEN! })

Features:

  • Polling-based (no webhook setup needed)
  • Automatic message chunking (4096 char limit)
  • Typing indicators
  • Group chat support
  • Outgoing message queue with retry on disconnect

WhatsApp

Uses Baileys. Authenticates via QR code scan.

npm install baileys @hapi/boom pino qrcode-terminal
import { whatsapp } from "./src/channels/whatsapp.js";

whatsapp({ storePath: "./store/whatsapp-auth" })

Features:

  • QR code authentication (displayed in terminal)
  • Session persistence (survives restarts)
  • LID-to-phone JID translation
  • Exponential backoff reconnection (up to 30s)
  • Markdown-to-WhatsApp formatting conversion
  • Typing/presence indicators
  • Group chat support

Adding a Custom Channel

Create src/channels/my-channel.ts:

import type { Channel } from "../types.js";

export function myChannel(config: { /* your config */ }): Channel {
  return {
    name: "my-channel",
    async connect() { /* connect to service */ },
    async disconnect() { /* cleanup */ },
    onMessage(cb) { /* wire up message listener, call cb() */ },
    async sendMessage(to, text) { /* send response */ },
    async setTyping(to, isTyping) { /* optional typing indicator */ },
  };
}

Providers

All providers are agent SDKs — full coding agent runtimes, not raw LLM APIs. They handle tool use, file access, and bash execution natively.

Claude (Agent SDK)

Uses @anthropic-ai/claude-agent-sdk. The same SDK that powers Claude Code.

npm install @anthropic-ai/claude-agent-sdk
import { claude } from "./src/providers/claude.js";

claude({
  model: "claude-sonnet-4-20250514",  // default
  maxTurns: 10,                        // max agent turns per message
  permissionMode: "bypassPermissions", // autonomous operation
  cwd: "/path/to/workspace",           // optional working directory
})

Features:

  • Session resume (conversations persist across messages)
  • MCP server passthrough (skill tools available to agent)
  • Built-in tools: Bash, Read, Write, Edit, Glob, Grep, WebSearch
  • Auth: ANTHROPIC_API_KEY env var or claude login (OAuth)

OpenAI Codex CLI

Uses @openai/codex. OpenAI's agent with built-in sandboxed execution.

npm install @openai/codex
import { codex } from "./src/providers/codex.js";

codex({
  model: "codex-mini-latest",  // default
})

Features:

  • Single-call execution (prompt in, response out)
  • Built-in sandbox for bash
  • Flexible response parsing
  • Auth: OPENAI_API_KEY env var

Pi Agent

HTTP-based streaming agent used by OpenClaw. Supports self-hosted or cloud Pi servers.

npm install @mariozechner/pi-agent-core
import { pi } from "./src/providers/pi.js";

pi({
  model: "pi-default",
  baseUrl: "http://localhost:8080",     // Pi server URL
  maxTokens: 4096,
  modelFailover: ["fallback-model"],    // try these if primary fails
  compactionThreshold: 100,             // summarize after N messages
})

Features:

  • Server-sent events (SSE) streaming
  • Model failover (automatic fallback)
  • Session compaction (summarizes old messages)
  • Auth: PI_API_KEY and PI_SERVER_URL env vars

Adding a Custom Provider

Create src/providers/my-provider.ts:

import type { Provider, ProviderEvent } from "../types.js";

export function myProvider(config: { /* your config */ }): Provider {
  return {
    name: "my-provider",
    async *run({ prompt, systemPrompt, sessionId, mcpServers }) {
      // Call your agent SDK here
      const response = await callMyAgent(prompt);
      yield { type: "text", text: response };
      yield { type: "done", sessionId: "new-session-id" };
    },
  };
}

Skills

Skills extend your agent with instructions and tools. Each skill is a directory with:

src/skills/my-skill/
├── SKILL.md          # Instructions the agent reads (added to system prompt)
└── server.ts         # Optional MCP server providing tools

Built-in: Scheduler

Schedule recurring tasks with cron expressions.

src/skills/scheduler/
├── SKILL.md          # Tells agent how to use scheduling tools
└── server.ts         # MCP server: schedule_task, list_tasks

Example interactions:

  • "Remind me every morning at 9am to check email" → creates cron job 0 9 * * *
  • "Every Friday at 5pm, send a weekly summary" → creates cron job 0 17 * * 5
  • "What tasks are scheduled?" → lists all active tasks

Adding a Custom Skill

  1. Create the directory:

    mkdir -p src/skills/my-skill
  2. Write instructions in SKILL.md:

    ## My Skill
    
    You can do X, Y, Z.
    
    ### Available tools
    - **my_tool**: Does something useful
      - `param1`: Description
  3. Optionally create an MCP server in server.ts:

    import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
    import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
    import { z } from "zod";
    
    const server = new McpServer({ name: "my-skill", version: "1.0.0" });
    
    server.tool("my_tool", "Does something useful", {
      param1: z.string().describe("Description"),
    }, async ({ param1 }) => {
      return { content: [{ type: "text", text: `Result: ${param1}` }] };
    });
    
    const transport = new StdioServerTransport();
    server.connect(transport);
  4. Register in config:

    skills: ["./src/skills/scheduler", "./src/skills/my-skill"],
  5. Restart: npm run dev

Project Structure

clawkit-lite/
├── src/
│   ├── index.ts              # Entry point
│   ├── runtime.ts            # Message bus (channel → provider → channel)
│   ├── types.ts              # Channel, Provider, Skill interfaces
│   ├── config.ts             # Load .env + config file
│   ├── db.ts                 # SQLite: messages, sessions, tasks
│   ├── channels/
│   │   ├── telegram.ts       # Telegram adapter (grammy)
│   │   └── whatsapp.ts       # WhatsApp adapter (baileys)
│   ├── providers/
│   │   ├── claude.ts         # Claude Agent SDK adapter
│   │   ├── codex.ts          # OpenAI Codex CLI adapter
│   │   └── pi.ts             # Pi Agent adapter
│   └── skills/
│       └── scheduler/
│           ├── SKILL.md      # Scheduling instructions
│           └── server.ts     # MCP server: schedule_task, list_tasks
├── workspace/
│   └── CLAUDE.md             # System prompt (agent identity + rules)
├── setup/
│   ├── bootstrap.sh          # Environment checks
│   └── index.ts              # Setup step runner
├── tests/
│   ├── helpers.ts            # Mock channel, provider, message factories
│   ├── db.test.ts            # Database layer tests
│   └── runtime.test.ts       # Runtime integration tests
├── store/                    # Auth state, SQLite database (gitignored)
├── clawkit.config.ts         # User configuration
├── .env.example              # Environment variable template
├── .env                      # Your secrets (gitignored)
├── package.json
└── tsconfig.json

Runtime Details

Message Bus

The runtime (src/runtime.ts) handles:

  1. Skill loading — reads SKILL.md files, detects MCP servers
  2. System prompt building — concatenates workspace/CLAUDE.md + skill instructions
  3. Message routing — channel message in → provider → response back to channel
  4. Conversation history — loads last 30 messages from SQLite for context
  5. Session persistence — saves/restores provider session IDs per sender
  6. Per-sender queue — ensures one agent turn per sender at a time (concurrent across senders)
  7. Scheduled tasks — polls cron-based tasks every 60s, executes due tasks via provider
  8. Graceful shutdown — cleans up intervals, disconnects channel

Database

SQLite via better-sqlite3 with WAL mode. Three tables:

| Table | Purpose | |-------|---------| | messages | Conversation history per session (sender/group) | | sessions | Maps senders to provider session IDs | | tasks | Scheduled tasks (prompt, cron, target, last_run) |

Stored at ./store/clawkit.db (gitignored).

Dependencies

Always installed (core):

better-sqlite3    — message/session/task storage
cron-parser       — scheduled task expressions
dotenv            — environment variable loading

Install per channel (pick one):

grammy                        — Telegram
baileys @hapi/boom pino qrcode-terminal  — WhatsApp

Install per provider (pick one):

@anthropic-ai/claude-agent-sdk    — Claude Code
@openai/codex                     — OpenAI Codex CLI
@mariozechner/pi-agent-core       — Pi Agent

Install if skills use MCP:

@modelcontextprotocol/sdk zod     — MCP server implementation

Base install: 3 core deps + 1 channel + 1 provider = ~4-5 packages.

Commands

npm run dev       # Run with tsx (development, auto-loads .ts)
npm run build     # Compile TypeScript to dist/
npm start         # Run compiled version (production)
npm test          # Run tests

Interactive Setup

If you have Claude Code installed, the /setup skill provides a guided wizard:

claude
# type: /setup

The wizard will:

  1. Check your environment (Node.js 20+, dependencies)
  2. Ask which channel you want (Telegram / WhatsApp)
  3. Ask which provider you want (Claude / Codex / Pi)
  4. Walk you through authentication (bot token, QR code, API keys)
  5. Ask for your agent's name
  6. Generate clawkit.config.ts and .env
  7. Install the right dependencies
  8. Optionally set up a background service (launchd/systemd)
  9. Verify everything works

How It Compares

| | Full ClawKit | ClawKit Lite | Official Nanoclaw | |-|-------------|-------------|-------------------| | Code | ~5k lines + registry | ~1,000 lines | ~6,900 lines | | Provider | Multi (typed interfaces) | Multi (swap one file) | Claude only | | Channels | Multi (typed interfaces) | Multi (swap one file) | WA + Telegram hardcoded | | Extensibility | Component categories | Skills + adapter swap | SKILL.md only | | Docker | No | No | Required | | Philosophy | Framework | Kit | Opinionated app |

Testing

npm test

31 tests covering:

  • Database: message CRUD, session persistence, task management
  • Runtime: message flow, typing indicators, history context, session resume, error handling (yielded + thrown), streaming, per-sender queue serialization, group messages, skill loading, MCP server detection, system prompt building, config variations

License

MIT