> Canonical guide: https://developers.foxlight.ai/build/sdk/serving/
> Contract snapshots: Skulk 2.0.0 (b0af39c79b6b7102b2478062904f1d7cc8619975); SDK 0.4.0 (31bb090b8f64689f87514e48385e22b6ad94a6c2). Check the installed runtime when versions differ.

# Serving an application _interface_

A capability can supply its own UI or HTTP API. The host decides which addresses the child may serve. Protocols 3 and 4 place the chosen address in `Startup.serve_host`.

```python
from skulk_capability_sdk.serving import (
    advertised_host, bind_hosts, peer_allowed,
)

hosts = bind_hosts(startup)
public_host = advertised_host(startup)
# Bind each returned host separately.
# Check peer_allowed(remote_address) at your connection boundary.
```

## Bind and advertise

`bind_hosts()` returns loopback and, when supplied, the host-selected serving address. Bind them separately. Binding every interface would also expose the application on networks the host did not choose.

`advertised_host()` chooses the reachable host for the surface URL and brackets IPv6 addresses appropriately. Without a serving address, the interface is loopback-only and needs a browser on that host.

## Caller admission

`peer_allowed()` accepts loopback and the configured Tailscale address ranges, handles IPv4-mapped IPv6, and refuses malformed or other addresses. Tailscale’s own access policy decides which peers can reach the serving address. These helpers do not authenticate an application user or grant permission to mutate state; apply the host and application’s authorization contract too.

## Publish readiness

Declare a surface URL and readiness through the managed integration. Discovery alone does not make the URL reachable or the application healthy. Update readiness when the application cannot serve its declared workflow.

[Serving API reference](https://developers.foxlight.ai/build/sdk/reference/serving/)
