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.