DEV Community

Santhosh Dhandapani
Santhosh Dhandapani

Posted on

I Built a 5-Line SDK for Claude Agents — Here's Why

Every team building Claude agents writes the same 300 lines of glue code. I got tired of it and built claude-runner — a thin TypeScript wrapper that turns the official Agent SDK into a 5-line experience.

claude-runner CLI demo

The Problem

The official @anthropic-ai/claude-agent-sdk is powerful but low-level:

  • query() returns an async generator with 20+ message types
  • MCP server config requires nested objects
  • Multi-turn needs manual async iterator coordination
  • No sandbox, no permission shortcuts, no CLI

Every developer ends up writing the same wrapper. So I published one.

5 Lines to Start

import { Runner } from 'claude-runner';

const runner = new Runner();
const result = await runner.run('Analyze this codebase and suggest improvements');
console.log(result.text);
Enter fullscreen mode Exit fullscreen mode

That's a fully autonomous agent — reads files, runs commands, calls tools, and returns a typed result with cost, tokens, duration, and session ID.

What It Does

Raw Agent SDK claude-runner
Lines to start 20+ 5
Message types 20+ nested 7 flat events
MCP config Object only Shorthand strings
Sandbox Manual spawner sandbox: 'docker'
Session resume resume: id option runner.resume(id)
Permissions canUseTool callback permissions: 'auto'

Streaming

claude-runner streaming demo

for await (const event of runner.stream('Refactor the auth module')) {
  switch (event.type) {
    case 'text': process.stdout.write(event.text); break;
    case 'tool_start': console.log(`→ ${event.tool}`); break;
    case 'tool_end': console.log(`← ${event.tool} (${event.duration}ms)`); break;
    case 'done': console.log(`Cost: $${event.result.cost.toFixed(4)}`); break;
  }
}
Enter fullscreen mode Exit fullscreen mode

7 flat event types instead of 20+ nested SDK messages. No parsing, no filtering.

MCP in One Line

const runner = new Runner({
  mcp: {
    github: 'npx @modelcontextprotocol/server-github',
    docs: 'https://api.example.com/mcp',
    postgres: {
      command: 'npx',
      args: ['@modelcontextprotocol/server-postgres'],
      env: { PGPASSWORD: process.env.PGPASSWORD },
    },
  },
});
Enter fullscreen mode Exit fullscreen mode

Shorthand strings, URLs, or full config objects. Tools are auto-discovered.

Docker & E2B Sandbox

// Docker — filesystem isolation
const runner = new Runner({
  sandbox: 'docker',
  docker: { image: 'node:22-slim' },
  permissions: 'auto',
});

// E2B — cloud VM sandbox
const runner = new Runner({
  sandbox: 'e2b',
  e2b: { apiKey: process.env.E2B_API_KEY },
});
Enter fullscreen mode Exit fullscreen mode

Your project is bind-mounted into the container. All tool calls operate inside. Container destroyed on exit.

CLI Included

npx claude-runner "Fix all failing tests"
npx claude-runner -m opus "Refactor the auth module"
npx claude-runner --mcp github="npx @mcp/server-github" "List open issues"
Enter fullscreen mode Exit fullscreen mode

Session Resume & Multi-Turn

const r1 = await runner.run('Create a test plan');
const r2 = await runner.resume(r1.sessionId, 'Approved. Generate the tests.').result;
Enter fullscreen mode Exit fullscreen mode

Full conversation context preserved across turns.

The Numbers

  • ~1,500 lines of source code
  • 1 dependency (@anthropic-ai/claude-agent-sdk)
  • 34 KB published package size
  • 61 tests passing
  • MIT license

Install

npm install claude-runner
Enter fullscreen mode Exit fullscreen mode

Requires Claude Code CLI installed and authenticated.

Links


Feedback welcome — issues, PRs, or just tell me what's missing. 🚗

Top comments (0)