May 28, 2026 · 9 min read
click-to-mcp Transport Modes: stdio, HTTP+SSE, and Streamable HTTP
click-to-mcp auto-wraps any Click or Typer CLI as an MCP server. But "MCP server" isn't a single thing — the Model Context Protocol defines three transport modes, and each one serves a different use case. Pick the wrong transport and your agent can't connect. Pick the right one and everything clicks into place.
This guide covers all three transports — stdio, HTTP+SSE, and Streamable HTTP — with concrete commands, client compatibility, and a decision framework. Plus: the config and list-tools commands that make setup a 30-second operation.
The Three Transports at a Glance
The MCP specification defines how clients and servers communicate. Three transports are currently supported, and click-to-mcp implements all of them:
| Transport | Command | Best For | Network | MCP Spec |
|---|---|---|---|---|
| stdio | click-to-mcp serve |
Local AI agents (Claude Code, Codex) | Same process | Original |
| HTTP+SSE | click-to-mcp serve-http |
Browser-based clients, remote access | HTTP (port 8000) | 2025-03 |
| Streamable HTTP | click-to-mcp serve-http-streamable |
Newer clients, simpler firewall traversal | HTTP (port 8001) | 2025-10 |
Let's break down each one.
1. stdio — The Default, and Still the Best for Local Agents
When you run click-to-mcp serve your-cli, the server communicates over standard input and output. The client (Claude Desktop, Claude Code, Codex) spawns your MCP server as a subprocess, sends JSON-RPC messages via stdin, and reads responses from stdout.
# Serve a CLI over stdio
click-to-mcp serve api-contract-guardian
# Serve all discovered CLIs (picks the first for stdio)
click-to-mcp serve --all
When to use stdio
- Claude Desktop — the default transport, configured in
claude_desktop_config.json - Claude Code CLI — runs MCP servers as child processes
- OpenAI Codex — same subprocess model
- Cursor IDE — supports both stdio and HTTP; stdio is simpler for local tools
- Any local-first agent — if the agent and the server are on the same machine, stdio is zero-configuration
Why stdio wins for local development
No network ports. No CORS. No firewall rules. The agent process and the MCP server process share a pipe. It's the fastest transport, the simplest to debug, and the one that requires zero infrastructure. If your agent runs on the same machine as your CLI tools, stdio is almost always the right answer.
Configuration for stdio
Use the config command to generate the exact JSON snippet for your client:
# Generate Claude Desktop config (stdio is the default transport)
click-to-mcp config api-contract-guardian
# Generate Cursor config
click-to-mcp config api-contract-guardian --client cursor
# Generate for VS Code Copilot
click-to-mcp config api-contract-guardian --client vscode
# Copy to clipboard instead of stdout
click-to-mcp config api-contract-guardian --copy
Output for Claude Desktop:
{
"mcpServers": {
"api-contract-guardian": {
"command": "click-to-mcp",
"args": ["serve", "api-contract-guardian"]
}
}
}
Paste that into ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows), restart Claude Desktop, and your CLI appears as a tool.
2. HTTP+SSE — For Browser and Remote Clients
Some MCP clients need an HTTP endpoint — web-based tools, remote agents, or setups where the server runs on a different machine. HTTP+SSE (Server-Sent Events) was the first HTTP transport in the MCP spec. The client sends requests via POST /message and receives streaming responses via an SSE connection on GET /sse.
# Install with HTTP support
pip install "click-to-mcp[http]"
# Serve over HTTP+SSE (default port 8000)
click-to-mcp serve-http api-contract-guardian
# Custom host and port
click-to-mcp serve-http api-contract-guardian --host 0.0.0.0 --port 9000
# Try it with the built-in demo
click-to-mcp demo-http
When to use HTTP+SSE
- Web-based MCP clients — browser tools that can't spawn local processes
- Remote agent access — agent on machine A, CLI tools on machine B
- Shared team servers — one MCP server endpoint, multiple agents consuming it
- Monitoring and debugging — you can hit the health endpoint and inspect traffic
The trade-off
HTTP+SSE requires two connections: one SSE stream for server-to-client messages and one POST endpoint for client-to-server requests. Some corporate firewalls and proxies block long-lived SSE connections. If you hit connectivity issues, Streamable HTTP is the fix.
Configuration for HTTP+SSE
# Generate config for HTTP transport
click-to-mcp config api-contract-guardian --transport http --port 8000
# For Cursor (which supports HTTP MCP servers)
click-to-mcp config api-contract-guardian --client cursor --transport http
Output:
{
"mcpServers": {
"api-contract-guardian": {
"url": "http://127.0.0.1:8000/sse"
}
}
}
Important: Start the server before connecting the client:
click-to-mcp serve-http api-contract-guardian --port 8000
3. Streamable HTTP — The Modern, Simpler HTTP Transport
Streamable HTTP is the newest MCP transport. Instead of maintaining a persistent SSE connection alongside the POST endpoint, it uses a single POST /message endpoint for everything. The server responds with the full JSON-RPC result in the HTTP response body — no SSE stream needed. Batch requests (arrays of JSON-RPC messages) are also supported.
# Install with HTTP support (same extra as HTTP+SSE)
pip install "click-to-mcp[http]"
# Serve over Streamable HTTP (default port 8001 — different from HTTP+SSE)
click-to-mcp serve-http-streamable api-contract-guardian
# Custom host and port
click-to-mcp serve-http-streamable api-contract-guardian --host 0.0.0.0 --port 9000
# Try it with the built-in demo
click-to-mcp demo-http-streamable
When to use Streamable HTTP
- Firewall-restricted environments — no SSE means no long-lived connections to block
- Newer MCP clients — clients built to the 2025-10 spec revision prefer this transport
- REST-friendly setups — standard POST/response pattern works with API gateways, load balancers, and reverse proxies
- Simpler debugging — one endpoint, standard HTTP semantics, easy to curl
Why two HTTP transports?
HTTP+SSE came first. It works, but the dual-connection model (POST + SSE) creates complexity: CORS for two endpoints, proxy configurations for long-lived connections, and connection lifecycle management. Streamable HTTP eliminates the SSE channel entirely. The MCP spec added it as the recommended HTTP transport going forward. click-to-mcp supports both so you can choose based on your client's capabilities.
curl -X POST http://127.0.0.1:8001/message -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"initialize","id":1,"params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"0.1"}}}'
If you get a JSON-RPC response, your server is live.
Configuration for Streamable HTTP
# Generate config for Streamable HTTP
click-to-mcp config api-contract-guardian --transport streamable-http --port 8001
# For VS Code Copilot
click-to-mcp config api-contract-guardian --client vscode --transport streamable-http
Output:
{
"mcpServers": {
"api-contract-guardian": {
"url": "http://127.0.0.1:8001/message"
}
}
}
The config Command: One Command, Five Clients
The click-to-mcp config command (added in v0.5.0) eliminates the most common setup mistake: wrong JSON structure for your specific MCP client. It generates the exact config format each client expects:
| Client | Config File Location | Config Key |
|---|---|---|
| Claude Desktop | ~/Library/Application Support/Claude/claude_desktop_config.json |
mcpServers |
| Cursor IDE | .cursor/mcp.json (project root) |
mcpServers |
| VS Code Copilot | .vscode/mcp.json (project root) |
mcp.servers |
| Windsurf | .windsurf/mcp.json (project root) |
mcpServers |
| Cline | ~/.cline/mcp_config.json |
mcpServers |
# Claude Desktop (default)
click-to-mcp config my-cli
# Cursor
click-to-mcp config my-cli --client cursor
# VS Code Copilot
click-to-mcp config my-cli --client vscode
# Windsurf
click-to-mcp config my-cli --client windsurf
# Cline
click-to-mcp config my-cli --client cline
# Generate config for ALL discovered CLIs at once
click-to-mcp config --all --client cursor
The --all flag is especially powerful: it discovers every Click/Typer CLI in your environment and generates a single config block with all of them. One paste and your agent has access to your entire CLI suite.
The list-tools Command: Preview Before You Serve
Before starting a server, you might want to know what tools will be exposed. The list-tools command (also v0.5.0) shows you the exact MCP tool surface — names, descriptions, and parameter schemas — without starting a server:
# List tools from a specific CLI
click-to-mcp list-tools api-contract-guardian
# List tools from ALL discovered CLIs
click-to-mcp list-tools --all
# JSON output for CI pipelines or scripting
click-to-mcp list-tools --all --json-output
Human-readable output:
Found 6 MCP tool(s):
api-contract-guardian_diff
Compare two OpenAPI specs and detect breaking changes
Parameters: base_branch, head_branch, format
Required: base_branch, head_branch
api-contract-guardian_check
Validate an OpenAPI spec against a ruleset
Parameters: spec_file, ruleset
Required: spec_file
JSON output (pipe into jq, use in CI, feed to documentation generators):
click-to-mcp list-tools --all --json-output | jq '.[].name'
Use cases for list-tools
- CI validation — verify your CLI exposes the expected tools before publishing a release
- Documentation — generate an API reference from the actual MCP tool surface
- Debugging — confirm parameter names, types, and required fields match what your agent sends
- Audit — check that internal-only commands aren't accidentally exposed as MCP tools
Decision Framework: Which Transport Should You Use?
Here's the simple decision tree:
Are you running the agent and the CLI tools on the same machine?
Yes → stdio. It's faster, simpler, and more secure. No ports, no CORS, no infrastructure.
Does your client need HTTP (remote, browser, or shared server)?
Yes → Streamable HTTP if your client supports it, otherwise HTTP+SSE. Streamable HTTP is the forward-compatible choice — single endpoint, no SSE, works through proxies. Use HTTP+SSE only if your client doesn't support the Streamable HTTP transport yet.
Not sure?
Start with stdio. You can always switch to an HTTP transport later — the config command generates the right JSON for any transport/client combination in seconds.
Ready to Serve Your CLIs?
Free and open source under Apache 2.0. Three transports, five clients, one command.
View on GitHub →Quick Reference: All click-to-mcp Commands
| Command | What It Does |
|---|---|
click-to-mcp discover |
List all installed Click/Typer CLIs |
click-to-mcp serve <name> |
Serve a CLI over stdio |
click-to-mcp serve-http <name> |
Serve a CLI over HTTP+SSE (port 8000) |
click-to-mcp serve-http-streamable <name> |
Serve a CLI over Streamable HTTP (port 8001) |
click-to-mcp list-tools <name> |
Preview MCP tools without starting a server |
click-to-mcp config <name> |
Generate client config JSON |
click-to-mcp demo |
Run the demo CLI over stdio |
click-to-mcp demo-http |
Run the demo CLI over HTTP+SSE |
click-to-mcp demo-http-streamable |
Run the demo CLI over Streamable HTTP |
What's Next
The MCP transport landscape is still evolving. The spec team is actively refining HTTP transport semantics, and more clients are adopting Streamable HTTP as the default. click-to-mcp tracks the spec — when a new transport lands, you'll get it as a pip install --upgrade away.
In the meantime, if you're building with Click or Typer and want your tools available to AI agents, the path is clear: pip install click-to-mcp, click-to-mcp discover, click-to-mcp serve. The transport you need is one flag away.