Skip to content

5.1. Gateway Setup

What are the prerequisites?

Complete Chapters 1-4, install Ollama, and run the offline gate:

mise run check
mise run test
ollama pull qwen3:4b
mise run doctor:model
mise run doctor:gateway

The host profile needs no Kubernetes cluster, cloud account, or provider key.

Before starting long-lived processes, run the deterministic smoke harness:

mise run smoke:host

It starts isolated fake-model, MCP, A2A, and gateway processes on temporary ports, verifies all four gateway surfaces plus CORS/readiness, and tears them down. It proves the host composition without spending model time; it does not inspect the manual Ollama stack you start next.

How do you start the host data plane?

Keep the application processes in separate terminals so their logs remain visible. If Ollama is not already managed as a service, run ollama serve first.

Start the MCP server:

cd agents/python
mise run mcp:http

Start the digest-pinned gateway image from the repository root:

mise run gateway:host

The wrapper publishes MCP :3000, A2A :3001, model :4000, metrics :15020, and readiness :15021 on 127.0.0.1. On native Linux it starts a bridge-address-only relay to the loopback MCP, A2A, and Ollama upstreams, plus the loopback-published gateway metrics endpoint that Compose Prometheus scrapes. This avoids a LAN-wide bind while preserving container-to-host access. For a detached process, use mise run gateway:host:start; inspect it with mise run gateway:host:status and mise run gateway:host:logs.

Bridge scope is a host-exposure boundary, not per-container authentication. Any trusted container on Docker's default bridge can reach the relayed ports, so do not run untrusted containers there during this lab. A multi-user or hostile-container environment needs a dedicated owned network and host firewall policy.

Start the A2A agent with both governed client routes:

cd agents/python
AGENT_MODEL_PROVIDER=openai-compatible \
AGENT_MODEL=qwen3:4b \
AGENT_MCP_URL=http://127.0.0.1:3000/mcp \
OPENAI_BASE_URL=http://127.0.0.1:4000/v1 \
OPENAI_API_KEY=local-ollama \
mise run a2a

Do not substitute the raw agentgateway -f ... binary in the quickstart: its host listeners bind all interfaces. The wrapper is the checked loopback boundary.

How do you verify the listeners?

curl -fsS http://127.0.0.1:3001/.well-known/agent-card.json | jq '{name,url}'
curl -fsS http://127.0.0.1:15020/metrics | head
curl -fsS http://127.0.0.1:15021/healthz/ready

The first response should name Ops Copilot and advertise the governed :3001 address; the second should return Prometheus text; the third should print ready. MCP and model listeners use protocol requests shown on the next pages, so a successful TCP connection alone is not their checkpoint.

How do you enable host observability?

Start the Compose stack before the gateway/agent when you want complete startup traces:

mise run observability:up

Add this to the agent process environment:

OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4318
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
OTEL_SERVICE_NAME=ops-copilot

The host agent exports traces when those variables are set. The host gateway always exposes metrics on :15020, which Compose Prometheus scrapes, but deliberately leaves OTLP export disabled so the optional collector can be stopped without retry noise. Kubernetes gateway profiles enable OTLP because their collector is deployed with them. MLflow is on 127.0.0.1:5000, Grafana on 127.0.0.1:3002, and Prometheus on 127.0.0.1:9090.

How do you stop the host profile?

Stop the foreground gateway, A2A, and MCP processes with Ctrl-C. Stop a detached gateway explicitly; the wrapper also removes its bridge relay:

mise run gateway:host:stop
mise run observability:down

The observability task preserves its MLflow, Prometheus, and Grafana volumes. Delete volumes only when the observability chapter explicitly asks you to reset them.

What is the setup checkpoint?

Keep the isolated mise run smoke:host result as the deterministic composition proof. On the manual Ollama stack, confirm the agent card only through :3001, list MCP tools through :3000, and make one model request through :4000. Do not bypass the gateway ports during the remaining chapter checks.