Serve vMCP metrics on a separate diagnostics listener - #6368
Open
amirejaz wants to merge 1 commit into
Open
Conversation
amirejaz
requested review from
ChrisJBurns,
JAORMX,
blkt,
jerm-dro,
jhrozek,
rdimitrov,
reyortiz3 and
tgrunnagle
as code owners
August 19, 2026 02:00
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## metrics-transport-port-deprecation #6368 +/- ##
======================================================================
+ Coverage 72.99% 73.04% +0.04%
======================================================================
Files 744 745 +1
Lines 78623 78676 +53
======================================================================
+ Hits 57393 57471 +78
+ Misses 17230 17180 -50
- Partials 4000 4025 +25 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This was referenced Aug 19, 2026
Virtual MCP registered /metrics on the mux that serves MCP traffic, under a comment noting it was unauthenticated. That is the vMCP half of finding E in #6271; #6296 moved the proxy half. Bind it to the diagnostics listener, so access can be governed by port: NetworkPolicy matches on pods, ports, and protocols and cannot filter on HTTP path, so a shared port makes "allow MCP, deny scraping" unexpressible. This does not authenticate the endpoint; the diagnostics listener carries no middleware. Honour the same migration switch the proxy path uses, so this is not a breaking change on its own: while metricsOnTransportPort is on, /metrics stays reachable on the MCP port too, and a deprecation warning names it. That matters more here than for the proxy. Nothing shipped enables the metrics path for MCPServer, but three vMCP artifacts do -- examples/vmcp-config.yaml and two operator docs -- so more deployments plausibly have it on. Add Server.DiagnosticsAddress so the resolved port can be discovered programmatically. The listener falls back to an available port when the configured one is taken, so tests and callers cannot construct the address; the vMCP telemetry tests now scrape through it. Part of #6271 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
amirejaz
force-pushed
the
vmcp-diagnostics-listener
branch
from
August 19, 2026 03:37
6d45011 to
c8ff688
Compare
amirejaz
changed the base branch from
main
to
metrics-transport-port-deprecation
August 19, 2026 03:37
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Virtual MCP registers
/metricson the mux that serves MCP traffic — under a commentthat acknowledged it was unauthenticated. That's the vMCP half of Finding E in #6271;
#6296 moved the proxy half. Until both move, the endpoint still shares the port
deployments route publicly.
/metricson the dedicated diagnostics listener (pkg/diagnostics), so accesscan be governed by port.
NetworkPolicymatches on pods, ports, and protocols andcannot filter on HTTP path, so while
/metricsshares the MCP port there is no wayto express "allow MCP traffic, deny metrics scraping".
change on its own. While
metricsOnTransportPortis on (the default),/metricsstays reachable on the MCP port too and a deprecation warning names it. Once it is
off, the application mux 404s rather than letting
/metricsfall through to the/MCP handler.
Server.DiagnosticsAddress()so the resolved port is discoverable.What this does not do: it does not authenticate, rate limit, or audit
/metrics.The diagnostics listener carries no middleware, and the host is inherited from the MCP
listener (
0.0.0.0under the operator), so the endpoint stays reachable from otherpods. Restricting who can reach that port is what protects it — see the
NetworkPolicyexample in
docs/observability.md.Part of #6271
Type of change
Test plan
task test)task test-e2e)task lint-fix)New coverage in
pkg/vmcp/server/diagnostics_test.go: no listener without telemetry,metrics bound to a port distinct from the MCP port, configured port honoured, host
defaulting, idempotent stop.
TestServeHandlerRegistersMetricsWhenTelemetryEnabledisrenamed to
TestServeHandlerDoesNotServeMetricsand now asserts the 404, since its oldassertion described the behaviour this PR removes.
Three telemetry tests scraped
/metricsoff the MCP address and now go throughDiagnosticsAddress()— necessary rather than cosmetic, since the listener falls backto an available port when the configured one is taken, so the address cannot be
constructed.
Remaining local failures (
TestValidateOCIRegistryHost,TestParseGitReference_*) andlint findings (
cmd/thv/app/upgrade.go,pkg/vmcp/config/crd_cli_roundtrip_test.go)are pre-existing on
mainin files this PR does not touch.Does this introduce a user-facing change?
Not on merge.
/metricsbecomes available on the diagnostics port(
prometheusPort, default9464) while remaining on the MCP port, so existingscrape configurations keep working until the window closes.
When it does close, this is the half that matters more.
The blast radius is larger here than for the proxy half. Nothing shipped enables the
metrics path for MCPServer, but three vMCP artifacts do —
examples/vmcp-config.yaml,docs/operator/virtualmcpserver-api.md, anddocs/operator/virtualmcpserver-observability.md— so more deployments plausibly haveit on. The example and the observability guide are updated to point at the diagnostics
port.
This should ship in the same release as #6296 and #6370, so operators get one
migration event rather than the same feature moving twice. None of it has shipped —
v0.44.0was cut before #6296 merged.Special notes for reviewers
DiagnosticsAddress()is worth a look beyond vMCP: the resolved diagnostics portcurrently only appears in a startup log, which is why the E2E metrics helpers in #6296
hardcode
9464(Copilot flagged this, and those threads are still open). This accessoris the vMCP-side answer; the equivalent for the proxy path — surfacing it in workload
status — is still outstanding.
TestServeHandlerMetricsOnTransportPortpins both ends of the migration — default andexplicitly-on serve on the MCP port, opted-out 404s — so neither the window nor the
cutover can regress unnoticed.
Generated with Claude Code