> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/QwenLM/qwen-code/llms.txt
> Use this file to discover all available pages before exploring further.

# query() Function

> Create and manage query sessions with Qwen Code

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

```typescript theme={null}
import { query } from '@qwen-code/sdk';
import type { QueryOptions } from '@qwen-code/sdk';
```

## Signature

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

## Parameters

### prompt

<ParamField path="prompt" type="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.
</ParamField>

**Example (Single-turn):**

```typescript theme={null}
const result = query({
  prompt: 'What files are in the current directory?',
  options: {},
});
```

**Example (Multi-turn):**

```typescript theme={null}
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

<ParamField path="options" type="QueryOptions">
  Configuration options for the query session. See [QueryOptions](#queryoptions) below.
</ParamField>

## QueryOptions

### Basic Options

<ParamField path="cwd" type="string" default="process.cwd()">
  The working directory for the query session. Determines the context in which file operations and commands are executed.

  ```typescript theme={null}
  query({
    prompt: 'List files',
    options: { cwd: '/path/to/project' },
  })
  ```
</ParamField>

<ParamField path="model" type="string">
  The AI model to use for the query session. Takes precedence over `OPENAI_MODEL` and `QWEN_MODEL` environment variables.

  ```typescript theme={null}
  options: { model: 'qwen-max' }
  ```

  Common models:

  * `gpt-4`
  * `gpt-3.5-turbo`
  * `qwen-max`
  * `qwen-plus`
  * `qwen-turbo`
</ParamField>

<ParamField path="pathToQwenExecutable" type="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)

  ```typescript theme={null}
  options: { pathToQwenExecutable: '/custom/path/to/qwen' }
  ```
</ParamField>

### Permission Options

<ParamField path="permissionMode" type="'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](/sdk/api/permission-modes) for details.
</ParamField>

<ParamField path="canUseTool" type="CanUseTool">
  Custom permission handler for tool execution approval. Invoked when a tool requires confirmation.

  ```typescript theme={null}
  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](/sdk/examples/custom-permissions) for examples.
</ParamField>

<ParamField path="allowedTools" type="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)'`

  ```typescript theme={null}
  options: {
    allowedTools: ['read_file', 'ShellTool(git status)', 'ShellTool(npm test)']
  }
  ```
</ParamField>

<ParamField path="excludeTools" type="string[]">
  List of tools to exclude from the session. Excluded tools return a permission error immediately. Takes highest priority.

  ```typescript theme={null}
  options: {
    excludeTools: ['run_terminal_cmd', 'delete_file', 'ShellTool(rm )']
  }
  ```
</ParamField>

<ParamField path="coreTools" type="string[]">
  List of core tools to enable. If specified, only these tools will be available to the AI.

  ```typescript theme={null}
  options: {
    coreTools: ['read_file', 'write_file', 'edit']
  }
  ```
</ParamField>

### MCP Integration

<ParamField path="mcpServers" type="Record<string, McpServerConfig>">
  MCP (Model Context Protocol) servers to connect. Supports both external servers and SDK-embedded servers.

  **External MCP server (stdio):**

  ```typescript theme={null}
  options: {
    mcpServers: {
      'my-server': {
        command: 'node',
        args: ['path/to/server.js'],
        env: { PORT: '3000' }
      }
    }
  }
  ```

  **SDK MCP server (in-process):**

  ```typescript theme={null}
  import { createSdkMcpServer, tool } from '@qwen-code/sdk';

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

  options: {
    mcpServers: {
      calculator: server
    }
  }
  ```

  See [MCP Integration](/sdk/mcp/overview) for details.
</ParamField>

### Session Control

<ParamField path="abortController" type="AbortController">
  Controller to cancel the query session. Call `abortController.abort()` to terminate.

  ```typescript theme={null}
  const abortController = new AbortController();

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

  // Cancel after 5 seconds
  setTimeout(() => abortController.abort(), 5000);
  ```

  See [Aborting Queries](/sdk/examples/abort) for examples.
</ParamField>

<ParamField path="maxSessionTurns" type="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.

  ```typescript theme={null}
  options: { maxSessionTurns: 10 }
  ```
</ParamField>

<ParamField path="sessionId" type="string">
  Specify a session ID for the new session. Ensures SDK and CLI use the same ID without resuming history.

  ```typescript theme={null}
  options: { sessionId: '123e4567-e89b-12d3-a456-426614174000' }
  ```
</ParamField>

<ParamField path="resume" type="string">
  Resume a previous session by providing its session ID.

  ```typescript theme={null}
  options: { resume: '123e4567-e89b-12d3-a456-426614174000' }
  ```
</ParamField>

### Advanced Options

<ParamField path="env" type="Record<string, string>">
  Environment variables to pass to the Qwen CLI process. Merged with the current process environment.

  ```typescript theme={null}
  options: {
    env: {
      OPENAI_API_KEY: 'sk-...',
      CUSTOM_VAR: 'value'
    }
  }
  ```
</ParamField>

<ParamField path="debug" type="boolean" default="false">
  Enable debug mode for verbose logging from the CLI process.

  ```typescript theme={null}
  options: { debug: true }
  ```
</ParamField>

<ParamField path="logLevel" type="'debug' | 'info' | 'warn' | 'error'" default="'error'">
  Logging level for the SDK. Controls the verbosity of log messages.

  ```typescript theme={null}
  options: { logLevel: 'debug' }
  ```
</ParamField>

<ParamField path="stderr" type="(message: string) => void">
  Custom handler for stderr output from the Qwen CLI process.

  ```typescript theme={null}
  options: {
    stderr: (message) => {
      console.error('[CLI Error]:', message);
    }
  }
  ```
</ParamField>

<ParamField path="authType" type="'openai' | 'qwen-oauth'" default="'openai'">
  Authentication type for the AI service.

  <Warning>
    Using `'qwen-oauth'` in SDK is not recommended as credentials are stored in `~/.qwen` and may need periodic refresh.
  </Warning>

  ```typescript theme={null}
  options: { authType: 'openai' }
  ```
</ParamField>

<ParamField path="includePartialMessages" type="boolean" default="false">
  When `true`, the SDK emits incomplete messages as they are being generated, allowing real-time streaming.

  ```typescript theme={null}
  options: { includePartialMessages: true }
  ```

  See [Message Types](/sdk/api/message-types) for handling partial messages.
</ParamField>

<ParamField path="agents" type="SubagentConfig[]">
  Configuration for subagents that can be invoked during the session.

  ```typescript theme={null}
  options: {
    agents: [
      {
        name: 'coder',
        description: 'Specialized coding agent',
        systemPrompt: 'You are an expert coder',
        level: 'session',
        tools: ['read_file', 'write_file']
      }
    ]
  }
  ```
</ParamField>

<ParamField path="timeout" type="object">
  Timeout configuration for various SDK operations. All values are in milliseconds.

  ```typescript theme={null}
  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)
    }
  }
  ```
</ParamField>

## Return Value

Returns a `Query` instance that implements `AsyncIterable<SDKMessage>`.

<ResponseField name="Query" type="AsyncIterable<SDKMessage>">
  An async iterable that yields messages from the query session.

  ```typescript theme={null}
  for await (const message of result) {
    // Handle message
  }
  ```

  See [Query Instance Methods](/sdk/api/query-instance) for available methods.
</ResponseField>

## Examples

### Basic Query

```typescript theme={null}
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

```typescript theme={null}
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

* [Message Types](/sdk/api/message-types) - Understand different message types
* [Query Instance Methods](/sdk/api/query-instance) - Methods available on Query instances
* [Permission Modes](/sdk/api/permission-modes) - Permission mode details
* [Examples](/sdk/examples/single-turn) - Practical usage examples
