Documentation
¶
Overview ¶
Package launcher manages locally-spawned upstream processes that expose their MCP endpoint over HTTP / SSE / streamable-HTTP transports.
Stdio upstreams already spawn a child process — that's how the protocol works. HTTP/SSE upstreams have historically required the user to start the process themselves before mcpproxy connected. The launcher decouples "how to start the process" from "how to talk to it", so the same {command, args, env, working_dir, docker isolation} configuration that stdio servers use can also drive an HTTP/SSE server's lifecycle.
This file owns URL-readiness probing. See launcher.go for spawn/stop.
Index ¶
Constants ¶
const DefaultStopGrace = 5 * time.Second
DefaultStopGrace is the time we wait between SIGTERM and SIGKILL when stopping a launched child. Tunable via Handle.SetStopGrace if a particular upstream needs longer (e.g. a Docker container with a slow shutdown hook). Five seconds is a common default for "graceful" in this codebase (see processGracefulTimeout in internal/upstream/core).
Variables ¶
This section is empty.
Functions ¶
func WaitForURL ¶
WaitForURL blocks until rawURL's host:port accepts a TCP connection, or until the context is canceled or timeout elapses (whichever comes first).
The check is deliberately a TCP dial, not an HTTP GET. SSE endpoints serve a streaming response that never closes; an HTTP GET against one will either hang or return a non-2xx status the moment the server's stream handler is hit, neither of which actually proves "the listener is up". TCP-dial just proves the bind happened, which is what we need before handing off to the transport-level connect.
timeout=0 means "use no overall deadline beyond ctx.Done()". Negative timeouts are coerced to 0 to keep callers from accidentally producing an already-expired deadline.
Types ¶
type Handle ¶
type Handle interface {
// Stop signals the child to exit (SIGTERM → grace → SIGKILL on
// timeout). Blocks until the child is reaped or ctx fires. Calling
// Stop more than once is safe — subsequent calls return the result
// of the first.
Stop(ctx context.Context) error
// Wait blocks until the child exits. Returns the exit error from
// exec.Cmd.Wait() (nil on clean exit, *exec.ExitError on non-zero).
Wait() error
// Done is closed when the child has exited for any reason. Useful
// for select{}-driven supervision.
Done() <-chan struct{}
// Pid returns the OS process id, or 0 if the child has exited.
Pid() int
}
Handle represents a running child managed by the launcher. Stop, Wait, and Done are safe to call from multiple goroutines.
func Spawn ¶
Spawn starts spec.Cmd and returns a Handle owning its lifecycle.
stdout+stderr are line-buffered into spec.LogSink (or discarded if nil). On Unix, the child is placed in its own process group so Stop can signal the entire group, not just the immediate child — this matters when the command shells out (e.g. `sh -c 'docker run …'`) and the actual server is a grandchild.
The supplied ctx is NOT used to bound the child's runtime — once Spawn returns, the child outlives ctx. ctx is only used to abort cmd.Start() itself if it's slow (rare). Callers who want ctx-tied lifetime should call Stop from a goroutine watching ctx.Done().
type Spec ¶
type Spec struct {
// Cmd is the command to start. The launcher will set Stdout/Stderr
// pipes and call cmd.Start(). Callers MUST NOT have started cmd
// already; calling Start again is undefined.
Cmd *exec.Cmd
// LogSink receives the child's combined stdout+stderr, line by line.
// May be nil to discard output (tests).
LogSink io.Writer
// Name is used in log messages to identify which upstream's launcher
// is doing the talking. Optional; defaults to cmd.Path basename.
Name string
// StopGrace overrides DefaultStopGrace if non-zero.
StopGrace time.Duration
}
Spec describes the command to launch.
Spec is intentionally narrow: it doesn't replicate the full ServerConfig surface — the caller is responsible for assembling the final exec.Cmd (env, working dir, Docker shell-wrap, process-group attrs). The launcher only owns the lifecycle once Cmd is started.