Fly.io — Launching MCP Servers on Fly.io¶
Summary¶
Short developer-blog post ("part showing off, part opinion") by
Sam Ruby announcing
fly mcp launch —
a new flyctl subcommand (shipped in
flyctl v0.3.125) that takes an existing local / stdio-style
MCP server command and one-shots it into a remote
HTTP/Streamable-HTTP MCP server running as a
Fly Machine, with client-config files
rewritten in place, bearer-token auth set up by default, and
--secret KEY=value flags piped through to the Machine's env.
The post frames the ergonomics problem — "two types of MCP
servers" + JSON-config files scattered across OS-specific paths +
OAuth 2.1 for remote servers is not casual-use-friendly — and
proposes fly mcp launch as the single-command solution.
Key takeaways¶
- Three MCP server shapes are named explicitly ("two types of MCP servers… and a third, deprecated type"): (1) small local process that runs on the operator's machine (stdio transport), (2) remote HTTP server standardising on OAuth 2.1, (3) a deprecated third shape. This wiki's concepts/local-mcp-server-risk page already captures the security case against (1); this post names (2) as Fly.io's target. (Source: sources/2025-05-19-flyio-launching-mcp-servers-on-flyio.)
- The MCP client-config problem is fragmentation, not
complexity. "With Claude, this goes into
~/Library/Application Support/Claude/claude_desktop_config.json, and is found under aMCPServerkey. With Zed, this file is in~/.config/zed/settings.jsonand is found under acontext_serverskey. And some tools put these files in a different place depending on whether you are running on MacOS, Linux, or Windows." Canonical wiki instance of concepts/mcp-client-config-fragmentation.fly mcp launchhandles this via a--claude/--cursor/--zed/--vscode/--windsurf/--neovimselector flag family that tells the command which client's JSON to rewrite. (Source: sources/2025-05-19-flyio-launching-mcp-servers-on-flyio.) - One canonical invocation. The post's demo is the
Slack MCP server
(NPM distribution:
@modelcontextprotocol/server-slack). The "here's our current thinking" command is:
fly mcp launch \
"npx -y @modelcontextprotocol/server-slack" \
--claude --server slack \
--secret SLACK_BOT_TOKEN=xoxb-your-bot-token \
--secret SLACK_TEAM_ID=T01234567
Four flag shapes: positional quoted command (the stdio MCP
server invocation, executed inside the Fly Machine), client
selector (--claude), server name in client config
(--server slack), and repeated --secret KEY=value
(becomes Fly Machine secrets).
(Source:
sources/2025-05-19-flyio-launching-mcp-servers-on-flyio.)
- Bearer-token authentication is on by default on both ends.
"By default, bearer token authentication will be set up on
both the server and client." That is: fly mcp launch does
not require the operator to stand up OAuth 2.1; it provisions a
token, writes it into the client-config JSON, and enforces it
at the server. OAuth 2.1 is still supported as an option.
(Source:
sources/2025-05-19-flyio-launching-mcp-servers-on-flyio.)
- All Fly platform knobs are available. "Complete with the
options you would expect from Fly.io, like the ability to
configure auto-stop, file contents, flycast, secrets, region,
volumes, and VM sizes." Concretely: the resulting server is a
first-class Fly Machine — auto-stop
works, Flycast private-network exposure
works, Volumes attach, region pinning
works. (Source:
sources/2025-05-19-flyio-launching-mcp-servers-on-flyio.)
- Client coverage at launch: six editors / agents. "Support
for Claude, Cursor, Neovim, VS Code, Windsurf, and Zed are
built in. You can select multiple clients and configuration
files." (Source:
sources/2025-05-19-flyio-launching-mcp-servers-on-flyio.)
- All MCP transports are supported, not just the recommended
ones. Later in the post: "Support for all transports, not
just the ones we recommend. Ability to deploy using the
command line or the Machines API, with a number of different
options that allow you to chose between elegant simplicity and
excruciating precise control. Ability to deploy each MCP
server to a separate Machine, container, or even inside your
application. Access via HTTP Authorization, wireguard tunnels
and flycast, or reverse proxies." The one-Machine-per-server
model is the default, but the platform also covers
one-container-per-server and in-process-as-a-library shapes.
(Source:
sources/2025-05-19-flyio-launching-mcp-servers-on-flyio.)
- Beta status acknowledged in-line. "Be forewarned, most
pages are marked as beta. But the examples provided all work.
Well, there may be a bug here or there, but the examples as
shown are thought to work. Maybe." Classic Fly.io voice; the
feature is shipping but the shape is still being negotiated
with customers. Closing sentence: "Let's figure out the ideal
ergonomics of deploying MCP servers remotely together!"
(Source:
sources/2025-05-19-flyio-launching-mcp-servers-on-flyio.)
Systems extracted¶
- systems/fly-mcp-launch — new system page. The
fly mcp launchflyctl subcommand + the broader Fly MCP deployment surface (Machines API shape, documentation at fly.io/docs/mcp,fly mcpfamily of subcommands). - systems/fly-flyctl — extended. The
fly mcp launchsubcommand is a flyctl verb (not a separate binary). - systems/fly-machines — extended. A remote MCP server
provisioned by
fly mcp launchis a Fly Machine; all Machine-level knobs apply (auto-stop, Flycast, Volumes, region, VM size). - systems/fly-proxy — extended. The Fly Proxy fronts the remote MCP server and provides the session-affinity routing required by long-lived MCP/SSE connections (see concepts/mcp-long-lived-sse + patterns/session-affinity-for-mcp-sse).
- systems/flycast — extended. Named in-post as one of the supported access paths for MCP servers that should not be exposed on the public internet.
- systems/model-context-protocol — extended. This is the first wiki instance of a platform-native remote-MCP-server launcher as a deployment pattern for MCP.
Concepts extracted¶
- concepts/mcp-client-config-fragmentation — new concept page. The JSON-config-file fragmentation the post leads with: each MCP-aware client (Claude Desktop, Cursor, Zed, VS Code, Windsurf, Neovim) stores its MCP-server list in a different file, under a different config key, with OS-dependent paths. Canonical wiki statement of why the manually-edit-JSON ergonomics of MCP are a tax on operator workflow.
- concepts/local-mcp-server-risk — reinforced. The post
names the same three problems with local-process MCP servers
that the existing
local-mcp-server-riskpage captures — arbitrary local execution, credential-inheritance, and the attack surface of "MCP servers have both taken the world by storm, and still trying to figure out what they want to be when they grow up." - concepts/mcp-long-lived-sse — extended. The post's mention of remote MCP servers speaking HTTP / SSE + per-Machine deployment is the substrate on which the session-affinity routing pattern already in this wiki runs.
Patterns extracted¶
- patterns/remote-mcp-server-via-platform-launcher — new pattern page. Platform CLI takes a local / stdio MCP server command, wraps it into a remote HTTP MCP server running as a platform-native compute primitive (in this case a Fly Machine), inverts the auth surface from operator-workstation-credential- inheritance to bearer-token-in-client-config, and rewrites the client's config JSON file(s) in place. One command turns "npx this package locally" into "call this HTTPS endpoint, authenticated by bearer token, from any MCP client."
- patterns/wrap-cli-as-mcp-server — counterpoint / inverse.
The earlier Fly.io flymcp post (2025-04-10) establishes the
pattern of wrapping a CLI as an MCP server for local
stdio consumption. This post's
fly mcp launchis the remote-deployment target for that pattern: once you have a stdio MCP server (by wrapping a CLI, writing one from scratch, or pulling a third-party one off NPM),fly mcp launchturns it into a remote server. The two posts together cover the full local ↔ remote axis of MCP-server ergonomics.
Operational numbers¶
- flyctl version bar:
v0.3.125(minimum version that shipsfly mcp launch). - Client coverage at launch: 6 (Claude, Cursor, Neovim, VS Code, Windsurf, Zed). Multi-client selection is supported in one invocation.
- MCP age at post time: "days away from turning six months old" (MCP launched 2024-11, post dated 2025-05-19).
- Demo command's secret count: 2 (
SLACK_BOT_TOKEN,SLACK_TEAM_ID).
Caveats¶
- Product-launch post, not an architecture retrospective. No internal numbers on Fly Machine cold-start for MCP, no per-Machine vs per-container sharing trade-off analysis, no operational data on how many MCP servers have been launched this way since shipping.
- Beta status: the post itself flags that "most pages are marked as beta" and that examples "as shown are thought to work. Maybe." The shape is being figured out in public.
- Bearer-token-by-default is the easy mode, not the secure mode. The post lists HTTP Authorization + WireGuard tunnels
- Flycast + reverse proxies as the access-path options, with bearer token as the default — the author is not making a strong claim about bearer-token being the right long-term posture, just the casual-use-friendly one.
- OAuth 2.1 framing is editorial. The post's complaint about OAuth 2.1 being heavyweight for casual use is Sam Ruby's opinion, not a design critique of the MCP authorization spec.
- No head-to-head with Cloudflare / Anthropic hosted MCP.
The post does not position
fly mcp launchagainst Cloudflare'sMcpAgent/ Durable-Object MCP deployment pattern, Anthropic's hosted MCP, or third-party deployment platforms — framing is purely "here's what we shipped." - Fly.io is a Tier-3 source. Per AGENTS.md scope rules, Tier-3 ingests require explicit distributed-systems architecture content. This post clears the bar on the remote-MCP-deployment + platform-launcher architectural contribution; the marketing framing ("part showing off") is acknowledged up front.
Source¶
- Original: https://fly.io/blog/mcp-launch/
- Raw markdown:
raw/flyio/2025-05-19-launching-mcp-servers-on-flyio-87417899.md
Related¶
- companies/flyio.
- systems/fly-mcp-launch — the flyctl subcommand this post announces.
- systems/fly-flyctl — the CLI that hosts the new subcommand.
- systems/model-context-protocol — the protocol the post targets.
- systems/fly-machines — the compute primitive a launched MCP server is a Machine of.
- concepts/mcp-client-config-fragmentation — the editorial motivation.
- concepts/local-mcp-server-risk — the security motivation.
- concepts/mcp-long-lived-sse — the routing constraint a remote MCP server inherits.
- patterns/remote-mcp-server-via-platform-launcher — the pattern this post names.
- patterns/wrap-cli-as-mcp-server — the counterpoint pattern from the earlier flymcp post.
- patterns/session-affinity-for-mcp-sse — the routing pattern remote MCP servers rely on.