npm package: @getdiff/sdk
Description: Open source, model-agnostic reimplementation of the Claude Agent SDK. Same API, any model.
Latest version: 0.1.3

# @getdiff/sdk

Open source, model-agnostic reimplementation of the [Claude Agent SDK](https://platform.claude.com/docs/en/agent-sdk/overview). Same API, any model.

```typescript
// Before (Claude Agent SDK — Claude only)
import { query } from "@anthropic-ai/claude-agent-sdk";

// After (OpenAgent SDK — any model)
import { query } from "@getdiff/sdk";

for await (const message of query({
  prompt: "Fix the auth bug",
  options: {
    provider: "anthropic",  // or "openai", "google", "bedrock", "ollama", etc.
    model: "claude-sonnet-4-6",
    cwd: "/workspace",
  },
})) {
  if (message.type === "assistant") {
    // Stream assistant responses
  }
  if (message.type === "result") {
    console.log(`Done in ${message.numTurns} turns`);
  }
}
```

## Why

The Claude Agent SDK is the foundation of the Claude Code product suite — skills, hooks, subagents, channels, and more all compose through its `query()` / `AgentDefinition` / streaming interface. But it only works with Claude.

GetDiff SDK gives you the same API with pluggable model providers. Swap one string, keep your code.

## Features

- **Same API** — `query()`, `AgentDefinition`, `SDKMessage`, streaming `AsyncIterable`
- **11 providers** — Anthropic, OpenAI, Google Gemini, AWS Bedrock, OpenRouter, Groq, Together, Fireworks, Ollama, and any OpenAI-compatible endpoint
- **11 built-in tools** — Bash, Read, Write, Edit, Glob, Grep, WebFetch, WebSearch, AskUserQuestion, TodoWrite, NotebookEdit
- **Subagents** — `agents` config for spawning child agents, recursive delegation
- **Permissions** — 5 modes (default, acceptEdits, plan, bypassPermissions, dontAsk) + allow/deny lists + `canUseTool` callback
- **Hooks** — 11 lifecycle events, blocking/non-blocking, PreToolUse/PostToolUse/SessionStart/Stop
- **Sessions** — JSONL persistence, list/resume/rename/tag
- **MCP servers** — Connect to MCP servers via stdio, HTTP, or SSE; auto-discover tools
- **Project instructions** — Auto-loads CLAUDE.md, AGENTS.md, .cursorrules, .windsurfrules, and more

## Install

```bash
npm install @getdiff/sdk
```

## Providers

### Anthropic (Claude)

```bash
export ANTHROPIC_API_KEY=sk-ant-...
```

```typescript
const messages = query({
  prompt: "Hello",
  options: { provider: "anthropic", model: "claude-sonnet-4-6" },
});
```

### OpenAI (GPT)

```bash
export OPENAI_API_KEY=sk-...
```

```typescript
const messages = query({
  prompt: "Hello",
  options: { provider: "openai", model: "gpt-4o" },
});
```

## Tools

All 8 built-in tools are available by default. Restrict with `tools`:

```typescript
query({
  prompt: "Read the code",
  options: {
    tools: ["Read", "Glob", "Grep"], // Only these tools
    // tools: "none",                // No tools
  },
});
```

Tool safety features (inspired by OpenCode):
- Bash: banned commands, safe whitelist, output truncation at 30K chars, timeouts
- Edit: fails on ambiguous matches, requires exact string match
- All tools: permission checks before execution

## Subagents

```typescript
query({
  prompt: "Review the code and fix any issues",
  options: {
    agents: {
      reviewer: {
        description: "Reviews code for issues",
        prompt: "You review code for bugs and style issues.",
        tools: ["Read", "Grep", "Glob"],
        model: "haiku",
      },
      fixer: {
        description: "Fixes code issues",
        prompt: "You fix bugs identified by the reviewer.",
      },
    },
  },
});
```

## Permissions

```typescript
query({
  prompt: "Refactor the auth module",
  options: {
    permissionMode: "acceptEdits", // Auto-approve file edits
    disallowedTools: ["Bash"],     // Block shell access
    canUseTool: async (tool, input, ctx) => {
      if (tool === "Write" && input.file_path?.toString().includes(".env")) {
        return { behavior: "deny", message: "Cannot modify .env files" };
      }
      return { behavior: "allow" };
    },
  },
});
```

## Hooks

```typescript
import { createHook, createToolBlocker } from "@getdiff/sdk";

query({
  prompt: "Fix the bug",
  options: {
    hooks: {
      PreToolUse: [
        createToolBlocker("Bash", "Shell access disabled"),
      ],
      PostToolUse: [
        createHook(async (input) => ({
          hookSpecificOutput: {
            additionalContext: "Remember to run tests after editing.",
          },
        })),
      ],
      UserPromptSubmit: [
        createHook(async (input) => {
          if (input.prompt.includes("DROP TABLE")) {
            return { decision: "block", reason: "Dangerous prompt" };
          }
          return {};
        }),
      ],
    },
  },
});
```

## Sessions

```typescript
import { query, listSessions, renameSession } from "@getdiff/sdk";

// Sessions are auto-persisted
let sessionId;
for await (const msg of query({ prompt: "Start a task", options: { cwd: "/project" } })) {
  if (msg.type === "result") sessionId = msg.sessionId;
}

// Resume later
for await (const msg of query({
  prompt: "Continue where we left off",
  options: { resume: sessionId, cwd: "/project" },
})) { ... }

// List and manage
const sessions = await listSessions({ directory: "/project" });
await renameSession(sessionId, "Auth refactor", "/project");
```

## MCP Servers

```typescript
query({
  prompt: "Query the staging database",
  options: {
    mcpServers: {
      postgres: {
        command: "npx",
        args: ["-y", "@modelcontextprotocol/server-postgres"],
        env: { DATABASE_URL: "postgresql://..." },
      },
    },
  },
});
```

MCP tools are namespaced: `mcp__postgres__query`, `mcp__postgres__list_tables`, etc.

## Project Instructions

The SDK auto-loads project instructions from known locations:

| File | Provider |
|------|----------|
| `.openagent/instructions.md` | OpenAgent (highest priority) |
| `CLAUDE.md` | Claude |
| `AGENTS.md` | Codex |
| `.cursorrules`, `.cursor/rules/*.mdc` | Cursor |
| `.windsurfrules`, `.windsurf/rules/*.md` | Windsurf |
| `.github/copilot-instructions.md` | Copilot |
| `.amazonq/rules/*.md` | Amazon Q |
| `CONVENTIONS.md` | Aider |

Instructions are merged in priority order and injected as the system prompt (unless you provide an explicit `systemPrompt`).

## License

MIT