Class McpMetricsExporter
- All Implemented Interfaces:
AutoCloseable
McpMetrics registry at /metrics for Prometheus to scrape.
MCP_METRICS_PORT |
Port to listen on. Unset means no listener — see below. |
MCP_METRICS_HOST |
Address to bind, default "127.0.0.1". |
MCP_METRICS_HOST_MANAGED |
Set by a supervising runtime that chose the bind address itself, inside a private network namespace. Suppresses the exposure warning only — see below. |
Why there is no default port
Generation-time PROMETHEUS_SERVER=YES emits this; the environment variable is what
starts it. The same split as MCP_HTTP_TOKEN, and here it is not merely tidy: the web
application launches up to twenty generated servers at once and the start-up harness forks
twenty-one per box. A default port would give one of them a listener and the other twenty a bind
failure to log, every run.
It uses the JDK's own HTTP server, and it is a separate port on purpose
com.sun.net.httpserver costs no dependency and works identically under both MCP
transports — a stdio server has no Jetty to hang a servlet on, and stdio is where a locally-run
server lives. A separate port also keeps the scrape off /mcp/*, whose bearer-token and
Origin filters exist to guard a surface that can write, and which a Prometheus scraper
would not satisfy anyway.
Exposure warns rather than refuses
Binding a non-loopback address logs a warning. It does not refuse the way
McpHttpPolicy refuses an unauthenticated MCP port: this endpoint is read-only and carries
no data from the database. It does publish the schema's object names and the shape of the
traffic, which is worth a line in the log and worth a network policy, but it is not the same
risk as an open call surface.
Why a container is allowed to bind every interface without being warned at
MCP_METRICS_HOST_MANAGED exists because the warning above is advice an operator
cannot act on when a supervising runtime placed this server inside a private network
namespace. Binding 0.0.0.0 there is not an exposure: nothing outside can reach the
namespace until the deployment publishes the port, and THAT is the deliberate act the warning
is really about. Telling twenty child servers' logs to "restrict it at the network" when the
namespace already does is how operators learn to scroll past warnings.
It suppresses only the warning, and only when the runtime supplied the address itself.
An operator who sets MCP_METRICS_HOST by hand is still told, because then the choice —
and the responsibility for a network policy — is genuinely theirs. Nothing here changes what is
bound, and the loopback default is untouched for the ordinary case of this class running as a
library in somebody's own JVM, where measuring a server must not be what puts it on a network.
A failure here must not take the server down
An unusable port is reported and the MCP server carries on. Metrics are an observability sideline, and refusing to serve tools because nothing could be told about them would be the wrong trade — unlike the fail-closed security guards, where refusing IS the protection. A port that will not parse is different and does throw: that is an operator typo, and silently ignoring it leaves someone believing they are collecting metrics when they are not. Copyright 2003-2026 ATB Consultancy Services Ltd (formerly Orinda Software Ltd, Dublin, Ireland)
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final StringPrometheus text exposition format, version 0.0.4.static final StringLoopback, so a server is not put on the network by the act of measuring it.static final StringSet by a supervising runtime that choseHOST_VARIABLEitself, inside a private network namespace.static final Stringstatic final StringThe scrape path.static final String -
Method Summary
Modifier and TypeMethodDescriptionvoidclose()intgetPort()The port actually bound — the point of the exercise when 0 was requested.static McpMetricsExporterstart(McpMetrics theMetrics, String theHost, int thePort) Start an exporter on a given address, bypassing the environment.static McpMetricsExporterstartIfConfigured(McpMetrics theMetrics, LogInterface theLog) Start the exporter ifPORT_VARIABLEnames a port, otherwise do nothing.
-
Field Details
-
PORT_VARIABLE
- See Also:
-
HOST_VARIABLE
- See Also:
-
HOST_MANAGED_VARIABLE
Set by a supervising runtime that choseHOST_VARIABLEitself, inside a private network namespace. Suppresses the exposure warning; binds nothing differently.- See Also:
-
DEFAULT_BIND_HOST
Loopback, so a server is not put on the network by the act of measuring it.- See Also:
-
METRICS_PATH
-
CONTENT_TYPE
-
-
Method Details
-
startIfConfigured
Start the exporter ifPORT_VARIABLEnames a port, otherwise do nothing.- Parameters:
theMetrics- the registry to servetheLog- where a bind failure or an exposure warning is reported; may be null- Returns:
- the running exporter, or null when no port was configured or the port could not be bound
- Throws:
IllegalArgumentException- if the port or host setting cannot be understood
-
start
public static McpMetricsExporter start(McpMetrics theMetrics, String theHost, int thePort) throws IOException Start an exporter on a given address, bypassing the environment.- Parameters:
thePort- the port, or 0 to let the operating system choose one- Throws:
IOException
-
getPort
public int getPort()The port actually bound — the point of the exercise when 0 was requested. -
close
public void close()- Specified by:
closein interfaceAutoCloseable
-