Skip to content

MCPServerEntry.spec.headerForward is accepted by CRD but never sent with requests by VirtualMCPServer #4996

Description

@lorr1

Summary

MCPServerEntry.spec.headerForward.addPlaintextHeaders (and addHeadersFromSecret) is defined in the CRD and accepted at admission, but the values are never actually sent on outbound requests to remoteUrl when the entry is consumed as a static backend of a VirtualMCPServer. Only MCPRemoteProxy currently wires this field through.

Reproducer

apiVersion: toolhive.stacklok.dev/v1beta1
kind: MCPServerEntry
metadata:
  name: github-copilot-projects
  namespace: stacklok-tunnel
spec:
  remoteUrl: https://api.githubcopilot.com/mcp/
  transport: streamable-http
  groupRef: { name: stacklok-group }
  externalAuthConfigRef: { name: github-oauth-upstream-inject }
  headerForward:
    addPlaintextHeaders:
      X-MCP-Toolsets: "projects,issues,pull_requests,users,context"

GitHub's remote MCP server uses X-MCP-Toolsets to combine multiple toolsets (the ?toolsets= query string is ignored and the URL path only accepts one toolset). Requests from the vMCP arrive at api.githubcopilot.com without this header, so only the default toolset's tools surface.

Evidence

HeaderForward is consumed only by MCPRemoteProxy:

  • cmd/thv-operator/controllers/mcpremoteproxy_runconfig.go
  • cmd/thv-operator/controllers/mcpremoteproxy_deployment.go
  • cmd/thv-operator/pkg/controllerutil/externalauth.go

For MCPServerEntry, the only reference is the type definition at cmd/thv-operator/api/v1beta1/mcpserverentry_types.go. No controller/runtime path feeds MCPServerEntry.spec.headerForward into the vMCP's outbound HTTP client for static backends.

Expected

When a VirtualMCPServer loads a backend from an MCPServerEntry, the runtime HTTP client used to reach remoteUrl should inject the addPlaintextHeaders and addHeadersFromSecret values on every outbound request (health checks, listTools, tool invocations).

Workaround

Use the URL path (/mcp/x/<toolset> or /mcp/x/all) since the GitHub upstream is path-addressable. Trades granularity for functionality.

Context

Discovered wiring github-copilot-projects behind the vMCP for the Stacklok Anthropic tunnel — see stacklok/infra#4485 and stacklok/infra branch fix/github-copilot-toolsets-header.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions