A Private MCP Port, Three Network Boundaries
Local tests trace a tool call through an outbound MCP tunnel and check where control-plane keys, connector tokens, and local headers can travel.
An outbound tunnel solves a network reachability problem: the MCP server can stay on a private address while a client inside that network polls for work. It does not make the tool call local. The request body and the reply still cross the remote tunnel service. Credentials need a more careful map, because this client handles a control-plane API key, a connector-supplied token, and optional static headers for the private server.
I read the tunnel client at commit 3502fcb8953230215c832197b1e4835fe47183da and ran its Go tests on Windows with Go 1.27.0. There is substantial code here: a control-plane poller, MCP dispatch, HTTP and in-memory transports, per-channel binding, redirect rules, and loopback tests. The architecture note describes the intended network path; the tests let me check parts of it without a hosted tunnel.
A Tool Call Through the Local Harness
The embedded-client test starts a mock control plane and an MCP server connected to the client through the MCP Go SDK's in-memory transport. Its queued command contains this JSON-RPC request:
{"jsonrpc":"2.0","id":"sdk-tool-call","method":"tools/call","params":{"name":"echo","arguments":{"message":"hello from sdk"}}}
The test's server returns an echo tool result. The mock control plane asserts an HTTP 200 response, response type jsonrpc, and result.structuredContent.message equal to Echo: hello from sdk. It also checks that three scripted responses arrive and that a stopped client cannot restart. This exercises the real client and MCP dispatch code against local fixtures. It does not contact the hosted service or an external MCP server.
I ran the focused tests with the Go module and build caches inside the research directory:
$env:GOMODCACHE = 'path\to\go-mod-cache'
$env:GOCACHE = 'path\to\go-build-cache'
$env:GOPATH = 'path\to\go-path'
go test -v . ./pkg/mcpclient -run 'TestNewValidatesRequiredInputs|TestClientForwardsMCPToolCallsOverInMemoryTransport|TestChannelTransportFactoryScopesStaticAuthorizationPerBinding|TestChannelTransportFactoryConnectorAuthorizationOverridesStaticHeader'
The terminal ended with PASS for both packages; the tool-call test took 0.11s. The configuration cases rejected an absent transport, tunnel ID, or API key, plus attempts to override reserved control-plane headers. Those are useful startup checks, but they do not establish end-to-end authorization at the hosted service.
Three Credentials, Three Paths
The SDK's configuration requires a tunnel ID and API key. That key authenticates its outbound poll and response traffic. The MCP HTTP transport separately handles credentials for the private server. The static-header wrapper only injects configured headers on the allowed MCP destination. Tests put two local servers on different origins and checked what each received.
| Artifact | Tested or configured path | Local observation |
|---|---|---|
| Tunnel API key | Client to control plane | Required at construction; reserved auth header cannot be replaced through extra headers |
Static MCP Authorization | Client to configured MCP origin | Server A received it; server B received an empty value from A's client |
Connector Authorization | Queued request to private MCP hop | It overrode the static header in the local HTTP test |
| MCP JSON-RPC body | Hosted queue, then private MCP hop | The local mock carried tools/call and checked its echo result |
The override matters for operators. A static backend token can stay on the last hop when it is the only credential source. If a connector supplies Authorization, the runtime forwards that value instead. The test also checked that a discovery-only header did not appear on a runtime request. A deployment should decide which source owns backend auth, rather than assuming the configured static token always wins.
Redirects Are Part of the Boundary
The client builds separate HTTP clients for discovery and runtime MCP traffic. Its runtime client copies the shared client and adds a CheckRedirect rule that validates the configured origin on every hop. A rejected redirect never gets another RoundTrip carrying the request body or token.
I ran these local server tests:
go test -v ./pkg/mcpclient -run 'TestChannelHTTPClientScopesForwardedHeadersAcrossRedirects|TestRuntimeMCPHTTPClientRejectsCrossOriginRedirects|TestRuntimeMCPHTTPClientAllowsSameOriginRedirect|TestRuntimeMCPHTTPClientRevalidatesEveryRedirectHop'
All four tests passed. The cross-origin test tried 301, 302, 303, 307, and 308 responses and asserted zero calls to the sink server. The same-origin 307 test kept the POST method, JSON body, and forwarded Authorization. A two-hop test accepted the first local redirect and rejected the next hop to another origin. The discovery-facing client has a narrower rule: a cross-origin redirect can proceed, but forwarded headers are stripped; that behavior also passed its local test.
This separation is an engineering choice with a clear limit. The origin guard keeps a runtime request from following a 3xx to a different host. It does not stop the configured MCP server itself from receiving a malicious tool call, and it does not keep tool arguments or connector tokens outside the hosted request path. The private port is a useful deployment property. Data handling, backend authorization, and redirect behavior remain separate review items.