Fly.io — Provisioning Machines using MCPs¶
Summary¶
Sam Ruby's short Fly.io developer-blog post (2025-05-07) marking
the mutation transition of Fly.io's flyctl
MCP server: the read-only
two-tool prototype from a month earlier
([[sources/2025-04-10-flyio-30-minutes-with-mcp-and-flyctl|30 Minutes
With MCP and flyctl]]) now supports write operations — the
author "created my first fly volume using an MCP … and it worked the
first time," then a few hours later (with GitHub Copilot assistance)
added support for all fly volumes subcommands.
The architectural thesis: "Today's state of the art is K8S,
Terraform, web-based UIs, and CLIs. Those days are numbered."
Ruby sketches the "Make it so" provisioning flow — LLM scans your
code, produces a plan (regions, databases, S3, memory, machines),
you adjust, you approve, it runs, it examines logs on failure. The
post lands in flyctl v0.3.117 and documents a claude_desktop_config.json
wiring template pointing at flyctl mcp server. One load-bearing
safety claim: because the MCP server shells out to flyctl, "I
would have received an error had I tried to destroy a volume that is
currently mounted. Knowing that gave me the confidence to try the
command" — the CLI's existing safety invariants become the agent's
guardrail at zero additional engineering cost.
Key takeaways¶
- The mutation transition. One month after the read-only
fly logs+fly statusprototype, the same MCP server now covers the fullfly volumessurface (create / list / extend / show / fork / snapshots / destroy). This is the wiki's first instance of a wrapped-CLI MCP server crossing the read-only → mutating boundary with production resources. "A few hours later, and with the assistance of GitHub Copilot, i added support for all fly volumes commands." - "Make it so" as the new provisioning UX. Ruby's thesis paragraph is the canonical wiki statement of concepts/natural-language-infrastructure-provisioning: "Imagine a future where you say to your favorite LLM 'launch my application on Fly.io', and your code is scanned and you are presented with a plan containing details such as regions, databases, s3 storage, memory, machines, and the like. You are given the opportunity to adjust the plan and, when ready, say 'Make it so'." This is a plan-then-apply loop — Terraform's control discipline reimplemented as an LLM interaction.
- CLI safety invariants protect the agent user. "Since this
support is built on
flyctl, I would have received an error had I tried to destroy a volume that is currently mounted. Knowing that gave me the confidence to try the command." The MCP server inherits every guardrail the CLI's human-operator path already enforces — no agent-specific authz layer, no refuse-list, no dry-run mode required at the MCP tier. Canonical wiki instance of patterns/cli-safety-as-agent-guardrail: wrap a CLI that already knows how to refuse unsafe operations, and the wrapper stays a thin proxy. Structurally the same argument as the 2025-04-10--json-as-load-bearing observation (concepts/structured-output-reliability) — five-year-old CLI design decisions become load-bearing for AI integration. - Agent-surfaced resource hygiene as an emergent UX. "I asked for a list of volumes for an existing app, and Claude noted that I had a few volumes that weren't attached to any machines. So I asked it to delete the oldest unattached volume, and it did so." The LLM spotted a hygiene issue the human hadn't specifically asked about; the human responded to the finding with a mutation. Sibling shape to the agentic troubleshooting loop extended into provisioning — "the LLM noted something, brought it to my attention, and I asked it to make a change as a result."
- Alternatives the author explicitly rejects. Ruby enumerates three mechanisms he could have used and why the MCP flow beat each: (a) Machines API — "would have required some effort"; (b) flyctl directly — "would have had to use the documentation and a bit of copy/pasting of arguments"; (c) Fly.io dashboard — "isn't any way to sort the list or delete a volume" (dashboard is read-shaped; mutations are still CLI-first). Load-bearing wiki datum on concepts/agent-ergonomic-cli: agent-driven provisioning flattens the dashboard-vs-API-vs-CLI choice the author would otherwise have to make.
- Vision — MCP servers on Fly private network, sidecar, or in-app. "There will be MCP servers running on your Fly.io private network — either on separate machines, or in 'sidecar' containers, or even integrated into your app. These will enable you to monitor and interact with your application." First wiki disclosure of Fly.io's near-term roadmap for in-network MCP surfaces. Pairs with the 2025-04-08 "Our Best Customers Are Now Robots" post's long-lived-SSE session affinity framing — the routing infrastructure for this is already being built.
- MCP Inspector as agent-free validation surface. "You don't even need a LLM to try out the flyctl MCP server. If you have Node.js installed, you can run the MCP Inspector … visit http://127.0.0.1:6274/, click on 'Connect', then 'List Tools', select 'fly-platform-status', then click on 'Run Tool'." Tooling-ergonomic observation: the MCP ecosystem has a local-dev-mode validator so server authors can iterate on tool schemas without burning LLM tokens.
- Local MCP server risk continues. The post doesn't repeat
the 2025-04-10 security caveat explicitly, but the shape is
unchanged — the Claude Desktop / Cursor / GitHub Copilot
instance is running
flyctlas a native subprocess, now with mutation authority. "If you ask it to destroy a volume, that operation is not reversable. Perhaps try this first on a throwaway application." Canonical wiki instance of concepts/local-mcp-server-risk extending into the mutation-authority regime; the read-only → mutating transition raises the blast radius of prompt-injection accordingly.
Systems / concepts / patterns extracted¶
Systems
- systems/fly-flyctl — the CLI being wrapped; now has an mcp
server subcommand exposing tools.
- systems/model-context-protocol — the transport.
- systems/fly-volumes — the first mutating-resource surface
added to the MCP server (full fly volumes subcommand set).
- systems/fly-machines — second-order surface; volumes are
attached to Machines, so the MCP hygiene flow surfaces
Machine-attachment state.
- systems/claude-code — sample MCP client via
claude_desktop_config.json; GitHub Copilot is also named as
an authoring assistant for expanding the server.
Concepts
- concepts/natural-language-infrastructure-provisioning — the
"Make it so" thesis; natural language replaces K8S /
Terraform / UIs / CLIs as the human-infra interface.
- concepts/agent-ergonomic-cli — the design-pressure framing;
three named alternatives (API / CLI / dashboard) all lose to
natural language through MCP.
- concepts/agentic-troubleshooting-loop — extended into a
provisioning / hygiene loop: agent surfaces a finding, human
confirms, agent executes.
- concepts/structured-output-reliability — --json as the
substrate enabling the wrap.
- concepts/local-mcp-server-risk — the security posture, now
with mutation authority.
Patterns - patterns/wrap-cli-as-mcp-server — extended: the read-only 90-LoC April prototype now covers a full-mutation resource family without rewriting the substrate. - patterns/plan-then-apply-agent-provisioning — the "Make it so" interaction shape; plan presented, adjusted, approved, then executed; on failure the LLM pulls logs + proposes next steps. - patterns/cli-safety-as-agent-guardrail — the CLI's existing invariants (can't destroy a mounted volume) become the MCP server's authorization boundary for free.
Operational numbers¶
- Release version. flyctl v0.3.117 is the first flyctl that ships the MCP-server-with-volumes-support.
- First-try success. Volume creation via MCP worked "the first time."
- Build velocity. Full
fly volumessubcommand family added "a few hours later, and with the assistance of GitHub Copilot." - Config format.
claude_desktop_config.jsonsnippet binds the server as{"command": "/Users/rubys/.fly/bin/flyctl", "args": ["mcp", "server"]}. - MCP Inspector local port.
http://127.0.0.1:6274/. - Timeline gap. 2025-04-10 (read-only flymcp / 2 tools) → 2025-05-07 (mutation + full volumes surface) = ~27 days from read-only to production-mutation MCP.
Caveats / open questions¶
- No code disclosure for the mutation wrappers. The post
names
internal/command/mcp/server.go+ theserver/directory on superfly/flyctl but doesn't paste the actual tool-registration shape, safety checks at the MCP layer (if any beyond the CLI's own), or elicitation / confirmation UX. - No failure-mode numbers. No discussion of what happens on
a prompt-injection attempt that asks the agent to destroy any
volume without confirmation; the mitigation story leans on
flyctl-level checks, but those only cover
mounted vs unmounted, notis this the user's intent. - "Make it so" is a roadmap sketch. The plan-then-apply UX is described as "not science fiction" but "some assembly required"; it's an aspirational target for the post, not a deployed mechanism in v0.3.117.
- No scope on write-surface ceiling. The post doesn't say which other mutating command families are next (Machines, apps, networks, secrets, etc.); the implied gradient is "see what works well and what doesn't work so well, make adjustments, build support in a bottoms up fashion, and iterate rapidly."
- Local-MCP security caveat is understated vs the 2025-04-10 post. Given the mutation transition, the expected structural answer (patterns/disposable-vm-for-agentic-loop) isn't re-emphasized; the reader has to carry the earlier post's risk framing forward.
- Claude Desktop / Copilot / Cursor lock-in not discussed. The snippet is Claude Desktop–specific; the stdio transport means any MCP client works, but no cross-client matrix is given.
Source¶
- Original: https://fly.io/blog/mcp-provisioning/
- Raw markdown:
raw/flyio/2025-05-07-provisioning-machines-using-mcps-a5cb76bb.md
Related¶
- sources/2025-04-10-flyio-30-minutes-with-mcp-and-flyctl — the read-only predecessor; this post is the mutation-transition sequel, ~27 days later.
- sources/2025-04-08-flyio-our-best-customers-are-now-robots — the routing-infrastructure framing for in-network MCP servers Ruby gestures toward.
- systems/fly-flyctl — the wrapped CLI.
- systems/model-context-protocol — the transport.
- systems/fly-volumes — the first mutating resource surfaced.
- concepts/natural-language-infrastructure-provisioning — the canonical thesis.
- patterns/wrap-cli-as-mcp-server — extended from read-only to mutation.
- patterns/plan-then-apply-agent-provisioning — the "Make it so" flow.
- patterns/cli-safety-as-agent-guardrail — the
flyctl-refuses-to-destroy-mounted-volume safety mechanism. - companies/flyio.