Documentation
¶
Index ¶
- Constants
- Variables
- func ContextWithResponseDeadlineEnforcement(ctx context.Context) context.Context
- func FindHeaderValue(headers http.Header, target string) *string
- func IsAuthRequiredProbeError(err error) bool
- func IsStartupWaitTimeoutError(err error) bool
- func IsTimeoutProbeError(err error) bool
- func NewInitializeRestartingSharedConnectionTransport(base mcp.Transport) mcp.Transport
- func NewProbeHTTPStatusError(statusCode int, cause error) error
- func NewProbeTimeoutError(timeout time.Duration, cause error) error
- func NewSharedConnectionTransport(base mcp.Transport) mcp.Transport
- func NewStartupWaitTimeoutError(timeout time.Duration, cause error) error
- func SessionIDFromHeaders(headers http.Header) *string
- type ChannelStdioRuntimeInfoProvider
- type ChannelTransportFactory
- type ForwardingConnection
- type ForwardingTransport
- func NewForwardingTransport(base mcp.Transport) ForwardingTransport
- func NewSerializedForwardingTransport(base ForwardingTransport) ForwardingTransport
- func NewSerializedForwardingTransportWithDeadlineRetirement(base ForwardingTransport) ForwardingTransport
- func NewStdioForwardingTransport(base ForwardingTransport) ForwardingTransport
- type ForwardingWriteResult
- type NonProtocolResponseError
- type NonProtocolResponseKind
- type PreservedMCPError
- type ProbeHTTPStatusError
- type ProbeState
- type ProbeTimeoutError
- type ResponseDeadlineRetiringConnection
- type SessionTerminatingTransport
- type StartupWaitTimeoutError
- type StdioRuntimeInfo
- type StdioRuntimeInfoProvider
- type TransportBuildParams
- type TransportProvider
Constants ¶
const ( HeaderSessionID = "Mcp-Session-Id" HeaderLastEventID = "Last-Event-ID" HeaderProtocolVersion = "Mcp-Protocol-Version" )
Variables ¶
var Module = fx.Module( "mcpclient", fx.Provide( NewProbeState, newMcpClient, newStdioCommandTransportFactoryProvider, newChannelStdioRuntimeInfoProvider, newChannelTransportFactory, fx.Annotate(newStreamableTransportProvider, fx.ResultTags(`group:"mcp_transport_providers"`)), fx.Annotate(newInjectableTransportProvider, fx.ResultTags(`group:"mcp_transport_providers"`)), fx.Annotate(newStdioTransportProvider, fx.ResultTags(`group:"mcp_transport_providers"`)), ), fx.Invoke(probeMcpServer), )
Functions ¶
func ContextWithResponseDeadlineEnforcement ¶ added in v0.0.11
ContextWithResponseDeadlineEnforcement marks MCP work whose full lifecycle is bounded by a tunnel command response deadline. Legacy commands without response_timeout intentionally remain unmarked.
func FindHeaderValue ¶
FindHeaderValue returns the value of a header in case-insensitive fashion. Nil is returned when the header is absent or the map is empty.
func IsAuthRequiredProbeError ¶
IsAuthRequiredProbeError reports whether a probe error indicates that the target MCP server is reachable but requires OAuth or other request authentication before initialize succeeds.
func IsStartupWaitTimeoutError ¶ added in v0.0.12
IsStartupWaitTimeoutError reports whether err was produced by an exhausted opt-in MCP listener startup wait.
func IsTimeoutProbeError ¶
func NewInitializeRestartingSharedConnectionTransport ¶ added in v0.0.13
NewInitializeRestartingSharedConnectionTransport returns a shared transport that starts a fresh underlying connection whenever a later logical request sends initialize.
Tunnel-service's legacy Harpoon client opens a new MCP client session for each OAuth shim call, while tunnel-client serializes those calls over one in-memory transport. go-sdk v1.7 rejects a second initialize on an already initialized server session, so Harpoon uses this narrow compatibility wrapper to preserve the old initialize/initialized flow without changing self-contained 2026 requests.
Callers must serialize logical request lifecycles while using this wrapper; Harpoon satisfies that requirement with its serialized forwarding transport.
func NewProbeHTTPStatusError ¶ added in v0.0.11
NewProbeHTTPStatusError attaches the observed HTTP status to a failed startup probe. It returns cause unchanged when no response status exists.
func NewSharedConnectionTransport ¶
NewSharedConnectionTransport returns a transport wrapper that reuses the same underlying connection across Connect calls.
func NewStartupWaitTimeoutError ¶ added in v0.0.12
NewStartupWaitTimeoutError constructs the non-ready error recorded when the opt-in MCP listener wait exhausts its configured budget.
func SessionIDFromHeaders ¶
SessionIDFromHeaders searches the provided headers map for the MCP session identifier and returns it when present.
Types ¶
type ChannelStdioRuntimeInfoProvider ¶
type ChannelStdioRuntimeInfoProvider interface {
StdioRuntimeInfo(channel types.Channel) (StdioRuntimeInfo, bool)
}
ChannelStdioRuntimeInfoProvider exposes stdio process details per channel.
type ChannelTransportFactory ¶
type ChannelTransportFactory struct {
// contains filtered or unexported fields
}
ChannelTransportFactory builds and caches MCP transports for configured channel bindings.
A connector request can arrive on any logical tunnel-service channel. The dispatcher asks this factory for the binding-specific transport, and the factory keeps one cached transport/HTTP client per channel so session headers, proxy selection, mTLS config, and raw-HTTP logging remain stable across requests for that channel.
func (*ChannelTransportFactory) Build ¶
func (f *ChannelTransportFactory) Build(binding runtimeconfig.MCPChannelBinding) (mcp.Transport, error)
Build returns a cached transport for the requested binding. Concurrent first use of the same channel is collapsed with singleflight so duplicate connector traffic cannot race into multiple stdio child processes or independent HTTP transport wrappers.
func (*ChannelTransportFactory) HTTPClientForBinding ¶
func (f *ChannelTransportFactory) HTTPClientForBinding(binding runtimeconfig.MCPChannelBinding) (*http.Client, error)
HTTPClientForBinding returns the HTTP client used for streamable MCP transports for a binding.
type ForwardingConnection ¶
type ForwardingConnection interface {
// Write writes a new message to the connection.
//
// Write may be called concurrently, as calls or responses may occur
// concurrently in user code.
//
// It returns the downstream HTTP result together with an error (if any)
// encountered while writing or processing the response. A recognized MCP
// error returned with a non-success HTTP status is carried in
// PreservedError and is not returned as a transport error.
Write(context.Context, http.Header, jsonrpc.Message) (ForwardingWriteResult, error)
Read(ctx context.Context) (jsonrpc.Message, error)
// Close closes the connection. It is implicitly called for non-context
// Read or Write failures. Shared deadline-retiring connections may preserve
// their physical transport when one request context expires.
//
// Close may be called multiple times, potentially concurrently.
Close() error
}
ForwardingConnection extends mcp.Connection with helpers that return the response headers collected from the underlying HTTP transport.
type ForwardingTransport ¶
type ForwardingTransport interface {
Connect(ctx context.Context) (ForwardingConnection, error)
}
ForwardingTransport decorates an mcp.Transport so callers can attach per-request headers and capture the response headers returned by the MCP server.
func NewForwardingTransport ¶
func NewForwardingTransport(base mcp.Transport) ForwardingTransport
NewForwardingTransport wraps the provided transport with header-forwarding capabilities.
func NewSerializedForwardingTransport ¶
func NewSerializedForwardingTransport(base ForwardingTransport) ForwardingTransport
NewSerializedForwardingTransport wraps a ForwardingTransport so only one request lifecycle is active on the shared underlying connection at a time.
Some MCP transports multiplex poorly when several connector calls write to the same long-lived connection and then each reader waits for its own response. The wrapper holds a lifecycle slot from Connect through any streamed notifications until the matching final JSON-RPC response, an error, or Close. Notifications without ids release immediately after the write because no response is legal.
func NewSerializedForwardingTransportWithDeadlineRetirement ¶ added in v0.0.12
func NewSerializedForwardingTransportWithDeadlineRetirement(base ForwardingTransport) ForwardingTransport
NewSerializedForwardingTransportWithDeadlineRetirement wraps a shared transport whose physical connection must survive one request deadline.
A deadline-retired request releases the lifecycle slot after recording its response ID. Later readers discard that retired response before it can be mistaken for a newer request. While any retired response remains outstanding, server requests and notifications are dropped because the JSON-RPC wire format does not identify which in-flight request owns them.
Stdio uses this because all logical connections share one child-process stdin/stdout pair. Closing those pipes for one deadline would poison every later request. Admitting the next request after retirement keeps terminal responses flowing even when the timed-out server work never replies.
func NewStdioForwardingTransport ¶ added in v0.0.13
func NewStdioForwardingTransport(base ForwardingTransport) ForwardingTransport
NewStdioForwardingTransport opts a shared stdio transport into the serialization and deadline-retirement behavior it needs, plus a compatibility shim for callers that omit MCP's initialized notification. After a successful initialize response, the wrapper writes notifications/initialized before it releases the lifecycle slot. If the caller later forwards the same notification, the wrapper acknowledges it without writing a duplicate to the stdio server. Callers must choose this wrapper explicitly so legacy stdio servers keep verbatim forwarding by default.
type ForwardingWriteResult ¶ added in v0.0.11
type ForwardingWriteResult struct {
StatusCode int
ResponseHeaders http.Header
PreservedError *PreservedMCPError
}
ForwardingWriteResult is the downstream HTTP result observed while writing an MCP message.
type NonProtocolResponseError ¶ added in v0.0.11
type NonProtocolResponseError struct {
// contains filtered or unexported fields
}
NonProtocolResponseError is handed to the separate fallback-classification path when a downstream response is not a valid, preservable MCP error.
func (*NonProtocolResponseError) Error ¶ added in v0.0.11
func (e *NonProtocolResponseError) Error() string
func (*NonProtocolResponseError) Kind ¶ added in v0.0.11
func (e *NonProtocolResponseError) Kind() NonProtocolResponseKind
Kind returns a bounded reason suitable for classification and tests.
func (*NonProtocolResponseError) Unwrap ¶ added in v0.0.11
func (e *NonProtocolResponseError) Unwrap() error
type NonProtocolResponseKind ¶ added in v0.0.11
type NonProtocolResponseKind string
NonProtocolResponseKind identifies why a downstream non-success response could not be preserved as an MCP JSON-RPC error.
const ( NonProtocolResponseBodyMissing NonProtocolResponseKind = "response_body_missing" NonProtocolResponseBodyUnreadable NonProtocolResponseKind = "response_body_unreadable" NonProtocolResponseBodyTooLarge NonProtocolResponseKind = "response_body_too_large" NonProtocolResponseMalformedJSON NonProtocolResponseKind = "malformed_json" NonProtocolResponseInvalidMCPError NonProtocolResponseKind = "invalid_mcp_error" )
type PreservedMCPError ¶ added in v0.0.11
type PreservedMCPError struct {
// contains filtered or unexported fields
}
PreservedMCPError is a recognized target-owned JSON-RPC error response. Its payload stays opaque so exact code, message, data, and future fields survive the tunnel unchanged.
func NewPreservedMCPError ¶ added in v0.0.11
func NewPreservedMCPError(payload []byte, code int64) *PreservedMCPError
NewPreservedMCPError constructs an opaque preserved response. Normal runtime callers receive these only after forwardingConnection validates the target JSON-RPC response; the constructor also supports alternate ForwardingConnection implementations and focused dispatcher tests.
func (*PreservedMCPError) Code ¶ added in v0.0.11
func (e *PreservedMCPError) Code() int64
Code returns the bounded JSON-RPC error code for safe diagnostics.
func (*PreservedMCPError) Payload ¶ added in v0.0.11
func (e *PreservedMCPError) Payload() []byte
Payload returns a defensive copy of the exact target JSON-RPC payload.
type ProbeHTTPStatusError ¶ added in v0.0.11
ProbeHTTPStatusError preserves the HTTP response status observed while the startup probe failed, without relying on the SDK's formatted error text.
func (*ProbeHTTPStatusError) Error ¶ added in v0.0.11
func (e *ProbeHTTPStatusError) Error() string
func (*ProbeHTTPStatusError) Unwrap ¶ added in v0.0.11
func (e *ProbeHTTPStatusError) Unwrap() error
type ProbeState ¶
type ProbeState struct {
// contains filtered or unexported fields
}
ProbeState tracks the result of the one-time startup probe against the main MCP channel.
func (*ProbeState) IsDone ¶
func (p *ProbeState) IsDone() bool
IsDone reports whether the probe has completed.
func (*ProbeState) Set ¶
func (p *ProbeState) Set(err error)
Set records the probe result and signals waiters.
func (*ProbeState) WaitUntilDone ¶
func (p *ProbeState) WaitUntilDone(ctx context.Context) error
WaitUntilDone blocks until the startup probe records a result or ctx is canceled.
type ProbeTimeoutError ¶
ProbeTimeoutError reports that the startup probe did not complete before the deadline.
func (*ProbeTimeoutError) Error ¶
func (e *ProbeTimeoutError) Error() string
func (*ProbeTimeoutError) Unwrap ¶
func (e *ProbeTimeoutError) Unwrap() error
type ResponseDeadlineRetiringConnection ¶ added in v0.0.12
type ResponseDeadlineRetiringConnection interface {
RetireResponseDeadline() bool
}
ResponseDeadlineRetiringConnection can retire one timed-out request lifecycle without closing a shared physical transport. Implementations must discard any later response for the retired request before another request can observe it.
RetireResponseDeadline is idempotent. Callers should use it only after a response deadline or equivalent per-request forwarding window expires. It returns true when the logical request was retired without closing the physical transport; false means the caller should keep its normal close path.
type SessionTerminatingTransport ¶
type SessionTerminatingTransport interface {
TerminateSession(ctx context.Context, headers http.Header) (int, http.Header, error)
}
SessionTerminatingTransport can explicitly close an MCP Streamable HTTP session and report the upstream HTTP response returned by the MCP server.
type StartupWaitTimeoutError ¶ added in v0.0.12
StartupWaitTimeoutError reports that the opt-in listener startup wait exhausted its budget while the target continued returning a retryable pre-connect failure. It deliberately remains distinct from ProbeTimeoutError: the legacy probe timeout is readiness-compatible, while exhausting the operator-requested listener gate must keep readiness failed.
func (*StartupWaitTimeoutError) Error ¶ added in v0.0.12
func (e *StartupWaitTimeoutError) Error() string
func (*StartupWaitTimeoutError) Unwrap ¶ added in v0.0.12
func (e *StartupWaitTimeoutError) Unwrap() error
type StdioRuntimeInfo ¶
type StdioRuntimeInfo struct {
PID int `json:"pid,omitempty"`
Command string `json:"command,omitempty"`
}
StdioRuntimeInfo describes the active stdio MCP process details.
type StdioRuntimeInfoProvider ¶
type StdioRuntimeInfoProvider interface {
StdioRuntimeInfo() StdioRuntimeInfo
}
StdioRuntimeInfoProvider exposes runtime details for stdio transport.
type TransportBuildParams ¶
type TransportBuildParams struct {
Config *runtimeconfig.MCPConfig
Binding runtimeconfig.MCPChannelBinding
HTTPClient *http.Client
}
TransportBuildParams carries shared dependencies for transport construction.
type TransportProvider ¶
type TransportProvider interface {
Kind() runtimeconfig.MCPTransportKind
Build(TransportBuildParams) (mcp.Transport, error)
}
TransportProvider constructs an MCP transport for a specific transport kind.