or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

agent-definitions.mdagents.mdclient.mdconfiguration-options.mdcontent-blocks.mdcore-query-interface.mdcustom-tools.mderror-handling.mderrors.mdhook-system.mdhooks.mdindex.mdmcp-config.mdmcp-server-configuration.mdmessages-and-content.mdmessages.mdoptions.mdpermission-control.mdpermissions.mdquery.mdtransport.md
COMPLETION_SUMMARY.md

query.mddocs/

0

# Simple Query Interface

1

2

The query() function provides a simple async iterator interface for stateless, one-shot interactions with Claude Code. It's ideal for automation scripts, batch processing, and scenarios where all inputs are known upfront.

3

4

## Capabilities

5

6

### Query Function

7

8

Async function for querying Claude Code. Returns an async iterator of Message objects representing the conversation flow.

9

10

```python { .api }

11

async def query(

12

*,

13

prompt: str | AsyncIterable[dict[str, Any]],

14

options: ClaudeAgentOptions | None = None,

15

transport: Transport | None = None

16

) -> AsyncIterator[Message]:

17

"""

18

Query Claude Code for one-shot or unidirectional streaming interactions.

19

20

This function is ideal for simple, stateless queries where you don't need

21

bidirectional communication or conversation management. For interactive,

22

stateful conversations, use ClaudeSDKClient instead.

23

24

Key differences from ClaudeSDKClient:

25

- Unidirectional: Send all messages upfront, receive all responses

26

- Stateless: Each query is independent, no conversation state

27

- Simple: Fire-and-forget style, no connection management

28

- No interrupts: Cannot interrupt or send follow-up messages

29

30

When to use query():

31

- Simple one-off questions

32

- Batch processing of independent prompts

33

- Code generation or analysis tasks

34

- Automated scripts and CI/CD pipelines

35

- When you know all inputs upfront

36

37

When to use ClaudeSDKClient:

38

- Interactive conversations with follow-ups

39

- Chat applications or REPL-like interfaces

40

- When you need to send messages based on responses

41

- When you need interrupt capabilities

42

- Long-running sessions with state

43

44

Args:

45

prompt: The prompt to send to Claude. Can be a string for single-shot queries

46

or an AsyncIterable[dict] for streaming mode with continuous interaction.

47

In streaming mode, each dict should have the structure:

48

{

49

"type": "user",

50

"message": {"role": "user", "content": "..."},

51

"parent_tool_use_id": None,

52

"session_id": "..."

53

}

54

options: Optional configuration (defaults to ClaudeAgentOptions() if None).

55

Set options.permission_mode to control tool execution:

56

- 'default': CLI prompts for dangerous tools

57

- 'acceptEdits': Auto-accept file edits

58

- 'bypassPermissions': Allow all tools (use with caution)

59

Set options.cwd for working directory.

60

transport: Optional transport implementation. If provided, this will be used

61

instead of the default transport selection based on options.

62

63

Yields:

64

Message objects from the conversation (UserMessage, AssistantMessage,

65

SystemMessage, ResultMessage, or StreamEvent)

66

"""

67

```

68

69

## Usage Examples

70

71

### Simple Query

72

73

```python

74

import anyio

75

from claude_agent_sdk import query

76

77

async def main():

78

async for message in query(prompt="What is 2 + 2?"):

79

print(message)

80

81

anyio.run(main)

82

```

83

84

### Processing Response Messages

85

86

```python

87

from claude_agent_sdk import query, AssistantMessage, TextBlock, ResultMessage

88

89

async def main():

90

async for message in query(prompt="What is the capital of France?"):

91

if isinstance(message, AssistantMessage):

92

for block in message.content:

93

if isinstance(block, TextBlock):

94

print(f"Claude: {block.text}")

95

elif isinstance(message, ResultMessage):

96

print(f"Cost: ${message.total_cost_usd:.4f}")

97

print(f"Duration: {message.duration_ms}ms")

98

99

anyio.run(main)

100

```

101

102

### Query with Options

103

104

```python

105

from claude_agent_sdk import query, ClaudeAgentOptions

106

107

async def main():

108

options = ClaudeAgentOptions(

109

system_prompt="You are a helpful Python expert",

110

max_turns=1,

111

cwd="/home/user/project"

112

)

113

114

async for message in query(

115

prompt="Explain what asyncio is",

116

options=options

117

):

118

print(message)

119

120

anyio.run(main)

121

```

122

123

### Using Tools

124

125

```python

126

from claude_agent_sdk import query, ClaudeAgentOptions

127

128

async def main():

129

options = ClaudeAgentOptions(

130

allowed_tools=["Read", "Write", "Bash"],

131

permission_mode='acceptEdits' # auto-accept file edits

132

)

133

134

async for message in query(

135

prompt="Create a hello.py file that prints 'Hello, World!'",

136

options=options

137

):

138

# Process tool use and results

139

pass

140

141

anyio.run(main)

142

```

143

144

### Setting Working Directory

145

146

```python

147

from pathlib import Path

148

from claude_agent_sdk import query, ClaudeAgentOptions

149

150

async def main():

151

options = ClaudeAgentOptions(

152

cwd=Path("/path/to/project") # or "/path/to/project" as string

153

)

154

155

async for message in query(

156

prompt="List the files in the current directory",

157

options=options

158

):

159

print(message)

160

161

anyio.run(main)

162

```

163

164

### Streaming Mode

165

166

```python

167

from claude_agent_sdk import query

168

169

async def main():

170

async def prompts():

171

yield {"type": "user", "message": {"role": "user", "content": "Hello"}, "session_id": "1"}

172

yield {"type": "user", "message": {"role": "user", "content": "How are you?"}, "session_id": "1"}

173

174

# All prompts are sent, then all responses received (still unidirectional)

175

async for message in query(prompt=prompts()):

176

print(message)

177

178

anyio.run(main)

179

```

180

181

### Using Custom Transport

182

183

```python

184

from claude_agent_sdk import query, Transport

185

186

class MyCustomTransport(Transport):

187

# Implement custom transport logic

188

async def connect(self) -> None:

189

pass

190

191

async def write(self, data: str) -> None:

192

pass

193

194

def read_messages(self):

195

pass

196

197

async def close(self) -> None:

198

pass

199

200

def is_ready(self) -> bool:

201

return True

202

203

async def end_input(self) -> None:

204

pass

205

206

async def main():

207

transport = MyCustomTransport()

208

async for message in query(

209

prompt="Hello",

210

transport=transport

211

):

212

print(message)

213

214

anyio.run(main)

215

```

216

217

### Error Handling

218

219

```python

220

from claude_agent_sdk import (

221

query,

222

ClaudeSDKError,

223

CLINotFoundError,

224

CLIConnectionError,

225

ProcessError,

226

CLIJSONDecodeError

227

)

228

229

async def main():

230

try:

231

async for message in query(prompt="Hello Claude"):

232

print(message)

233

except CLINotFoundError:

234

print("Please install Claude Code: npm install -g @anthropic-ai/claude-code")

235

except CLIConnectionError as e:

236

print(f"Connection error: {e}")

237

except ProcessError as e:

238

print(f"Process failed with exit code {e.exit_code}: {e.stderr}")

239

except CLIJSONDecodeError as e:

240

print(f"JSON decode error: {e.line}")

241

except ClaudeSDKError as e:

242

print(f"SDK error: {e}")

243

244

anyio.run(main)

245

```

246