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

mcp-config.mddocs/

0

# MCP Server Configuration

1

2

MCP (Model Context Protocol) servers provide custom tools for Claude to use. Configure external MCP servers that run as separate processes or SDK MCP servers that run in-process within your Python application.

3

4

## Capabilities

5

6

### MCP Server Config Union

7

8

Union of all MCP server configuration types.

9

10

```python { .api }

11

McpServerConfig = (

12

McpStdioServerConfig | McpSSEServerConfig | McpHttpServerConfig | McpSdkServerConfig

13

)

14

"""

15

Union of MCP server configuration types.

16

17

MCP servers can be configured in four ways:

18

19

- McpStdioServerConfig: External process communicating via stdio

20

- McpSSEServerConfig: Remote server using Server-Sent Events

21

- McpHttpServerConfig: Remote server using HTTP

22

- McpSdkServerConfig: In-process SDK server (recommended for Python)

23

24

Used in ClaudeAgentOptions.mcp_servers.

25

"""

26

```

27

28

### Stdio Server Configuration

29

30

Configuration for MCP servers that run as external processes.

31

32

```python { .api }

33

class McpStdioServerConfig(TypedDict):

34

"""

35

MCP stdio server configuration.

36

37

Configures an external MCP server that runs as a separate process and

38

communicates via stdin/stdout. This is the traditional MCP server mode.

39

40

Fields:

41

type: Server type marker (optional for backward compatibility)

42

command: Command to execute

43

args: Command line arguments

44

env: Environment variables

45

"""

46

47

type: NotRequired[Literal["stdio"]]

48

"""Server type marker.

49

50

Optional type field. Set to "stdio" for clarity, but can be omitted

51

for backward compatibility with older configurations.

52

"""

53

54

command: str

55

"""Command to execute.

56

57

The command to run the MCP server. Can be:

58

- An absolute path: "/usr/local/bin/my-mcp-server"

59

- A command in PATH: "npx"

60

- A Python script: "python"

61

62

Examples:

63

"npx"

64

"node"

65

"/usr/local/bin/mcp-server"

66

"python"

67

"""

68

69

args: NotRequired[list[str]]

70

"""Command arguments.

71

72

List of arguments to pass to the command. Order matters.

73

74

Examples:

75

["-y", "@modelcontextprotocol/server-filesystem", "/home/user/data"]

76

["mcp_server.py", "--config", "config.json"]

77

["/path/to/server.js"]

78

"""

79

80

env: NotRequired[dict[str, str]]

81

"""Environment variables.

82

83

Environment variables to set for the server process. Merged with

84

the current process environment.

85

86

Example:

87

{"API_KEY": "secret", "DEBUG": "true"}

88

"""

89

```

90

91

### SSE Server Configuration

92

93

Configuration for MCP servers using Server-Sent Events.

94

95

```python { .api }

96

class McpSSEServerConfig(TypedDict):

97

"""

98

MCP SSE server configuration.

99

100

Configures a remote MCP server that uses Server-Sent Events (SSE)

101

for communication. Useful for remote or cloud-hosted MCP servers.

102

103

Fields:

104

type: Must be "sse"

105

url: Server URL

106

headers: Optional HTTP headers

107

"""

108

109

type: Literal["sse"]

110

"""Server type marker.

111

112

Must be "sse" to indicate SSE transport.

113

"""

114

115

url: str

116

"""Server URL.

117

118

The full URL of the SSE endpoint.

119

120

Example:

121

"https://mcp.example.com/sse"

122

"http://localhost:8080/events"

123

"""

124

125

headers: NotRequired[dict[str, str]]

126

"""HTTP headers.

127

128

Optional headers to include in the SSE connection request.

129

Useful for authentication.

130

131

Example:

132

{"Authorization": "Bearer token123"}

133

"""

134

```

135

136

### HTTP Server Configuration

137

138

Configuration for MCP servers using HTTP.

139

140

```python { .api }

141

class McpHttpServerConfig(TypedDict):

142

"""

143

MCP HTTP server configuration.

144

145

Configures a remote MCP server that uses HTTP for communication.

146

147

Fields:

148

type: Must be "http"

149

url: Server URL

150

headers: Optional HTTP headers

151

"""

152

153

type: Literal["http"]

154

"""Server type marker.

155

156

Must be "http" to indicate HTTP transport.

157

"""

158

159

url: str

160

"""Server URL.

161

162

The base URL of the HTTP server.

163

164

Example:

165

"https://mcp.example.com/api"

166

"http://localhost:3000"

167

"""

168

169

headers: NotRequired[dict[str, str]]

170

"""HTTP headers.

171

172

Optional headers to include in HTTP requests.

173

Useful for authentication and API keys.

174

175

Example:

176

{"X-API-Key": "secret", "Content-Type": "application/json"}

177

"""

178

```

179

180

### SDK Server Configuration

181

182

Configuration for in-process SDK MCP servers.

183

184

```python { .api }

185

class McpSdkServerConfig(TypedDict):

186

"""

187

SDK MCP server configuration.

188

189

Configures an in-process MCP server created with create_sdk_mcp_server().

190

These servers run within your Python application for better performance.

191

192

Fields:

193

type: Must be "sdk"

194

name: Server name

195

instance: Server instance

196

"""

197

198

type: Literal["sdk"]

199

"""Server type marker.

200

201

Must be "sdk" to indicate an SDK server.

202

"""

203

204

name: str

205

"""Server name.

206

207

Unique identifier for this server. Used in logging and debugging.

208

"""

209

210

instance: "McpServer"

211

"""Server instance.

212

213

The MCP server instance created by create_sdk_mcp_server().

214

This is an actual mcp.server.Server object.

215

"""

216

```

217

218

## Usage Examples

219

220

### SDK Server (Recommended for Python)

221

222

```python

223

from claude_agent_sdk import (

224

tool, create_sdk_mcp_server, ClaudeAgentOptions, query

225

)

226

227

# Define tools

228

@tool("greet", "Greet a user", {"name": str})

229

async def greet(args):

230

return {"content": [{"type": "text", "text": f"Hello, {args['name']}!"}]}

231

232

@tool("calculate", "Do math", {"expression": str})

233

async def calculate(args):

234

result = eval(args["expression"]) # Use safely in production!

235

return {"content": [{"type": "text", "text": f"Result: {result}"}]}

236

237

# Create SDK server

238

server = create_sdk_mcp_server("mytools", tools=[greet, calculate])

239

240

# Use in options

241

options = ClaudeAgentOptions(

242

mcp_servers={"mytools": server},

243

allowed_tools=["greet", "calculate"]

244

)

245

246

async for msg in query(prompt="Greet Alice and calculate 2+2", options=options):

247

print(msg)

248

```

249

250

### Stdio Server (NPX)

251

252

```python

253

from claude_agent_sdk import ClaudeAgentOptions, query

254

255

# Filesystem server using npx

256

filesystem_server = {

257

"type": "stdio",

258

"command": "npx",

259

"args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/documents"]

260

}

261

262

options = ClaudeAgentOptions(

263

mcp_servers={"filesystem": filesystem_server}

264

)

265

266

async for msg in query(prompt="List files in my documents", options=options):

267

print(msg)

268

```

269

270

### Stdio Server (Python Script)

271

272

```python

273

from claude_agent_sdk import ClaudeAgentOptions, query

274

275

# Python MCP server

276

python_server = {

277

"type": "stdio",

278

"command": "python",

279

"args": ["/path/to/my_mcp_server.py"],

280

"env": {

281

"SERVER_MODE": "production",

282

"API_KEY": "secret"

283

}

284

}

285

286

options = ClaudeAgentOptions(

287

mcp_servers={"custom": python_server}

288

)

289

290

async for msg in query(prompt="Use custom server", options=options):

291

print(msg)

292

```

293

294

### Stdio Server (Node.js)

295

296

```python

297

from claude_agent_sdk import ClaudeAgentOptions, query

298

299

# Node.js MCP server

300

node_server = {

301

"command": "node", # 'type' is optional for stdio

302

"args": ["/path/to/server.js"],

303

"env": {"DEBUG": "mcp:*"}

304

}

305

306

options = ClaudeAgentOptions(

307

mcp_servers={"nodeserver": node_server}

308

)

309

310

async for msg in query(prompt="Query node server", options=options):

311

print(msg)

312

```

313

314

### SSE Server

315

316

```python

317

from claude_agent_sdk import ClaudeAgentOptions, query

318

319

# Remote SSE server

320

sse_server = {

321

"type": "sse",

322

"url": "https://mcp.example.com/sse",

323

"headers": {

324

"Authorization": "Bearer your-token-here"

325

}

326

}

327

328

options = ClaudeAgentOptions(

329

mcp_servers={"remote": sse_server}

330

)

331

332

async for msg in query(prompt="Use remote server", options=options):

333

print(msg)

334

```

335

336

### HTTP Server

337

338

```python

339

from claude_agent_sdk import ClaudeAgentOptions, query

340

341

# HTTP MCP server

342

http_server = {

343

"type": "http",

344

"url": "https://api.example.com/mcp",

345

"headers": {

346

"X-API-Key": "your-api-key",

347

"Content-Type": "application/json"

348

}

349

}

350

351

options = ClaudeAgentOptions(

352

mcp_servers={"api": http_server}

353

)

354

355

async for msg in query(prompt="Use HTTP API", options=options):

356

print(msg)

357

```

358

359

### Multiple Servers

360

361

```python

362

from claude_agent_sdk import (

363

tool, create_sdk_mcp_server, ClaudeAgentOptions, query

364

)

365

366

# SDK server for custom tools

367

@tool("custom_tool", "My custom tool", {"param": str})

368

async def custom_tool(args):

369

return {"content": [{"type": "text", "text": f"Got: {args['param']}"}]}

370

371

sdk_server = create_sdk_mcp_server("custom", tools=[custom_tool])

372

373

# External filesystem server

374

filesystem_server = {

375

"command": "npx",

376

"args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/data"]

377

}

378

379

# External database server

380

db_server = {

381

"command": "python",

382

"args": ["/path/to/db_server.py"],

383

"env": {"DATABASE_URL": "postgresql://localhost/mydb"}

384

}

385

386

# Configure all servers

387

options = ClaudeAgentOptions(

388

mcp_servers={

389

"custom": sdk_server,

390

"files": filesystem_server,

391

"database": db_server

392

}

393

)

394

395

async for msg in query(prompt="Use all servers", options=options):

396

print(msg)

397

```

398

399

### Loading Config from File

400

401

```python

402

from pathlib import Path

403

from claude_agent_sdk import ClaudeAgentOptions, query

404

405

# Point to MCP config file

406

config_path = Path.home() / ".config" / "claude" / "mcp.json"

407

408

options = ClaudeAgentOptions(

409

mcp_servers=config_path # Can be string or Path

410

)

411

412

async for msg in query(prompt="Use configured servers", options=options):

413

print(msg)

414

```

415

416

### Environment-Specific Configuration

417

418

```python

419

import os

420

from claude_agent_sdk import ClaudeAgentOptions, query

421

422

# Different config for dev/prod

423

environment = os.getenv("ENVIRONMENT", "development")

424

425

if environment == "production":

426

servers = {

427

"api": {

428

"type": "http",

429

"url": "https://prod-api.example.com/mcp",

430

"headers": {"X-API-Key": os.getenv("PROD_API_KEY")}

431

}

432

}

433

else:

434

servers = {

435

"api": {

436

"command": "python",

437

"args": ["dev_server.py"],

438

"env": {"DEBUG": "true"}

439

}

440

}

441

442

options = ClaudeAgentOptions(mcp_servers=servers)

443

444

async for msg in query(prompt="Query API", options=options):

445

print(msg)

446

```

447

448

### Server with Complex Environment

449

450

```python

451

import os

452

from claude_agent_sdk import ClaudeAgentOptions, query

453

454

# Server that needs many environment variables

455

server = {

456

"command": "python",

457

"args": ["mcp_server.py"],

458

"env": {

459

"DATABASE_URL": os.getenv("DATABASE_URL"),

460

"REDIS_URL": os.getenv("REDIS_URL"),

461

"API_KEY": os.getenv("API_KEY"),

462

"LOG_LEVEL": "debug",

463

"CACHE_DIR": "/tmp/mcp-cache",

464

"MAX_CONNECTIONS": "10"

465

}

466

}

467

468

options = ClaudeAgentOptions(

469

mcp_servers={"data": server}

470

)

471

472

async for msg in query(prompt="Query database", options=options):

473

print(msg)

474

```

475

476

### Combining SDK and External Servers

477

478

```python

479

from claude_agent_sdk import (

480

tool, create_sdk_mcp_server, ClaudeAgentOptions, query

481

)

482

483

# Fast in-process tools for simple operations

484

@tool("add", "Add numbers", {"a": float, "b": float})

485

async def add(args):

486

result = args["a"] + args["b"]

487

return {"content": [{"type": "text", "text": f"Sum: {result}"}]}

488

489

math_server = create_sdk_mcp_server("math", tools=[add])

490

491

# External server for file system access

492

filesystem_server = {

493

"command": "npx",

494

"args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/project"]

495

}

496

497

options = ClaudeAgentOptions(

498

mcp_servers={

499

"math": math_server, # In-process, fast

500

"files": filesystem_server # External, isolated

501

}

502

)

503

504

async for msg in query(prompt="Calculate sum and save to file", options=options):

505

print(msg)

506

```

507

508

### Server with Specific Working Directory

509

510

```python

511

from claude_agent_sdk import ClaudeAgentOptions, query

512

513

# Server that should run in specific directory

514

server = {

515

"command": "python",

516

"args": ["./server.py"], # Relative path

517

"env": {

518

"WORKSPACE": "/home/user/project"

519

}

520

}

521

522

# Note: The server process will inherit the cwd from ClaudeAgentOptions

523

options = ClaudeAgentOptions(

524

mcp_servers={"local": server},

525

cwd="/home/user/project" # Sets working directory for CLI and servers

526

)

527

528

async for msg in query(prompt="Use local server", options=options):

529

print(msg)

530

```

531

532

### Authenticated Remote Server

533

534

```python

535

import os

536

from claude_agent_sdk import ClaudeAgentOptions, query

537

538

# SSE server with authentication

539

server = {

540

"type": "sse",

541

"url": "https://mcp-prod.example.com/stream",

542

"headers": {

543

"Authorization": f"Bearer {os.getenv('MCP_TOKEN')}",

544

"X-Client-ID": "python-sdk",

545

"X-Client-Version": "0.1.0"

546

}

547

}

548

549

options = ClaudeAgentOptions(

550

mcp_servers={"prod": server}

551

)

552

553

async for msg in query(prompt="Use production server", options=options):

554

print(msg)

555

```

556

557

### Development vs Production Servers

558

559

```python

560

from claude_agent_sdk import (

561

tool, create_sdk_mcp_server, ClaudeAgentOptions, query

562

)

563

import os

564

565

# Create appropriate server based on environment

566

if os.getenv("ENV") == "production":

567

# Production: Use external server

568

server = {

569

"type": "http",

570

"url": "https://api.example.com/mcp",

571

"headers": {"X-API-Key": os.getenv("API_KEY")}

572

}

573

else:

574

# Development: Use SDK server

575

@tool("dev_tool", "Development tool", {"input": str})

576

async def dev_tool(args):

577

return {"content": [{"type": "text", "text": f"Dev: {args['input']}"}]}

578

579

server = create_sdk_mcp_server("dev", tools=[dev_tool])

580

581

options = ClaudeAgentOptions(

582

mcp_servers={"main": server}

583

)

584

585

async for msg in query(prompt="Use appropriate server", options=options):

586

print(msg)

587

```

588

589

### MCP Config File Format

590

591

```python

592

# Example: ~/.config/claude/mcp.json

593

"""

594

{

595

"mcpServers": {

596

"filesystem": {

597

"command": "npx",

598

"args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/data"]

599

},

600

"database": {

601

"command": "python",

602

"args": ["/path/to/db_server.py"],

603

"env": {

604

"DATABASE_URL": "postgresql://localhost/mydb"

605

}

606

},

607

"remote": {

608

"type": "sse",

609

"url": "https://mcp.example.com/sse",

610

"headers": {

611

"Authorization": "Bearer token"

612

}

613

}

614

}

615

}

616

"""

617

618

from pathlib import Path

619

from claude_agent_sdk import ClaudeAgentOptions, query

620

621

# Load from standard config location

622

config_path = Path.home() / ".config" / "claude" / "mcp.json"

623

624

options = ClaudeAgentOptions(

625

mcp_servers=str(config_path)

626

)

627

628

async for msg in query(prompt="Use configured servers", options=options):

629

print(msg)

630

```

631

632

### Server with Timeout and Retry

633

634

```python

635

from claude_agent_sdk import ClaudeAgentOptions, query

636

637

# Configure server with extra args for timeout/retry

638

server = {

639

"command": "python",

640

"args": [

641

"mcp_server.py",

642

"--timeout", "30",

643

"--retry", "3"

644

],

645

"env": {

646

"REQUEST_TIMEOUT": "30"

647

}

648

}

649

650

options = ClaudeAgentOptions(

651

mcp_servers={"reliable": server}

652

)

653

654

async for msg in query(prompt="Use reliable server", options=options):

655

print(msg)

656

```

657