DEV Community

Santhosh Dhandapani
Santhosh Dhandapani

Posted on • Edited on

claude-runner: Build Claude Agents in 5 Lines — CLI, SDK, and Cloud

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
  • Requires Claude CLI installed — can't deploy to cloud

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'
Cloud deployment Needs CLI installed API key only
Session resume resume: id option runner.resume(id)
Permissions canUseTool callback permissions: 'auto'

NEW: API Mode — Deploy Anywhere

The biggest limitation of the Claude Agent SDK is that it requires the Claude CLI installed. That means no Lambda, no Cloud Run, no serverless.

API Mode fixes this. Just pass an API key — no CLI needed:

const runner = new Runner({
  apiKey: process.env.ANTHROPIC_API_KEY,
  model: 'sonnet',
});

const result = await runner.run('Summarize this data');
Enter fullscreen mode Exit fullscreen mode

Or from the CLI:

ANTHROPIC_API_KEY=sk-xxx npx claude-runner "Summarize this data"
Enter fullscreen mode Exit fullscreen mode

Agent Mode vs API Mode

Agent Mode (default) API Mode
Requires Claude CLI installed API key only
Built-in tools Read, Write, Bash, Edit Bring your own
Custom tools defineTool() defineTool()
Deploys to Local, CI with CLI Anywhere
Cost model Claude subscription Pay-per-token

API Mode uses the raw Anthropic Messages API with an agentic tool loop — same RunEvent types, same RunResult, same streaming. Just no CLI dependency.

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

Both validated — Docker on Rancher Desktop, E2B on real cloud VMs.

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"
npx claude-runner --api-key sk-xxx "Summarize this data"
Enter fullscreen mode Exit fullscreen mode

Real-World Use Cases

Agent Mode (CLI):

  • Code reviewer: runner.run('Review src/ for bugs')
  • Test generator: analyze → resume → generate
  • CI/CD agent: npx claude-runner -p auto "Fix failing tests"

API Mode (no CLI):

  • SaaS chatbot on Cloud Run
  • Lambda function for data analysis
  • Slack bot with custom tools
  • GitHub webhook for PR reviews
  • Content generation API

Install

# Agent Mode — full Claude Code power (needs CLI)
npm install claude-runner

# API Mode — no CLI needed, deploys anywhere
npm install claude-runner @anthropic-ai/sdk
Enter fullscreen mode Exit fullscreen mode

Links


Now Available in Python 🐍

Same API, same simplicity — now on PyPI:

pip install claude-runner-py[api]
Enter fullscreen mode Exit fullscreen mode
import asyncio
from claude_runner import Runner

async def main():
    runner = Runner(api_key="sk-ant-...")
    result = await runner.run("Analyze this codebase")
    print(result.text)

asyncio.run(main())
Enter fullscreen mode Exit fullscreen mode

Custom tools work the same way:

from claude_runner import define_tool, ToolResult

async def get_weather(city: str) -> ToolResult:
    return ToolResult(content=[{"type": "text", "text": f"72F in {city}"}])

weather = define_tool("get_weather", "Get weather", {"city": {"type": "string"}}, get_weather)
runner = Runner(api_key="sk-ant-...", tools=[weather])
Enter fullscreen mode Exit fullscreen mode

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

Top comments (0)