KubeMQ
ConnectorsConcepts

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/ready

The middleware chain

Every request flows through the same middleware stack, applied outermost-first:

OrderMiddlewarePurpose
1RecoveryCatches panics so one bad request cannot crash the server.
2Traffic GateRejects requests with HTTP 503 while the broker is not ready.
3OTel TracingOpenTelemetry instrumentation (kubemq-http), when telemetry is enabled.
4CORSConfigurable cross-origin policy via HttpConfig.Cors.
5AuthExtracts a JWT Bearer token and sets claims; anonymous claims when auth is off.
6Body LimitCaps request body size (default 100M).
7LoggingDebug-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:

ConnectorDisable with
A2ACONNECTORSA2_A_ENABLE=false
MCPCONNECTORSMCP_ENABLE=false
CloudEventsCONNECTORSCE_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:next

The 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 2A 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.

Was this page helpful?

On this page