Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows
—
Claude Code provides TypeScript and Python SDKs for programmatic access, enabling integration into applications, scripts, and automated workflows.
Comprehensive TypeScript SDK for Node.js applications and scripts.
// Installation
npm install @anthropic-ai/claude-code
// Basic setup
import { ClaudeCodeSDK } from '@anthropic-ai/claude-code';
const sdk = new ClaudeCodeSDK({
apiKey: process.env.ANTHROPIC_API_KEY,
workingDirectory: '/path/to/project'
});interface ClaudeCodeSDK {
// Session management
createSession(options?: SessionOptions): Promise<Session>;
// Permission management
canUseTool(toolName: string): boolean;
getPermissions(): ToolPermissions;
// Event handling
onUserInput(callback: (input: string) => void): void;
onToolExecution(callback: (tool: string, input: any) => void): void;
onError(callback: (error: Error) => void): void;
// Request management
cancelRequest(requestId: string): void;
getActiveRequests(): string[];
}
interface SessionOptions {
apiKey?: string;
model?: string;
workingDirectory?: string;
permissions?: ToolPermissions;
hooks?: HookConfiguration;
maxTokens?: number;
temperature?: number;
}
interface Session {
// Messaging
sendMessage(message: string): Promise<Response>;
sendMessageStream(message: string): AsyncIterable<ResponseChunk>;
// Custom tools
addCustomTool(name: string, callback: ToolCallback): void;
removeCustomTool(name: string): void;
listCustomTools(): string[];
// Session state
getConversationHistory(): ConversationMessage[];
clearHistory(): void;
saveSession(path: string): Promise<void>;
loadSession(path: string): Promise<void>;
// Configuration
updatePermissions(permissions: ToolPermissions): void;
getConfiguration(): SessionConfiguration;
}// Simple message exchange
const session = await sdk.createSession();
const response = await session.sendMessage("Fix the bug in auth.js");
console.log(response.content);
// Streaming responses
const session = await sdk.createSession();
for await (const chunk of session.sendMessageStream("Explain this codebase")) {
process.stdout.write(chunk.content);
}
// Custom tool integration
session.addCustomTool('custom-linter', async (input) => {
const { filePath } = input;
const results = await runCustomLinter(filePath);
return { results, success: true };
});
// Permission-controlled session
const session = await sdk.createSession({
permissions: {
allowedTools: ['Read(*)', 'Write(src/**/*.ts)'],
blockedTools: ['Bash(rm *)']
}
});// Automated code review
async function performCodeReview(files: string[]) {
const session = await sdk.createSession({
model: 'claude-3-opus-20240229',
permissions: {
allowedTools: [`Read(${files.join('|')})`]
}
});
const reviews = [];
for (const file of files) {
const response = await session.sendMessage(`Review code quality in ${file}`);
reviews.push({ file, review: response.content });
}
return reviews;
}
// Batch processing with error handling
async function batchProcess(tasks: string[]) {
const session = await sdk.createSession();
const results = [];
for (const task of tasks) {
try {
const response = await session.sendMessage(task);
results.push({ task, success: true, result: response.content });
} catch (error) {
results.push({ task, success: false, error: error.message });
}
}
return results;
}
// Custom hook integration
const session = await sdk.createSession({
hooks: {
PreToolUse: [
{
matcher: 'Write',
hooks: [
{
type: 'command',
command: 'node backup-file.js'
}
]
}
]
}
});Full-featured Python SDK for Python applications and automation scripts.
# Installation
pip install claude-code-sdk
# Basic setup
from claude_code_sdk import ClaudeCodeSDK
sdk = ClaudeCodeSDK(
api_key=os.getenv('ANTHROPIC_API_KEY'),
working_directory='/path/to/project'
)class ClaudeCodeSDK:
def __init__(self, api_key: str, working_directory: str = None):
"""Initialize SDK with API key and optional working directory"""
async def create_session(self, options: SessionOptions = None) -> Session:
"""Create a new Claude Code session"""
def can_use_tool(self, tool_name: str) -> bool:
"""Check if tool is permitted"""
def get_permissions(self) -> ToolPermissions:
"""Get current tool permissions"""
def on_user_input(self, callback: Callable[[str], None]):
"""Register callback for user input events"""
def cancel_request(self, request_id: str):
"""Cancel active request"""
class Session:
async def send_message(self, message: str) -> Response:
"""Send message and get response"""
async def send_message_stream(self, message: str) -> AsyncIterator[ResponseChunk]:
"""Send message and get streaming response"""
def add_custom_tool(self, name: str, callback: Callable):
"""Add custom tool with callback"""
def get_conversation_history(self) -> List[ConversationMessage]:
"""Get conversation history"""
async def save_session(self, path: str):
"""Save session to file"""
async def load_session(self, path: str):
"""Load session from file"""import asyncio
from claude_code_sdk import ClaudeCodeSDK
# Basic usage
async def main():
sdk = ClaudeCodeSDK(api_key="your-api-key")
session = await sdk.create_session()
response = await session.send_message("Fix the bug in auth.py")
print(response.content)
# Streaming responses
async def stream_example():
session = await sdk.create_session()
async for chunk in session.send_message_stream("Explain this codebase"):
print(chunk.content, end='')
# Custom tool integration
def custom_formatter(input_data):
file_path = input_data.get('file_path')
# Custom formatting logic
return {'formatted': True, 'path': file_path}
session.add_custom_tool('format-code', custom_formatter)
# Batch processing
async def batch_code_review(files):
session = await sdk.create_session(
options={'model': 'claude-3-opus-20240229'}
)
reviews = []
for file in files:
response = await session.send_message(f"Review {file}")
reviews.append({'file': file, 'review': response.content})
return reviews// Express.js API endpoint
app.post('/api/code-review', async (req, res) => {
try {
const { files } = req.body;
const session = await sdk.createSession({
permissions: {
allowedTools: files.map(f => `Read(${f})`)
}
});
const results = [];
for (const file of files) {
const response = await session.sendMessage(`Review ${file}`);
results.push({ file, review: response.content });
}
res.json({ success: true, results });
} catch (error) {
res.status(500).json({ error: error.message });
}
});# Python CLI tool
import click
from claude_code_sdk import ClaudeCodeSDK
@click.command()
@click.argument('task')
@click.option('--files', multiple=True)
async def claude_cli(task, files):
"""Claude Code CLI wrapper"""
sdk = ClaudeCodeSDK(api_key=os.getenv('ANTHROPIC_API_KEY'))
session = await sdk.create_session()
if files:
for file in files:
await session.send_message(f"Read {file}")
response = await session.send_message(task)
click.echo(response.content)
if __name__ == '__main__':
asyncio.run(claude_cli())// GitHub Actions workflow integration
async function runCodeReview() {
const sdk = new ClaudeCodeSDK({
apiKey: process.env.ANTHROPIC_API_KEY
});
const session = await sdk.createSession({
permissions: {
allowedTools: ['Read(*)', 'Bash(git diff *)']
}
});
// Get changed files
const changedFiles = await session.sendMessage("git diff --name-only HEAD~1");
// Review each file
const review = await session.sendMessage(
`Review the code changes in: ${changedFiles.content}`
);
// Post review as PR comment
await postPRComment(review.content);
}try {
const response = await session.sendMessage("Complex task");
console.log(response.content);
} catch (error) {
if (error instanceof PermissionError) {
console.error('Permission denied:', error.message);
} else if (error instanceof RateLimitError) {
console.error('Rate limit exceeded:', error.retryAfter);
} else if (error instanceof NetworkError) {
console.error('Network error:', error.message);
} else {
console.error('Unknown error:', error);
}
}
// Event-based error handling
sdk.onError((error) => {
console.error('SDK Error:', error);
// Log to monitoring service
monitor.logError(error);
});from claude_code_sdk import ClaudeCodeSDK, PermissionError, RateLimitError
try:
response = await session.send_message("Complex task")
print(response.content)
except PermissionError as e:
print(f"Permission denied: {e}")
except RateLimitError as e:
print(f"Rate limit exceeded. Retry after: {e.retry_after}")
except Exception as e:
print(f"Unexpected error: {e}")// Jest test example
import { ClaudeCodeSDK } from '@anthropic-ai/claude-code';
describe('Claude Code Integration', () => {
let sdk: ClaudeCodeSDK;
beforeEach(() => {
sdk = new ClaudeCodeSDK({
apiKey: 'test-key',
baseURL: 'http://test-server'
});
});
test('should create session', async () => {
const session = await sdk.createSession();
expect(session).toBeDefined();
});
test('should handle custom tools', async () => {
const session = await sdk.createSession();
session.addCustomTool('test-tool', (input) => {
return { result: 'test-result' };
});
const response = await session.sendMessage('Use test-tool');
expect(response.content).toContain('test-result');
});
});// Enable debug logging
const sdk = new ClaudeCodeSDK({
apiKey: 'your-key',
debug: true,
logLevel: 'verbose'
});
// Custom logging
sdk.onToolExecution((tool, input) => {
console.log(`Tool executed: ${tool}`, input);
});
sdk.onUserInput((input) => {
console.log(`User input: ${input}`);
});
// Performance monitoring
const startTime = Date.now();
const response = await session.sendMessage("task");
const duration = Date.now() - startTime;
console.log(`Request completed in ${duration}ms`);// Reuse sessions for better performance
class ClaudeCodeManager {
private sessions = new Map<string, Session>();
async getSession(key: string): Promise<Session> {
if (!this.sessions.has(key)) {
const session = await this.sdk.createSession();
this.sessions.set(key, session);
}
return this.sessions.get(key)!;
}
async closeSession(key: string) {
const session = this.sessions.get(key);
if (session) {
await session.close();
this.sessions.delete(key);
}
}
}# Efficient batch processing
async def batch_process_files(files: List[str]):
session = await sdk.create_session()
# Load all files first
for file in files:
await session.send_message(f"Read {file}")
# Process in batch
file_list = ', '.join(files)
response = await session.send_message(f"Analyze these files: {file_list}")
return response.contentInstall with Tessl CLI
npx tessl i tessl/npm-anthropic-ai--claude-code