# 30 Minutes With MCP and flyctl

DevFeed: [30 Minutes With MCP and flyctl](<https://devfeed.tech/articles/30-minutes-with-mcp-and-flyctl-1685.md>)

Original publisher: [Read original article](<https://fly.io/blog/30-minute-mcp/>)

Published: 2025-04-10T00:00:00Z

Content type: article

Language: en

Sources: [The Fly Blog](<https://devfeed.tech/sources/the-fly-blog.md>)

Topics: [MSP MCP](<https://devfeed.tech/topics/msp-mcp.md>), [AI Chat](<https://devfeed.tech/topics/ai-chat.md>)

Tags: [automation](<https://devfeed.tech/tags/automation.md>), [cdn](<https://devfeed.tech/tags/cdn.md>), [claude](<https://devfeed.tech/tags/claude.md>), [close-to-users](<https://devfeed.tech/tags/close-to-users.md>), [deploy-app-servers](<https://devfeed.tech/tags/deploy-app-servers.md>), [docker](<https://devfeed.tech/tags/docker.md>), [elixir](<https://devfeed.tech/tags/elixir.md>), [fly](<https://devfeed.tech/tags/fly.md>), [fly-io](<https://devfeed.tech/tags/fly-io.md>), [go](<https://devfeed.tech/tags/go.md>), [heroku-alternative](<https://devfeed.tech/tags/heroku-alternative.md>), [heroku-competitor](<https://devfeed.tech/tags/heroku-competitor.md>), [hosting](<https://devfeed.tech/tags/hosting.md>), [i](<https://devfeed.tech/tags/i.md>), [json](<https://devfeed.tech/tags/json.md>), [llm](<https://devfeed.tech/tags/llm.md>), [logs](<https://devfeed.tech/tags/logs.md>), [mcp](<https://devfeed.tech/tags/mcp.md>), [mcp-server](<https://devfeed.tech/tags/mcp-server.md>), [networking](<https://devfeed.tech/tags/networking.md>), [postgresql-clusters](<https://devfeed.tech/tags/postgresql-clusters.md>), [python](<https://devfeed.tech/tags/python.md>), [servers](<https://devfeed.tech/tags/servers.md>)

## AI overview

A developer describes building a minimal MCP server for flyctl in 30 minutes. The server exposes flyctl status and log commands so an LLM can inspect an application and investigate unhealthy machines.

## Source excerpt

I wrote this post on our internal message board, and then someone asked, "why is this an internal post and not on our blog", so now it is. well, Cursor built I built the most basic MCP server for flyctl I could think of. It took 30 minutes. MCP, for those unaware, is the emerging standard protocol for connecting an LLM (or an app that drives an LLM in the cloud, like Claude Desktop) to, well, anything. The "client" in MCP is the LLM; the "server" is the MCP server and the "tools" it exports. It mostly just defines an exchange of JSON blobs; one of those JSON blobs enables the LLM to discover all the tools exported by the server. A classic example of an MCP server is (yes, really) a Python shell. MCP publishes to (say) Claude that it can run arbitrary Python code with a tool call; not only that, says the tool description, but you can use those Python tool calls to, say, scrape the web. When the LLM wants to scrape the web with Python, it uses MCP send a JSON blob describing the Python tool call; the MCP server (yes, really) runs the Python and returns the result. Because I have not yet completely lost my mind, I chose to expose just two flyctl commands: fly logs and fly status. Because I'm lazy, I used MCP's stdio mode; the MCP server just captures the output of flyctl. Because someone already wrote a really good Go MCP library , this whole thing is like 90 lines of code. We may have gotten a little lucky, because we made a decision back in 2020 to give most of our flyctl commands a json mode to make them easier to drive from automation. I use that in my MCP server. I don't know how much of a difference it made. It's, uh, annoyingly useful. I loaded it up and pointed it at unpkg. I got this, from Claude: This appears to be a globally distributed CDN service running the unpkg JavaScript package registry, with machines strategically placed around the world to provide low-latency access. There are some stability issues with a couple of the machines, and several have exp