Any MCP host
stretto works with any MCP host that starts servers over stdio, which is how desktop apps, IDEs and agent frameworks run local servers. The change is always the same: in the host's configuration, replace the server's command with stretto-proxy, and put the server's command after --.
stretto init prints it
For Claude Code, Claude Desktop, Cursor and VS Code, stretto init prints the configuration in the host's own format. Give it the host, a name for the server, and the server's command after --:
stretto init --host cursor --domain orders -- npx -y some-mcp-serverIt prints (its arguments wrapped here):
{
"mcpServers": {
"orders": {
"command": "stretto-proxy",
"args": ["--record", "~/.stretto/logs/orders", "--domain", "orders",
"--", "npx", "-y", "some-mcp-server"]
}
}
}--hostisclaude-code,claude-desktop,cursororvscode. The configuration goes to stdout; where it goes, and the next steps, go to stderr.--domain NAMEis the server's name in the host, and the domain of its sessions and flows. The proxy records sessions in~/.stretto/logs/NAME, or where--record DIRsays.--write PATHwrites the configuration file instead of printing it. It leaves an existing file alone unless you add--force, which replaces the whole file, with any other servers in it; to add a server to a file that has others, merge the printed configuration by hand.- A server program named by a relative path is written with its absolute path, since the host starts servers in a directory of its own choosing.
init writes no env block. If the server needs environment variables, add them to its entry as before: the server inherits the proxy's environment. Every option is in the CLI reference.
In the console
The console's page for a server shows the same configuration for each host, from a registry of your servers. It also tests the connection, listing the server's tools as they are now.
Per host
| Host | --host | What init prints | Page |
|---|---|---|---|
| Claude Code | claude-code | a claude mcp add command; with --write .mcp.json, the project's file | Claude Code |
| Claude Desktop | claude-desktop | JSON for claude_desktop_config.json, with the proxy's full path | Claude Desktop |
| Cursor | cursor | JSON for ~/.cursor/mcp.json or .cursor/mcp.json | Cursor and VS Code |
| VS Code | vscode | JSON for .vscode/mcp.json, or the user mcp.json | Cursor and VS Code |
| A server reached over HTTP | none | write the entry by hand, with --upstream URL in place of the command | Streamable HTTP servers |
In any other host, write the entry by hand. Before:
{
"mcpServers": {
"orders": {
"command": "npx",
"args": ["-y", "some-mcp-server"],
"env": { "SOME_API_KEY": "…" }
}
}
}After:
{
"mcpServers": {
"orders": {
"command": "stretto-proxy",
"args": ["--record", "~/.stretto/logs/orders", "--domain", "orders",
"--", "npx", "-y", "some-mcp-server"],
"env": { "SOME_API_KEY": "…" }
}
}
}The host still sees a stdio MCP server with the same tools.
The three stages
A deployment moves through three configurations, and stretto init prints each. Only the proxy's arguments change; the server's command after -- stays the same.
1. Record. Log sessions to learn from:
stretto init --host cursor --domain orders -- npx -y some-mcp-server"args": ["--record", "~/.stretto/logs/orders", "--domain", "orders",
"--", "npx", "-y", "some-mcp-server"]Then learn a flow and review it:
stretto learn --sessions ~/.stretto/logs/orders --domain orders \
--habit-only --out ~/.stretto/orders.flow.json
stretto flow-show ~/.stretto/orders.flow.json2. Shadow. Serve the flow so that it decides and logs, but makes no lookups (shadow mode):
stretto init --host cursor --domain orders \
--flow ~/.stretto/orders.flow.json --shadow \
-- npx -y some-mcp-server"args": ["--record", "~/.stretto/shadow/orders", "--domain", "orders",
"--flow", "/home/me/.stretto/orders.flow.json",
"--flow-decider", "reach", "--flow-shadow",
"--", "npx", "-y", "some-mcp-server"]Then keep the flow to the calls where its lookups were the agent's own:
stretto promote --flow ~/.stretto/orders.flow.json \
--sessions ~/.stretto/shadow/orders \
--out ~/.stretto/orders-promoted.flow.json3. Serve. Let the promoted flow act:
stretto init --host cursor --domain orders \
--flow ~/.stretto/orders-promoted.flow.json \
-- npx -y some-mcp-server"args": ["--record", "~/.stretto/logs/orders", "--domain", "orders",
"--flow", "/home/me/.stretto/orders-promoted.flow.json",
"--flow-decider", "reach",
"--", "npx", "-y", "some-mcp-server"]A flow learned with --habit-only has no arbiter, so init serves it with the reach decider (--flow-decider reach), which asks no model and needs no key (deciders). A flow with an arbiter is served with it, and init reminds you that the server then needs TYPESAFE_API_KEY in its env. To name the only tools the flow may call on its own, add --flow-tools to args by hand (lookups).
What to watch for
- Paths. Hosts start servers without a shell. The proxy expands a leading
~in its own path options (--record,--flow,--context,--flow-log,--confirm-log,--oracle-cache), but the server's arguments after--are passed as written: give them as absolute paths. - Finding the program. Some hosts do not see your shell's
PATH.initwritesstretto-proxy's full path for Claude Desktop, which starts servers with a minimalPATH. If another host cannot start it, use its full path too, fromwhich stretto-proxy; the same goes fornpxor the server's own command. - Credentials. Put them in
env, not inargs. The proxy never records its environment; it replaces credential-looking arguments in the log's header with<redacted>, but only as a best effort. - One proxy per server. Wrap each server you want to record in its own proxy, with its own
--domain. A flow learns from one server's calls. - Its messages. The proxy writes to stderr, prefixed
stretto-proxy:; the first message says where the log is. Hosts usually keep a server's stderr in their MCP logs. - Exit status. The proxy exits with the server's status, or with 125 if the proxy itself fails, such as when the log cannot be created or the server cannot be started.
The conversation
MCP does not carry the conversation, and none of the hosts above hand it to a server. --context FILE reads it from a file that something else appends to, one JSON line per message; without it, a flow still works, but cannot prefer a value the user mentioned (the conversation). Leave it out unless your harness writes that file.
Related
stretto initandstretto-proxy's optionsstretto-proxyreference- Quick start
- The console: each server's host configuration and connection test