# AgentOS on Fly.io (/deploy/templates/fly/deploy)



**The [agentos-fly](https://github.com/agno-agi/agentos-fly) template is for teams that develop locally with Docker and deploy to production on Fly.io.**

It includes:

* **Agno**, the team that coordinates platform work, also exposed as the `agno` MCP tool.
* **Platform Builder**, which creates and updates agents, teams, and workflows through the runtime.
* **Platform Manager**, which inspects the platform, eval history, deployment checks, and schedules.
* **Platform Engineer**, which inspects the project’s source code.
* **Eight [skills](/deploy/coding-agents)** for setting up, building, testing, reviewing, and deploying the project with a coding agent.

Coding agents can use these skills with the AgentOS API, evals, traces, and container logs to inspect and improve the platform.

## Get started [#get-started]

Copy the prompt below into Claude Code, Cursor, or Codex to configure and run the template with a coding agent.

```txt
Help me set up my agent platform and build my first agent.

Clone https://github.com/agno-agi/agentos-fly into a folder called agent-platform, cd in, and run the setup-platform skill (in .agents/skills/).
```

Prefer to drive yourself? Follow the manual steps below.

## Manual setup [#manual-setup]

**Prerequisites:** [Docker](https://www.docker.com/get-started/) installed and running. An [OpenAI API key](https://platform.openai.com).

<Steps>
  <Step title="Clone and configure">
    ```bash
    git clone https://github.com/agno-agi/agentos-fly.git agentos
    cd agentos

    cp example.env .env
    ```

    Edit `.env` and set `OPENAI_API_KEY`.
  </Step>

  <Step title="Start the platform">
    ```bash
    docker compose up -d --build
    ```

    The first build takes a few minutes. Confirm the API is available at [localhost:8000/docs](http://localhost:8000/docs).
  </Step>

  <Step title="Verify end to end">
    ```bash
    ./scripts/mcp_check.sh
    ```

    Prints `MCP OK` with the tool count and a real agent answer through the MCP endpoint.
  </Step>

  <Step title="Connect the AgentOS UI">
    1. Open [os.agno.com](https://os.agno.com) and sign in.
    2. Click **Connect OS**, enter `http://localhost:8000`, and name it **Local AgentOS**.
  </Step>

  <Step title="Build your first agent">
    1. Chat with **Platform Builder**: "Build an agent that tracks AI news and writes a daily brief". Go through the agent development process.
    2. Once created, click **Refresh** on the top right, pick the new agent from the **Agents** dropdown, and ask: "What's new with Anthropic?"
    3. Ask **Platform Manager**: "How healthy is the platform?" It answers from eval history, deployment checks, schedules, and the agent you just built.
  </Step>
</Steps>

<Check>
  At this point, your AgentOS is running locally.
</Check>

## Connect your frontends [#connect-your-frontends]

| Frontend                    | How                                                                                                                                                                                                              |
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| MCP clients on your machine | `uvx agno connect` auto-detects Claude Code, Claude Desktop, Codex, and Cursor and registers `http://localhost:8000/mcp`. Verify from the app: "can you access my agentos mcp?"                                  |
| AgentOS UI                  | [os.agno.com](https://os.agno.com) → **Connect OS** → `http://localhost:8000`.                                                                                                                                   |
| claude.ai and ChatGPT       | Hosted sessions can't reach localhost. Deploy to production first, then add `https://<app>.fly.dev/mcp` as a custom connector and approve the consent page with the `MCP_CONNECT_SECRET` that `up.sh` generates. |
| Slack                       | Set `SLACK_BOT_TOKEN` and `SLACK_SIGNING_SECRET`. See [Slack setup](/agent-os/interfaces/slack/setup).                                                                                                           |
| Your product                | Call the AgentOS REST API with 80+ endpoints. Browse them at `/docs`.                                                                                                                                            |

## Deploy to production [#deploy-to-production]

**Prerequisites:** [flyctl](https://fly.io/docs/flyctl/install/) installed and `fly auth login` completed.

<Steps>
  <Step title="Create a production env">
    ```bash
    cp .env .env.production
    ```

    Edit `.env.production` with production values: a different OpenAI key, production-only credentials, a different Slack workspace.
  </Step>

  <Step title="Deploy">
    ```bash
    ./scripts/fly/up.sh
    ```

    Provisions the app and an unmanaged Fly Postgres on the same private network, pushes your credentials as Fly secrets, and deploys a single always-on machine. Fly app names are global, so the script generates `agentos-<suffix>` and records it in `fly.toml`. It also sets `AGENTOS_URL` to `https://<app>.fly.dev` before the first deploy so scheduled jobs reach the platform, and generates `MCP_CONNECT_SECRET`, the OAuth consent secret for chat apps, into `.env.production` when it's missing.

    Deploys use `fly deploy --ha=false` to keep the template at one machine. Postgres coordinates schedule claims across workers; adding a machine does not inherently double every scheduled run. Default sizing is `shared-cpu-2x` with 4 GB (~~$21/mo) plus a small Postgres machine (~~$4/mo). For dedicated cores, switch the size to `performance-2x` (\~$62/mo) in `fly.toml`.

    <Note>
      Fly's stock 

      `postgres-flex`

       image does not ship pgvector: sessions and memory work out of the box, but knowledge bases (RAG) need the extension. Set 

      `FLY_PG_IMAGE`

       to a 

      `postgres-flex`

       derivative with pgvector installed before running 

      `up.sh`

      . Without it, the script prints a warning and everything except knowledge bases works. See 

      [Enable pgvector](/deploy/templates/fly/reference#customize)

      .
    </Note>
  </Step>

  <Step title="Mint your JWT key">
    The script pauses for a `JWT_VERIFICATION_KEY`. Token-Based Authorization is on by default. Production startup requires that verification key or a readable JWKS file at the container path in `JWT_JWKS_FILE`; otherwise the process exits.

    1. Open [os.agno.com](https://os.agno.com), click **Connect OS** → **Live**, and enter your Fly URL.
    2. Name it **Live AgentOS**, turn on &#x2A;*Token-Based Authorization (JWT)** on the connection panel, and connect. The UI generates the public key. If the OS is already connected, enable the setting under **Settings** → **OS & Security**.
    3. Copy the public key and paste the full PEM into the `up.sh` prompt. The script saves it to your env file and deploys.

    If you skip the prompt, add `JWT_VERIFICATION_KEY` to `.env.production` later and run `./scripts/fly/env-sync.sh`. For JWKS, bake or mount the file in the Fly Machine, set `JWT_JWKS_FILE` to its container path, then deploy. Env sync only forwards the path.

    <Note>
      Live AgentOS connections are a paid feature. Use code 

      `PLATFORM30`

       for one month off.
    </Note>
  </Step>

  <Step title="Connect your MCP clients">
    Re-run `uvx agno connect`, this time pointed at your deployed domain:

    ```bash
    uvx agno connect --url https://<app>.fly.dev
    ```

    For claude.ai and ChatGPT on the web: add `https://<app>.fly.dev/mcp` as a custom connector in the chat app's connector settings. Leave the form's optional OAuth fields (client ID / client secret) empty. Click **Connect** and, on the consent page, enter the `MCP_CONNECT_SECRET` that `up.sh` generated during deploy (saved in `.env.production`).
  </Step>

  <Step title="Confirm it's live">
    ```bash
    fly logs
    ```

    The app name comes from `fly.toml`, so no `--app` flag is needed. Open `https://<app>.fly.dev/docs` to confirm the API is serving.
  </Step>
</Steps>

<Check>
  Your AgentOS is live on Fly.io.
</Check>

### Redeploy after code changes [#redeploy-after-code-changes]

```bash
./scripts/fly/redeploy.sh
```

### Sync environment variables [#sync-environment-variables]

```bash
./scripts/fly/env-sync.sh
```

### Tear down [#tear-down]

```bash
./scripts/fly/down.sh
```

<Warning>
  Destroys the Fly app and its Postgres, including all data in the database. Once both are confirmed gone, it resets `fly.toml` so a future `up.sh` provisions fresh.
</Warning>

## Next steps [#next-steps]

<CardGroup cols="2">
  <Card title="Build with coding agents" icon="wand-magic-sparkles" href="/deploy/coding-agents">
    Skills to create → improve → evaluate your platform using coding agents.
  </Card>

  <Card title="Fly.io reference" icon="book" href="/deploy/templates/fly/reference">
    Commands, environment variables, troubleshooting.
  </Card>
</CardGroup>
