transport-options.md

reference

← Back to skill

Content hash: 1d802c1ce203a46c5c0f21e2b4721ca513b2ac03d493531f42dcabfa197e881e
## MCP Transport Options

### Transport comparison

| Feature | stdio | Streamable HTTP |
|---------|-------|-----------------|
| Connection | Child process stdin/stdout | HTTP endpoint |
| Network surface | None (local only) | Open to network |
| Auth | None needed (process-owned) | Required (header-based) |
| Use case | Local dev, desktop agents | Remote servers, web apps, multitenancy |
| Latency | Minimal (IPC) | Network RTT |
| Default SDK | `mcp.client.stdio.stdio_client` | `mcp.client.streamable_http.streamable_http_client` |

### stdio client pattern
```python
from mcp.client.stdio import stdio_client
from mcp import ClientSession, StdioServerParameters

params = StdioServerParameters(command="python", args=["server.py"])
async with stdio_client(params) as (read, write):
    async with ClientSession(read, write) as session:
        await session.initialize()
        # ... discover and call tools ...
```

### Streamable HTTP client pattern
```python
from mcp.client.streamable_http import streamable_http_client

async with streamable_http_client("https://mcp.example.com/mcp", headers={
    "Authorization": "Bearer <token>"
}) as (read, write):
    async with ClientSession(read, write) as session:
        await session.initialize()
```

### Session lifecycle (do NOT skip)
1. **connect** (open transport)
2. **initialize** (handshake: exchange capabilities)
3. **notify initialized** (client confirms)
4. **discover** (list tools/resources/prompts)
5. **invoke** (call tools)
6. **close** (disconnect)

### Error handling checklist
- [ ] Wrap `call_tool` in try/except; surface structured error to model
- [ ] Set client-side timeout on every tool call
- [ ] Handle `isError=True` in `CallToolResult`
- [ ] Support `notifications/cancelled` for aborting long calls
- [ ] Page through `list_tools`/`list_resources` with `cursor`

### Capability-aware design
Not all servers support everything. Check before calling:
```python
caps = (await session.initialize()).capabilities
if caps.tools:
    await session.list_tools()
if caps.resources:
    await session.list_resources()  # may raise if unsupported
```