Shared HTTP Server
One HTTP server on port 9090 fronts every connector — its middleware chain, the enable model, and reserved channel prefixes.
Three built-in gateways run on one shared HTTP server inside kubemq-server: CloudEvents (documented here under Connectors) plus the AI gateways A2A and MCP (documented under Aiway). There is no separate port or process per gateway: they register their routes on the same server, pass through the same middleware chain, and inherit the same auth, CORS, and TLS configuration.
One server, many connectors
When kubemq-server starts, each enabled connector registers its routes on the shared
HTTP server, and the server is started once. Requests to /a2a/*, /mcp, and /ce/*
all land on the same listener and flow through the same middleware pipeline before
reaching the connector that owns the route.
A request passes through the middleware chain in order before reaching a connector route.
Port 9090
The shared HTTP server listens on port 9090. The port is configured by
Connectors.Http.Port; if it is left unset, it inherits from Rest.Port (which
defaults to 9090). A warning is logged if both are set to different values.
Connector metrics are exposed separately on port 8080 (/metrics), alongside the
internal dashboard API. See Observability for the
metrics surface and the AI dashboard.
Health and readiness probes are public and unauthenticated:
curl http://localhost:9090/ping
curl http://localhost:9090/health
curl http://localhost:9090/readyThe middleware chain
Every request flows through the same middleware stack, applied outermost-first:
| Order | Middleware | Purpose |
|---|---|---|
| 1 | Recovery | Catches panics so one bad request cannot crash the server. |
| 2 | Traffic Gate | Rejects requests with HTTP 503 while the broker is not ready. |
| 3 | OTel Tracing | OpenTelemetry instrumentation (kubemq-http), when telemetry is enabled. |
| 4 | CORS | Configurable cross-origin policy via HttpConfig.Cors. |
| 5 | Auth | Extracts a JWT Bearer token and sets claims; anonymous claims when auth is off. |
| 6 | Body Limit | Caps request body size (default 100M). |
| 7 | Logging | Debug-level request start/end logging. |
The traffic gate is wired to the broker's readiness: the server automatically
starts accepting traffic when the broker becomes ready and rejects it (with 503)
when it is not. This is why a connector can be enabled yet briefly return 503 during
startup.
Auth and TLS/mTLS are shared across all connectors and documented once in Auth & security.
SSE and request timeouts
The server's WriteTimeout is set to 0 so long-lived Server-Sent Events streams
(A2A message/stream, CloudEvents SSE subscriptions) stay open indefinitely. Non-SSE
route groups instead apply a per-route TimeoutMiddleware — default 60 seconds,
returning HTTP 504 Gateway Timeout if the deadline is exceeded before the response is
committed.
For requests that proxy to a downstream agent, a GatewayTimeoutBuffer of 10
seconds is added on top of the caller-specified timeout, so the gateway does not time
out before the agent it is waiting on.
Enable model: on by default
All three gateways are enabled by default. Start kubemq-server and /a2a/*,
/mcp, and /ce/* are live — there is no flag to turn them on. (The A2A and MCP
gateways are documented under Aiway; their enable vars are listed here
because they share this server's enable model.) To turn one off, set its enable env var
to false:
| Connector | Disable with |
|---|---|
| A2A | CONNECTORSA2_A_ENABLE=false |
| MCP | CONNECTORSMCP_ENABLE=false |
| CloudEvents | CONNECTORSCE_ENABLE=false |
For example, to run with MCP disabled:
docker run -d -p 50000:50000 -e KUBEMQ_TOKEN=YOUR_LICENSE_KEY -e CONNECTORSMCP_ENABLE=false europe-docker.pkg.dev/kubemq/images/kubemq:nextThe enable var names are irregular by design. Environment variables are derived
from the dotted config keys (Connectors.A2A.Enable, Connectors.MCP.Enable,
Connectors.CE.Enable) by a snake-casing transform that splits on letter-case
boundaries, strips dots, and uppercases. The boundaries fall in unexpected places — so
A2A becomes CONNECTORSA2_A_ENABLE (the 2→A boundary inserts an underscore), while
MCP and CE join into CONNECTORSMCP_ENABLE and CONNECTORSCE_ENABLE with no
underscore before the connector name. Use these exact names; never invent a
=true flag to enable a connector, and note that CONNECTORS_CE_ENABLE (with an
underscore) does not work — the live binding is CONNECTORSCE_ENABLE.
This differs from older KubeMQ behavior, where these gateways were off by default and opted in. That framing is stale: today they ship on.
Reserved channel prefix
The shared server reserves the _AGENTS_. channel prefix for internal agent
platform subjects (agent request/reply, SSE stream relays, and registry replication).
Any user operation targeting a channel that begins with _AGENTS_. is rejected by
IsReservedChannel. Pick channel names outside this prefix for your own queues,
events, commands, and queries.
Related
Auth & security
JWT Bearer auth, CORS, origin validation, and TLS/mTLS for every connector.
Observability
Prometheus metrics on port 8080, OTel tracing, and the AI dashboard.
Connectors overview
What connectors are and how the gateways fit together.
Aiway
The AI Agents Fabric — where the A2A and MCP gateways are documented.
Was this page helpful?
Observability
Prometheus metrics, OpenTelemetry tracing, and the AI dashboard shared by KubeMQ's HTTP gateways — CloudEvents, plus A2A and MCP (documented under Aiway).
Migration
Pick the right KubeMQ wire-protocol connector for your broker and migrate onto it — the connector map, a cross-protocol matrix, and guides for nine ecosystems.