Queries
Basic Query
const claude = new Claude()
const result = await claude.query('Explain what src/index.ts does')
console.log(result.text) // Claude's response text
console.log(result.sessionId) // "abc-123-..." — for resuming later
console.log(result.usage) // { inputTokens: 1500, outputTokens: 800 }
console.log(result.cost) // 0.012 or null
console.log(result.durationMs) // 3200
console.log(result.messages) // full message historyQueryResult Fields
Full reference for the object returned by query():
const result = await claude.query('Explain the auth module')
result.text // string — Claude's response
result.sessionId // string — session ID for resuming
result.usage // { inputTokens: number, outputTokens: number }
result.cost // number | null — USD cost
result.durationMs // number — wall-clock time
result.messages // Message[] — full conversation history
result.structured // unknown | null — parsed JSON when schema was used
result.raw // Record<string, unknown> — raw CLI JSON responseAccessing Message History
import {
Claude,
BLOCK_TEXT,
BLOCK_TOOL_USE,
BLOCK_TOOL_RESULT,
} from '@scottwalker/claude-connector'
const claude = new Claude()
const result = await claude.query('Explain the auth module')
for (const msg of result.messages) {
console.log(`[${msg.role}]`)
if (typeof msg.content === 'string') {
console.log(msg.content)
} else {
for (const block of msg.content) {
switch (block.type) {
case BLOCK_TEXT:
console.log(block.text)
break
case BLOCK_TOOL_USE:
console.log(`Tool: ${block.name}(${JSON.stringify(block.input)})`)
break
case BLOCK_TOOL_RESULT:
console.log(`Result: ${block.content}`)
break
}
}
}
}Per-Query Overrides
Any ClientOptions field that has a QueryOptions counterpart can be overridden per-query:
import {
Claude,
PERMISSION_PLAN,
PERMISSION_ACCEPT_EDITS,
EFFORT_MEDIUM,
EFFORT_MAX,
} from '@scottwalker/claude-connector'
const claude = new Claude({
model: 'sonnet',
maxTurns: 10,
maxBudget: 5.0,
permissionMode: PERMISSION_PLAN,
effortLevel: EFFORT_MEDIUM,
systemPrompt: 'You are a helpful assistant.',
allowedTools: ['Read', 'Glob'],
tools: ['Read', 'Glob', 'Grep', 'Bash'],
})
// Override everything for one query
const result = await claude.query('Fix the critical bug NOW', {
model: 'opus',
maxTurns: 50,
maxBudget: 20.0,
permissionMode: PERMISSION_ACCEPT_EDITS,
effortLevel: EFFORT_MAX,
systemPrompt: 'You are an emergency bug fixer. Act fast.',
allowedTools: ['Read', 'Glob', 'Grep', 'Edit', 'Bash'],
tools: ['default'],
cwd: '/home/user/production-hotfix',
additionalDirs: ['/home/user/shared-config'],
env: { HOTFIX: 'true' },
agent: 'fixer',
worktree: 'hotfix-branch',
})Parallel Queries
Run multiple independent queries concurrently:
const claude = new Claude()
const results = await claude.parallel([
{ prompt: 'Review src/auth.ts for security issues' },
{ prompt: 'Find dead code in src/utils/' },
{ prompt: 'Check for TypeScript strict mode violations', options: { model: 'haiku' } },
])
for (const result of results) {
console.log(result.text)
console.log('---')
}Model Selection
// Aliases
const claude = new Claude({ model: 'opus' })
const claude = new Claude({ model: 'sonnet' })
const claude = new Claude({ model: 'haiku' })
// Full model ID
const claude = new Claude({ model: 'claude-sonnet-4-6' })Fallback Model
Automatically fall back if the primary model is overloaded:
const claude = new Claude({
model: 'opus',
fallbackModel: 'sonnet',
})Effort Levels
Controls thinking depth:
import {
Claude,
EFFORT_LOW,
EFFORT_MEDIUM,
EFFORT_HIGH,
EFFORT_MAX,
} from '@scottwalker/claude-connector'
const claude = new Claude({ effortLevel: EFFORT_LOW }) // fast, shallow
const claude = new Claude({ effortLevel: EFFORT_MEDIUM }) // balanced
const claude = new Claude({ effortLevel: EFFORT_HIGH }) // deep thinking
const claude = new Claude({ effortLevel: EFFORT_MAX }) // maximum depthSystem Prompt
Override the Entire System Prompt
const claude = new Claude({
systemPrompt: 'You are a senior Go developer. Always respond in Go idioms.',
})
const result = await claude.query('How do I handle errors?')Append to the Default System Prompt
const claude = new Claude({
appendSystemPrompt: 'Always include test examples in your answers.',
})Per-Query System Prompt Override
const claude = new Claude({
systemPrompt: 'You are a TypeScript expert.',
})
// Override for a specific query
const result = await claude.query('Explain ownership', {
systemPrompt: 'You are a Rust expert.',
})Piped Input (stdin)
Provide additional context alongside the prompt — equivalent to echo "data" | claude -p "prompt":
import { readFileSync } from 'node:fs'
const logContent = readFileSync('/var/log/app.log', 'utf-8')
const result = await claude.query('Find errors in these logs', {
input: logContent,
})Analyze Diff Output
import { execSync } from 'node:child_process'
const diff = execSync('git diff HEAD~5').toString()
const result = await claude.query('Review these changes for bugs', {
input: diff,
})Git Worktree Isolation
Run queries in an isolated git worktree — changes don't affect your working tree:
// Auto-generated worktree name
const result = await claude.query('Experiment with a new API design', {
worktree: true,
})
// Named worktree
const result = await claude.query('Build the auth feature', {
worktree: 'feature-auth',
})TIP
Worktree isolation is ideal for exploratory changes. Claude operates on a separate copy of your repo, so your working tree remains clean.
Additional Directories
Grant Claude access to directories outside the main working directory:
const claude = new Claude({
cwd: '/home/user/project',
additionalDirs: ['/home/user/shared-lib', '/home/user/config'],
})
// Per-query additional directories
const result = await claude.query('Compare our auth with the shared lib', {
additionalDirs: ['/home/user/other-project/src'],
})Thinking Config
Control Claude's extended thinking behavior (SDK mode only):
// Adaptive — Claude decides when and how deeply to think
const claude = new Claude({
thinking: { type: 'adaptive' },
})
// Fixed budget — allocate a specific token budget for thinking
const claude = new Claude({
thinking: { type: 'enabled', budgetTokens: 10_000 },
})
// Disabled — no extended thinking
const claude = new Claude({
thinking: { type: 'disabled' },
})
// Per-query override
const result = await claude.query('Solve this complex math problem', {
thinking: { type: 'enabled', budgetTokens: 50_000 },
})Per-Query Abort with signal
Cancel a specific query without affecting other queries or the client:
const claude = new Claude()
const controller = new AbortController()
// Abort this specific query after 10 seconds
setTimeout(() => controller.abort(), 10_000)
try {
const result = await claude.query('Analyze the entire codebase', {
signal: controller.signal,
})
} catch (err) {
console.log('Query was aborted')
}TIP
signal cancels a single query. claude.abort() kills the entire active session. Use signal when running parallel queries and you only want to cancel one.
Runtime Model Switch
Change the model mid-session (SDK mode only):
const claude = new Claude({ model: 'sonnet' })
// Start a query, then switch model for the next turn
const r1 = await claude.query('Outline the refactoring plan')
await claude.setModel('opus')
const r2 = await claude.query('Now implement step 1 of the plan')Account & Model Info
Query account details and available models (SDK mode only):
const claude = new Claude()
// Account information
const account = await claude.accountInfo()
console.log(account.email) // "user@example.com"
console.log(account.subscriptionType) // "max"
// List supported models
const models = await claude.supportedModels()
for (const m of models) {
console.log(`${m.displayName} (${m.value})`)
console.log(` Effort levels: ${m.supportedEffortLevels?.join(', ')}`)
console.log(` Adaptive thinking: ${m.supportsAdaptiveThinking}`)
}Abort
Cancel a running query:
const claude = new Claude()
const promise = claude.query('Analyze the entire codebase')
// Abort after 10 seconds
setTimeout(() => claude.abort(), 10_000)
try {
await promise
} catch (err) {
console.log('Query was aborted')
}