Skip to main content
The query() function is the primary entry point for interacting with Qwen Code. It creates a new query session and returns a Query instance that implements AsyncIterable<SDKMessage>.

Import

import { query } from '@qwen-code/sdk';
import type { QueryOptions } from '@qwen-code/sdk';

Signature

function query({
  prompt,
  options,
}: {
  prompt: string | AsyncIterable<SDKUserMessage>;
  options?: QueryOptions;
}): Query

Parameters

prompt

prompt
string | AsyncIterable<SDKUserMessage>
required
The prompt to send to Qwen Code.
  • String: For single-turn queries (most common)
  • AsyncIterable: For multi-turn conversations
The transport remains open until the prompt is consumed.
Example (Single-turn):
const result = query({
  prompt: 'What files are in the current directory?',
  options: {},
});
Example (Multi-turn):
async function* conversation(): AsyncIterable<SDKUserMessage> {
  yield {
    type: 'user',
    session_id: 'my-session',
    message: { role: 'user', content: 'Create a file' },
    parent_tool_use_id: null,
  };
  
  yield {
    type: 'user',
    session_id: 'my-session',
    message: { role: 'user', content: 'Now delete it' },
    parent_tool_use_id: null,
  };
}

const result = query({
  prompt: conversation(),
  options: {},
});

options

options
QueryOptions
Configuration options for the query session. See QueryOptions below.

QueryOptions

Basic Options

cwd
string
default:"process.cwd()"
The working directory for the query session. Determines the context in which file operations and commands are executed.
query({
  prompt: 'List files',
  options: { cwd: '/path/to/project' },
})
model
string
The AI model to use for the query session. Takes precedence over OPENAI_MODEL and QWEN_MODEL environment variables.
options: { model: 'qwen-max' }
Common models:
  • gpt-4
  • gpt-3.5-turbo
  • qwen-max
  • qwen-plus
  • qwen-turbo
pathToQwenExecutable
string
Path to the Qwen Code executable. If not provided, the SDK uses the bundled CLI (v0.1.1+) or auto-detects from common locations.Supported formats:
  • Command name: 'qwen' (executes from PATH)
  • JavaScript file: '/path/to/cli.js' (uses Node.js or Bun)
  • TypeScript file: '/path/to/index.ts' (uses tsx if available)
  • Native binary: '/path/to/qwen' (executes directly)
options: { pathToQwenExecutable: '/custom/path/to/qwen' }

Permission Options

permissionMode
'default' | 'plan' | 'auto-edit' | 'yolo'
default:"'default'"
Permission mode controlling tool execution approval.
  • default: Write tools denied unless approved via canUseTool or in allowedTools. Read-only tools execute without confirmation.
  • plan: Blocks all write tools, instructing AI to present a plan first.
  • auto-edit: Auto-approve edit tools (edit, write_file) while other tools require confirmation.
  • yolo: All tools execute automatically without confirmation.
See Permission Modes for details.
canUseTool
CanUseTool
Custom permission handler for tool execution approval. Invoked when a tool requires confirmation.
type CanUseTool = (
  toolName: string,
  input: Record<string, unknown>,
  options: {
    signal: AbortSignal;
    suggestions?: PermissionSuggestion[] | null;
  }
) => Promise<PermissionResult>
Must respond within 60 seconds (configurable via timeout.canUseTool) or the request will be auto-denied.See Custom Permission Handler for examples.
allowedTools
string[]
List of tools allowed to run without confirmation. Matching tools bypass canUseTool callback.Pattern matching:
  • Tool name: 'write_file', 'run_shell_command'
  • Tool class: 'WriteTool', 'ShellTool'
  • Shell command prefix: 'ShellTool(git status)'
options: {
  allowedTools: ['read_file', 'ShellTool(git status)', 'ShellTool(npm test)']
}
excludeTools
string[]
List of tools to exclude from the session. Excluded tools return a permission error immediately. Takes highest priority.
options: {
  excludeTools: ['run_terminal_cmd', 'delete_file', 'ShellTool(rm )']
}
coreTools
string[]
List of core tools to enable. If specified, only these tools will be available to the AI.
options: {
  coreTools: ['read_file', 'write_file', 'edit']
}

MCP Integration

mcpServers
Record<string, McpServerConfig>
MCP (Model Context Protocol) servers to connect. Supports both external servers and SDK-embedded servers.External MCP server (stdio):
options: {
  mcpServers: {
    'my-server': {
      command: 'node',
      args: ['path/to/server.js'],
      env: { PORT: '3000' }
    }
  }
}
SDK MCP server (in-process):
import { createSdkMcpServer, tool } from '@qwen-code/sdk';

const server = createSdkMcpServer({
  name: 'calculator',
  tools: [/* ... */],
});

options: {
  mcpServers: {
    calculator: server
  }
}
See MCP Integration for details.

Session Control

abortController
AbortController
Controller to cancel the query session. Call abortController.abort() to terminate.
const abortController = new AbortController();

const result = query({
  prompt: 'Long task',
  options: { abortController },
});

// Cancel after 5 seconds
setTimeout(() => abortController.abort(), 5000);
See Aborting Queries for examples.
maxSessionTurns
number
default:"-1 (unlimited)"
Maximum number of conversation turns before the session automatically terminates. A turn consists of a user message and an assistant response.
options: { maxSessionTurns: 10 }
sessionId
string
Specify a session ID for the new session. Ensures SDK and CLI use the same ID without resuming history.
options: { sessionId: '123e4567-e89b-12d3-a456-426614174000' }
resume
string
Resume a previous session by providing its session ID.
options: { resume: '123e4567-e89b-12d3-a456-426614174000' }

Advanced Options

env
Record<string, string>
Environment variables to pass to the Qwen CLI process. Merged with the current process environment.
options: {
  env: {
    OPENAI_API_KEY: 'sk-...',
    CUSTOM_VAR: 'value'
  }
}
debug
boolean
default:"false"
Enable debug mode for verbose logging from the CLI process.
options: { debug: true }
logLevel
'debug' | 'info' | 'warn' | 'error'
default:"'error'"
Logging level for the SDK. Controls the verbosity of log messages.
options: { logLevel: 'debug' }
stderr
(message: string) => void
Custom handler for stderr output from the Qwen CLI process.
options: {
  stderr: (message) => {
    console.error('[CLI Error]:', message);
  }
}
authType
'openai' | 'qwen-oauth'
default:"'openai'"
Authentication type for the AI service.
Using 'qwen-oauth' in SDK is not recommended as credentials are stored in ~/.qwen and may need periodic refresh.
options: { authType: 'openai' }
includePartialMessages
boolean
default:"false"
When true, the SDK emits incomplete messages as they are being generated, allowing real-time streaming.
options: { includePartialMessages: true }
See Message Types for handling partial messages.
agents
SubagentConfig[]
Configuration for subagents that can be invoked during the session.
options: {
  agents: [
    {
      name: 'coder',
      description: 'Specialized coding agent',
      systemPrompt: 'You are an expert coder',
      level: 'session',
      tools: ['read_file', 'write_file']
    }
  ]
}
timeout
object
Timeout configuration for various SDK operations. All values are in milliseconds.
options: {
  timeout: {
    canUseTool: 60000,      // Permission callback timeout (default: 60s)
    mcpRequest: 600000,     // MCP tool call timeout (default: 60s)
    controlRequest: 60000,  // Control operation timeout (default: 60s)
    streamClose: 15000,     // Stream close wait timeout (default: 60s)
  }
}

Return Value

Returns a Query instance that implements AsyncIterable<SDKMessage>.
Query
AsyncIterable<SDKMessage>
An async iterable that yields messages from the query session.
for await (const message of result) {
  // Handle message
}
See Query Instance Methods for available methods.

Examples

Basic Query

import { query } from '@qwen-code/sdk';

const result = query({
  prompt: 'What is the capital of France?',
  options: {},
});

for await (const message of result) {
  if (message.type === 'assistant') {
    console.log(message.message.content);
  }
}

With All Options

import { query } from '@qwen-code/sdk';

const abortController = new AbortController();

const result = query({
  prompt: 'Analyze the codebase and suggest improvements',
  options: {
    cwd: '/path/to/project',
    model: 'gpt-4',
    permissionMode: 'default',
    canUseTool: async (toolName, input) => {
      if (toolName.startsWith('read_')) {
        return { behavior: 'allow', updatedInput: input };
      }
      return { behavior: 'deny', message: 'Not allowed' };
    },
    allowedTools: ['ShellTool(git status)'],
    excludeTools: ['delete_file'],
    abortController,
    debug: true,
    logLevel: 'info',
    maxSessionTurns: 20,
    includePartialMessages: true,
    timeout: {
      canUseTool: 120000, // 2 minutes
    },
  },
});

for await (const message of result) {
  console.log(message);
}

See Also