docs
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