Starport is a self-hosted LLM inference gateway in one binary. It serves the
OpenAI-compatible API at /v1 and the OpenRouter-compatible API at /api/v1.
One Starmap catalog generation gives it every provider, model, capability,
context, and price fact. The 2026-08-29 generation lists 17 providers and
routes 511 models.
The embedded console above shows the gateway overview, the model catalog with prices, one model across two providers, and provider health with incident history.
Starport adds less than 50 ms p99 gateway overhead per request. The overhead
benchmark measures 0 ms p50 and p99 over 200 requests against a mock upstream.
Every response reports its own number in the x-starport-overhead-ms header.
A CI benchmark fails the build when the bound breaks. See
docs/PERFORMANCE.md for the methodology and exclusions.
Starport serves individual developers, startups, and enterprises:
- An individual developer runs one command and gets an isolated gateway, a console, and one temporary gateway API key.
- A startup keeps its OpenAI and OpenRouter clients and changes one base URL.
- An enterprise adds shared provider inference credentials, BYOK policy, budgets, rate limits, encrypted credential storage, and secret references.
Install the released cask on macOS or Linux:
brew install agentstation/tap/starport
starport --versionThe current public release also contains checksummed archives for macOS, Linux, and Windows. Download an archive from GitHub Releases.
To build from source, install the Go version from go.mod, then run:
git clone https://github.com/agentstation/starport.git
cd starport
make build
./starport --versionStarport checks every provider in the active catalog generation. It registers
each provider whose transport and authentication primitive it supports. It
discovers deployment-owned provider inference credentials from the ordered
profiles in that catalog. You do not select a provider with starport init or
a provider-specific flag.
Two kinds of credential appear below and they are not interchangeable. A gateway API key authenticates a client to Starport and carries its scopes and limits. A provider credential pays a provider. A gateway API key never pays a provider, and a provider credential never authenticates a client.
Set one conventional provider credential. This example uses OpenAI:
export OPENAI_API_KEY="replace-with-provider-inference-key"
starport devThe command starts an isolated gateway at http://127.0.0.1:8080. It uses
in-memory state, creates no configuration files, prints one temporary Starport
gateway API key, and opens the console in a browser:
Starport development gateway
URL: http://127.0.0.1:8080
Authentication: required
Gateway API key (shown once): replace-with-generated-gateway-key
Console (one-time launch link): http://127.0.0.1:8080/launch?lt=replace-with-ticket
The console link is not a key. The gateway spends the link on first use and
exchanges it for a browser session that this machine issued. You paste nothing
into the browser, and the browser stores no key. Add --no-open to print the
link instead, which fits a machine you reach over SSH. starport ui opens a
new link at any time.
A browser without a link must present this machine's local admin token.
starport auth token --copy puts the token on the clipboard of the gateway
machine. Both paths prove presence at that machine and end in the same console
session.
Keep this terminal open.
Copy the printed gateway key into a second terminal. This key authenticates the client to Starport. It is not the provider inference key.
export STARPORT_API_KEY="replace-with-generated-gateway-key"Readiness is independent of provider credentials. A ready response means that the gateway can accept requests. The authenticated model response contains the current Starmap catalog view.
curl --fail http://127.0.0.1:8080/health/ready
curl --fail-with-body \
-H "Authorization: Bearer $STARPORT_API_KEY" \
http://127.0.0.1:8080/api/v1/modelsSend an OpenRouter-style chat request:
curl --fail-with-body \
-H "Authorization: Bearer $STARPORT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"openrouter/auto","messages":[{"role":"user","content":"Hello"}]}' \
http://127.0.0.1:8080/api/v1/chat/completionsThe first provider request proves whether the provider accepts the resolved credential and whether the account can use the selected offering. Starport records authentication, permission, quota, billing, rate-limit, and service failures in its scoped provider state.
Starport requires a gateway API key by default. Add --no-auth to
starport dev or starport serve to serve open. Open service fits a
workstation, a private container, or a test rig. The console offers the same
switch under Settings. You can close an open gateway again from the machine
that runs it.
Starport refuses --no-auth on an address the network can reach unless you
also pass --allow-remote-no-auth. See
Authentication mode.
For persistent local or production state, run starport init once. The command
creates a Starport master key and initial gateway identity. It does not select a
provider or persist provider inference credentials. Then use starport serve,
and starport ui to open the console. Issue further gateway API keys in the
console under Keys.
See the operator guide.
Local Ollama inference needs no credential. Add each installed model to a
reviewed Starmap workspace, and set STARPORT_CATALOG_WORKSPACE_PATH before
startup.
Use a Starport gateway key for client authentication.
| Client contract | Base URL |
|---|---|
| OpenAI | http://127.0.0.1:8080/v1 |
| OpenRouter | http://127.0.0.1:8080/api/v1 |
OpenAI Python example:
import os
from openai import OpenAI
client = OpenAI(
base_url="http://127.0.0.1:8080/v1",
api_key=os.environ["STARPORT_API_KEY"],
)
response = client.chat.completions.create(
model="openai/gpt-4o-mini",
messages=[{"role": "user", "content": "Hello"}],
)For an OpenRouter client, replace its default base URL with
http://127.0.0.1:8080/api/v1. Keep the client request and response types.
Version 1 includes:
- Chat completions, streaming chat, embeddings, and model discovery.
- The Responses API at
/v1/responseson the same chat contract. - Moderations at
/v1/moderationsand gateway-executed batches at/v1/batches. - Exact provider and model routing with fallback and
openrouter/auto. - Provider routing preferences: order, sort, price caps, and model variants.
- Presets with
@preset/model references, immutable revisions, and rollback. - Catalog-driven providers over the compiled OpenAI, Anthropic, Google Cloud, Google AI Studio, and Ollama transport primitives.
- Encrypted provider credentials, renewable cloud credentials, and direct secret-source references.
- Header-only gateway authentication, per-key rate limits, per-key budgets, and allowed-model limits.
- Team budgets, refused before the provider call.
- Guardrails that redact or refuse, detect payment cards under Luhn, and fail closed.
- Request logs and usage accounting with catalog-priced costs at
/api/v1/activity. - Prometheus metrics at
/metrics, optional OTLP trace export, and NDJSON usage export. - An admin audit log. Every admin mutation writes an actor-attributed record, and the console renders the log.
- Signed webhooks for budget, job, and provider-health transitions.
- An agent surface: the catalog verbs answer offline with
--json, andstarport agent setupinstalls the embedded skill. - An embedded web console. Its pages cover the overview, chat with model comparison, models, providers with incident history, usage, presets, keys, files, and settings.
- A file store at
/v1/filesthat keeps a document for a later chat request. It writes to a local filesystem or an S3-compatible bucket. - A
file-parserplugin that reads an attached document before the chat model sees it. Thenativeengine reads a text layer in process and charges nothing. Therecognitionengine sends a scanned page to a catalog model that servesdocuments-recognition, and the record reports what the pages cost. - Reranking at
/v1/rerankand/api/v1/rerank, which scores a document list against one query. It needs thererank:writescope, and Starmap owns the offerings, the billing basis, and the price. - Account-safe response caching, with an opt-in semantic cache beside the exact identity.
- Badger storage for one process and Valkey storage for multiple processes.
Starport uses direct changes and has no legacy provider aliases or storage readers. It does not yet promise a compatibility window.
Starport reads config.env from the platform user configuration directory.
Process environment variables override the file. starport config paths
prints the resolved paths.
Set STARPORT_CONFIG_DIR to an absolute path for an isolated development or
CI instance. This value changes the configuration, data, and rate-limit paths
together.
starport config show prints the effective schema and hides secret values.
starport doctor runs passive checks. Add --probe for read-only storage and
identity checks.
Provider IDs, credential fields, conventional environment names, defaults,
authentication profiles, and endpoints come from the active Starmap catalog.
For example, Starport checks OPENAI_API_KEY before
STARPORT_OPENAI_API_KEY. A provider that uses an already compiled transport
and authentication primitive needs no Starport provider switch.
Starport resolves all catalog providers at startup and, by default, reconciles
them every minute. Set STARPORT_CREDENTIAL_SOURCES_RECONCILE_INTERVAL to
change that interval. An administrator can also trigger the same shared work:
curl --fail-with-body \
-X POST \
-H "Authorization: Bearer $STARPORT_API_KEY" \
http://127.0.0.1:8080/api/v1/admin/providers/refreshAnother process cannot change Starport's process environment. Restart Starport after you change an environment value. File and remote secret sources can return new material during interval or manual reconciliation.
Add _REFERENCE to the catalog-derived Starport name to select a direct secret
source. Starport supports Google Cloud Secret Manager, Azure Key Vault, AWS
Secrets Manager, HashiCorp Vault KV v2, and OpenBao KV v2. For example:
export STARPORT_OPENAI_API_KEY_REFERENCE='aws-secrets-manager:starport/openai#api-key'The operator guide defines the resource syntax, source authentication, version selection, and fallback rule.
To consume verified catalog publications from a Starmap server, set its versioned API base URL:
export STARPORT_CATALOG_REMOTE_URL="https://catalog.example.com/api/v1"
export STARPORT_CATALOG_REMOTE_API_KEY="replace-if-the-server-requires-one"Remote mode keeps the last accepted generation for restart and recovery. It is mutually exclusive with a local catalog workspace and local acquisition. See the remote catalog guide.
See the configuration reference and operator guide for production settings.
Vertex AI and Azure OpenAI can use renewable default cloud credentials. Their project, location, and endpoint fields use the conventional names declared by Starmap:
export GOOGLE_CLOUD_PROJECT="replace-with-project-id"
export GOOGLE_CLOUD_LOCATION="us-central1"
export AZURE_OPENAI_ENDPOINT="https://replace-with-resource.openai.azure.com"Vertex AI uses Google Application Default Credentials. Azure OpenAI uses
AZURE_OPENAI_API_KEY when present. Without it, Azure OpenAI uses
DefaultAzureCredential. Starport gets renewable bearer tokens before an
inference request uses them.
Starmap catalog-acquisition credentials remain separate from Starport inference credentials.
Pull a versioned image and verify its GitHub attestation:
STARPORT_VERSION="$(gh release view \
--repo agentstation/starport \
--json tagName \
--jq '.tagName | ltrimstr("v")')"
docker pull "ghcr.io/agentstation/starport:$STARPORT_VERSION"
gh attestation verify "oci://ghcr.io/agentstation/starport:$STARPORT_VERSION" \
--repo agentstation/starport \
--signer-workflow agentstation/starport/.github/workflows/release.yaml
docker run --rm "ghcr.io/agentstation/starport:$STARPORT_VERSION" --versionThe Compose file builds Starport locally and uses Valkey for shared state. Put
the master key and any catalog-declared provider values in the ignored .env
file. This example uses OpenAI:
cp .env.example .env
# Edit .env. Set STARPORT_SECURITY_MASTER_KEY and OPENAI_API_KEY.
docker compose up --build -d valkey
docker compose run --rm starport init --configured-storage --name primary-admin
docker compose up -d starportSave the gateway key from initialization. Do not initialize the same identity repository again.
make deps
make check
bash scripts/smoke-first-run.sh
bash scripts/smoke-openrouter-sdks.shmake check reads files but does not change them. Use make format or
make tidy when you want to change source or module files.
See the development guide and contribution guide.
- Architecture
- Operator guide
- Security posture
- Performance methodology
- Vertex AI configuration
- Model catalog contract
- Documentation index
Starport uses the GNU AGPLv3 license. See LICENSE.
Report vulnerabilities through the process in SECURITY.md. For credential handling, encryption, and data flows, read the security posture.
