> ## Documentation Index
> Fetch the complete documentation index at: https://docs.horizon.prefect.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Hosted servers

> Build, deploy, protect, and observe Python MCP and FastMCP servers on Horizon.

export const memoryAllocation = 1024;

export const sessionTTL = 24;

export const requestTimeout = 170;

export const openAuthenticationPlans = "Developer and Enterprise";

Hosted servers are the Horizon-managed path for Python MCP and FastMCP servers
you keep in Git. Point Horizon at a repository and entrypoint, and each build
turns one source revision into an artifact that can be served from a stable MCP
URL, promoted, previewed, or rolled back.

The important boundary is simple: Horizon owns the path from source to a
protected deployment URL. Your server code still owns the MCP behavior behind
that URL, including tools, resources, prompts, upstream API calls, durable state,
and application errors.

<CardGroup cols={2}>
  <Card title="Build from a commit" icon="code-branch">
    Resolve a branch, pull request, or manual selection to an exact Git commit
    before packaging the server.
  </Card>

  <Card title="Serve one MCP URL" icon="route">
    Give clients a Horizon deployment URL, usually ending in <code>/mcp</code>,
    instead of exposing a process or runtime address.
  </Card>

  <Card title="Protect before Python runs" icon="shield">
    Check Horizon authentication, server access, and capability policy before a
    protected request reaches your handlers.
  </Card>

  <Card title="Debug by boundary" icon="chart-line">
    Use build logs, request logs, server logs, clients, and user activity to
    see where a request stopped.
  </Card>
</CardGroup>

## When hosted is the right shape

Choose a hosted server when the server code should be built, deployed, and run
by Horizon.

Hosted works well when:

* You are creating a new Python MCP or FastMCP server and want the deployment
  lifecycle attached from the start.
* The source lives in Git and each deployment should point to a specific commit.
* Pull request previews should test code, manifests, and environment changes
  before production promotion.
* Clients should use a shared Horizon endpoint with server and capability access
  checks in front of the code.
* Operators need build logs, request logs, server logs, clients, and users
  connected to the same server record.

If the server already runs somewhere else and should stay there, register it as
an [external server](/servers/external). If clients should connect to one
curated endpoint made from selected capabilities across multiple servers, use a
[remix server](/servers/remix).

## Client contract

To clients, a hosted server is a Horizon MCP endpoint. Clients call the live or
preview deployment URL. Horizon identifies the selected deployment, checks
access when the endpoint is protected, and routes accepted MCP requests to the
artifact selected for that deployment.

| Concern        | What clients and operators can expect                                                                                                                                                                                                        |
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Source         | A build uses a specific Git commit. Moving a branch after the build starts does not change that artifact.                                                                                                                                    |
| Endpoint       | Clients call the Horizon deployment URL, not an internal runtime address.                                                                                                                                                                    |
| Build output   | A successful build creates an artifact, a discovered MCP manifest, and build logs.                                                                                                                                                           |
| Deployment     | A live or preview deployment selects one successful artifact to serve behind a stable URL.                                                                                                                                                   |
| Authentication | Hosted servers have Horizon authentication enabled by default. They can optionally exchange an authenticated user's credential for a linked upstream credential. Disabling Horizon authentication is available on {openAuthenticationPlans}. |
| Authorization  | Server access and capability policies are evaluated before protected hosted server code runs.                                                                                                                                                |
| Runtime        | Python handlers run with a {requestTimeout}-second request window and {memoryAllocation} MB of memory.                                                                                                                                       |
| State          | Local memory and files are ephemeral. Store durable application state outside the local filesystem.                                                                                                                                          |
| Observability  | Horizon records hosted traffic across requests, clients, users, builds, and server logs.                                                                                                                                                     |

<Info>
  Most hosted-server debugging starts by locating the boundary. Build failures
  happen before an artifact exists. Gateway denials happen before Python code
  runs. Runtime failures happen after Horizon has forwarded the request to your
  deployed server.
</Info>

## Ownership boundary

Hosted does not make Horizon the owner of every part of the application. It
separates platform mechanics from server behavior.

| Area              | Horizon owns                                                                                    | You own                                                                                          |
| ----------------- | ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| Source and builds | Resolving commits, installing dependencies, packaging artifacts, and recording build logs.      | Repository content, entrypoint behavior, dependency declarations, and code review.               |
| Deployments       | Selecting which successful artifact serves live or preview traffic.                             | Deciding what to promote, test, or roll back.                                                    |
| Gateway           | Deployment URLs, Horizon authentication, server access, capability policy, and session routing. | Choosing who should have access and which capabilities are sensitive.                            |
| Runtime           | Starting the hosted Python process and enforcing the request window and memory allocation.      | Handler behavior, startup work, upstream calls, application errors, and durable storage choices. |
| Observability     | Horizon-side request, client, user, build, and server log records.                              | Interpreting application output and adding useful server logs.                                   |

## Lifecycle

<Steps>
  <Step title="Connect source">
    Link the Git repository that contains the Python MCP or FastMCP server.
    Choose the entrypoint and dependency file Horizon should use for builds.
  </Step>

  <Step title="Create a build">
    Horizon resolves the requested branch, pull request, or manual selector to
    an exact commit, installs dependencies, packages the server, and inspects
    the MCP surface area.
  </Step>

  <Step title="Publish an artifact">
    A successful build produces an immutable artifact and manifest. A failed
    build leaves the currently selected live artifact unchanged.
  </Step>

  <Step title="Serve a deployment">
    A live or preview deployment selects one successful artifact. Promotion and
    rollback change the artifact behind the same deployment URL.
  </Step>

  <Step title="Route client traffic">
    MCP clients call the deployment URL. Horizon identifies the deployment,
    checks access, preserves MCP session routing for up to {sessionTTL} hours,
    and forwards accepted requests to the hosted runtime.
  </Step>

  <Step title="Run your handlers">
    Tool, resource, and prompt handlers execute in your Python process. Horizon
    captures request outcomes and stdout or stderr emitted by the running
    server.
  </Step>
</Steps>

## Authentication model

Hosted servers expose one authentication control, Horizon Authentication, which
is either enabled or disabled.

| Horizon Authentication | User experience                                                                                  | Request behavior                                                                                                   |
| ---------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ |
| Enabled                | The MCP client completes Horizon sign-in or sends a Horizon API key.                             | Horizon validates the caller, checks server and capability access, then forwards accepted requests.                |
| Disabled               | The MCP client sends whatever the server code expects, or no credential if the server is public. | Horizon forwards without validating a Horizon bearer credential; the server owns authentication and authorization. |

Horizon authentication is enabled by default for shared and production hosted
servers. When a client supports interactive sign-in, the user completes a Horizon
authorization flow and the client receives a Horizon credential for that hosted
endpoint. Non-interactive clients can send a Horizon API key as a bearer token.

Disabling Horizon authentication is for endpoints that are intentionally public
or for servers whose code implements the full authentication and authorization
model. It is available on {openAuthenticationPlans}, and the change applies after
a new deployment uses the updated setting.

A protected hosted server can optionally use
[delegated authorization](/platform/external-authentication). You link one OAuth
or API-key auth source from **Access** and **Authentication**. For an eligible
user request, Horizon exchanges the identified actor for the saved downstream
credential and injects it into the configured request header before hosted code
runs. This lets code that already expects the upstream credential in that
header call the provider without implementing an OAuth callback or token store.

Delegated authorization is optional. Without a linked auth source, your Python
code chooses how to authenticate upstream calls, such as with deployment
environment variables or an authorization flow implemented by the server.

## What changes when

Builds, deployments, gateway metadata, and client manifests update on different
timelines. When a change appears stale, check which boundary owns it.

| Change                                                        | When clients see it                                                                            |
| ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| Source code, dependency, entrypoint, or Python version change | After a new build succeeds and that artifact is selected by a deployment.                      |
| Environment variable change                                   | After a new build and deployment selection for hosted runtime behavior.                        |
| Authentication mode change                                    | After a new deployment uses the updated server setting.                                        |
| Server explicit grant or default role change                  | After Horizon updates live access metadata; no code change is required.                        |
| Capability policy change                                      | After the policy is saved and the hosted server is redeployed with updated policy metadata.    |
| Live deployment promotion or rollback                         | As soon as the deployment selects the new artifact, subject to client-side caching.            |
| Client manifest refresh                                       | After the client reconnects or lists capabilities again. Some clients cache tools and prompts. |

## Manifest and discovery

Horizon inspects the hosted server during build and stores the discovered MCP
manifest for the artifact. The dashboard, remix composition, and capability
policy setup use the manifest from the relevant build or deployment. Playground
and Chat connect to the selected target and use its live capabilities.

A deployment serves one selected artifact at a time. A new tool, resource, or
prompt is not visible to clients until the code that registers it is built and
the resulting artifact is selected by the deployment the client is using.

Register capabilities during import or startup instead of after a request-time
side effect. If a tool is registered only after a handler runs, Horizon may not
see it during build inspection. If registration depends on environment
variables, preview and production builds can intentionally produce different
manifests.

## Troubleshooting

<AccordionGroup>
  <Accordion title="The build fails before an artifact exists">
    Check your build logs for dependency installation, entrypoint loading,
    import-time, or inspection errors. A failed build does not replace the live
    artifact.
  </Accordion>

  <Accordion title="A build succeeded, but live traffic did not change">
    Check [Deployments](/deployments). The successful artifact may belong to a
    preview deployment, may not have been promoted, or may have been superseded
    by another selected artifact.
  </Accordion>

  <Accordion title="A protected request returns 401 or 403">
    The request stopped before Python code ran. Check
    [Authentication](/platform/authentication),
    [Authorization](/platform/authorization), server access, capability policy,
    and request logs.
  </Accordion>

  <Accordion title="A request reaches the server and then fails">
    Gateway routing succeeded. Check your server logs, handler code, upstream
    calls, and any application errors written to stdout or stderr.
  </Accordion>

  <Accordion title="A request times out">
    The handler or startup path exceeded the {requestTimeout}-second request
    window. Move long work out of the request path, reduce startup work, or
    return earlier and continue work asynchronously.
  </Accordion>

  <Accordion title="A file or in-memory value disappears">
    The server used ephemeral local state as durable state. Store durable
    application state outside the local filesystem.
  </Accordion>

  <Accordion title="A tool is missing in the client">
    Confirm the selected target serves the build that contains the tool. Then
    refresh Playground or reconnect clients that cache tools and prompts.
  </Accordion>
</AccordionGroup>

## Before clients use the server

Before sharing a hosted endpoint, check the parts of the contract clients will
depend on:

* The live deployment selects the intended successful build artifact.
* Playground can list capabilities and call representative tools through the
  Horizon endpoint.
* Authentication matches the audience: Horizon authentication enabled for shared
  servers, disabled only when server code owns authentication.
* Server access and capability policies cover sensitive actions.
* Environment variables are scoped correctly for production and previews.
* Request logs and server logs make it clear whether failures stop at the
  gateway or inside Python code.

## Related docs

<CardGroup cols={2}>
  <Card title="Builds" icon="hammer" href="/builds">
    Understand build inputs, states, artifacts, and manifest inspection.
  </Card>

  <Card title="Deployments" icon="cloud-arrow-up" href="/deployments">
    Serve successful artifacts as live or preview deployments.
  </Card>

  <Card title="Compute model" icon="server" href="/platform/compute-model">
    Review request timeouts, memory, startup, sessions, and ephemeral state.
  </Card>

  <Card title="Environment variables" icon="lock" href="/environment-variables">
    Configure production and preview environment variables.
  </Card>

  <Card title="Authentication" icon="key" href="/platform/authentication">
    Learn how clients and API keys authenticate to hosted endpoints.
  </Card>

  <Card title="Connect a client" icon="plug" href="/connect-a-client">
    Configure an MCP client for a Horizon deployment URL.
  </Card>
</CardGroup>
