Horizon Deploy

by @zzstoatzz.io · created Sep 11, 2026

Install this skill

npx @skillz.supply/cli install did:plc:xbtmt2zjwlrfegqvch7fboei/skills.horizon-deploy

Writes SKILL.md into your agent's skills folder under this skill's name. No CLI? Download the file, or view it.

name: "horizon-deploy"

description: "Deploy a FastMCP server to Prefect Horizon from a local source archive."

createdAt: "2026-09-11T18:46:00.191354+00:00"

repoUrl: "https://skillz.supply/skills/did:plc:xbtmt2zjwlrfegqvch7fboei/skills.horizon-deploy/SKILL.md"

# horizon deploy

Horizon can build a hosted server from an uploaded source archive. Use this path
for a prototype or one-off utility that does not need repository automation. Use
a connected repository when the server needs preview builds or automatic deploys.

## environment

Use the requested organization and project with credentials from the user's configured
secret store or existing authenticated session. Never assume an organization, API key
location, deployment script, or serving domain from another environment.

Prefer a maintained SDK or existing project deployment tooling. Use the live OpenAPI
contract for operations those tools do not support.

## prepare

Collect these inputs before changing Horizon:

- organization slug
- project slug and display name
- source directory
- entrypoint, including the server object when needed
- dependency file, when automatic discovery is insufficient
- deployment target, normally `production`

Use `fastmcp inspect <entrypoint> --json` to confirm the server loads and exposes
the expected capabilities. Run the project's checks before packaging it.

Use a configured `HORIZON_API_KEY` for headless deployment. When no API key
is available and interactive login is appropriate, use `fastmcp login` and
confirm the account with `fastmcp whoami`. Never
print the key, pass it on the command line, or persist it in project files.

## deploy the archive

Read Horizon's current
[Deploy without Git](https://docs.horizon.prefect.io/servers/upload) guide before
deploying. Use the live
[OpenAPI document](https://horizon.prefect.io/api/v0/openapi.json) for current
request and response schemas. Do not reconstruct a request from memory when the
contract is available.

Follow this sequence:

1. List the organizations available to the credential and select the requested
   organization. Confirm its role includes project writes.
2. List the organization's projects. Reuse the project with the requested slug.
   If none exists, create one hosted project, then read its production target.
3. Build a temporary gzipped tar archive from the source directory. Exclude
   `.env*`, `.git`, virtual environments, installed dependencies, build output,
   caches, and local agent state. Inspect the archive contents before upload.
4. Calculate the archive's byte size and hexadecimal SHA-256. Request a presigned
   upload URL with those values, then upload the archive bytes with exactly the
   headers returned by Horizon.
5. Create a version whose source is the uploaded archive checksum. Supply the
   entrypoint and dependency file as build configuration. Creating the version
   starts the build.
6. Poll that version until it becomes ready or fails. On failure, report the
   build error and retrieve its logs. Do not deploy a failed version or create
   another project as a retry strategy.
7. Create a deployment that selects the ready version and requested target. Poll
   until the deployment succeeds or fails.
8. Read the serving URL from the target or deployment. Verify it with
   `fastmcp list <url> --json`, then call one safe tool and check its result.

Set runtime credentials through Horizon project secrets before the first
production deployment. Keep them out of source archives and command output.

## update an existing project

Reuse the project and target. Create and upload a new archive, build a new
version, deploy that version, and repeat the same verification. Do not create a
new project for each revision.

## API invariants

These routes were checked on 2026-09-08; confirm against the live contract:

- List organizations with `GET /me/organizations`, not `GET /organizations`.
- A hosted project creates a `production` target and a `fastmcp.app` serving URL.
- Set secrets through `POST /organizations/{org}/projects/{id}/environments/production/secrets`
  using `{keyName, value, sensitive: true}`.
- Public access is a project `authMode` setting. Change it to `passthrough` only
  when public access is requested; the server may still enforce its own auth.
- Target logs require `startDate` and `endDate` query parameters.

- Upload the archive before creating its version. Version creation starts the
  build immediately.
- Send exactly the headers returned with the presigned URL. Do not reconstruct
  the S3 signature or checksum header.
- Use the hexadecimal archive digest for Horizon's `checksumSha256` fields.
- Treat a project-write `404` as a possible permission failure. Check the
  organization role before changing endpoint paths.
- If this skill differs from the live API, the OpenAPI contract and returned
  upload instructions win.