Documentation
¶
Overview ¶
Package proxy runs an MCP stdio proxy for SigV4-protected AWS MCP servers.
The public entry point is Run. Callers provide a Config describing the upstream MCP endpoint and optional RunOptions for embedding concerns such as logging, custom MCP transports, a shared HTTP client, or a replacement upstream connector for tests.
A minimal embedded proxy run looks like:
err := proxy.Run(ctx, proxy.Config{
Endpoint: new("https://service.us-east-1.api.aws/mcp"),
Region: new("us-east-1"),
Service: new("service"),
}, proxy.RunOptions{
Logger: logger,
})
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Run ¶
func Run(ctx context.Context, cfg Config, options RunOptions) error
Run starts the proxy and blocks until the MCP server transport exits or the context is canceled.
Example ¶
ExampleRun demonstrates embedding the complete proxy with a custom MCP transport and upstream connector. Production embedders can omit both to use the standard stdio and SigV4 Streamable HTTP paths.
package main
import (
"context"
"fmt"
"github.com/ajbeck/go-aws-mcp-proxy/proxy"
"github.com/modelcontextprotocol/go-sdk/mcp"
)
func main() {
serverTransport, clientTransport := mcp.NewInMemoryTransports()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
endpoint := "https://example.invalid/mcp"
errs := make(chan error, 1)
go func() {
errs <- proxy.Run(ctx, proxy.Config{Endpoint: &endpoint}, proxy.RunOptions{
Connector: exampleConnector{},
Transport: serverTransport,
Version: "example",
})
}()
client := mcp.NewClient(&mcp.Implementation{Name: "embedded-client", Version: "1.0.0"}, nil)
session, err := client.Connect(ctx, clientTransport, nil)
if err != nil {
panic(err)
}
result, err := session.CallTool(ctx, &mcp.CallToolParams{Name: "hello"})
if err != nil {
panic(err)
}
fmt.Println(result.Content[0].(*mcp.TextContent).Text)
if err := session.Close(); err != nil {
panic(err)
}
if err := <-errs; err != nil {
panic(err)
}
}
type exampleConnector struct{}
func (exampleConnector) Connect(context.Context, proxy.Config, *mcp.InitializeParams) (proxy.UpstreamSession, error) {
return exampleSession{}, nil
}
type exampleSession struct{}
func (exampleSession) CallTool(context.Context, *mcp.CallToolParams) (*mcp.CallToolResult, error) {
return &mcp.CallToolResult{Content: []mcp.Content{&mcp.TextContent{Text: "hello from embedded upstream"}}}, nil
}
func (exampleSession) Close() error { return nil }
func (exampleSession) InitializeResult() *mcp.InitializeResult {
return &mcp.InitializeResult{Capabilities: &mcp.ServerCapabilities{Tools: &mcp.ToolCapabilities{}}}
}
func (exampleSession) ListTools(context.Context, *mcp.ListToolsParams) (*mcp.ListToolsResult, error) {
return &mcp.ListToolsResult{Tools: []*mcp.Tool{{
Name: "hello",
Description: "Return a greeting from the embedded upstream.",
InputSchema: map[string]any{"type": "object"},
}}}, nil
}
Output: hello from embedded upstream
Types ¶
type Config ¶
type Config struct {
Endpoint *string
Service *string
Profiles *[]string
Region *string
CaBundle *string
Metadata *map[string]string
AllowEmptyTools *bool
LazyConnect *bool
ReadOnly *bool
LogLevel *string
Retries *int
Timeout *time.Duration
ConnectTimeout *time.Duration
ReadTimeout *time.Duration
WriteTimeout *time.Duration
ToolTimeout *time.Duration
DisableTelemetry *bool
SkipAuth *bool
OptionalAuth *bool
}
Config describes a proxy run.
type DiagnoseOptions ¶ added in v1.0.0
type DiagnoseOptions struct {
// HTTPClient is used for STS identity checks and the optional MCP probe.
HTTPClient *http.Client
// Logger receives diagnostic transport logs.
Logger *slog.Logger
// Probe requests an MCP initialize and tools/list check against the endpoint.
Probe bool
// ProbeConnector replaces the default Streamable HTTP connector.
ProbeConnector UpstreamConnector
// Version is reported to the upstream MCP server during a probe.
Version string
// contains filtered or unexported fields
}
DiagnoseOptions configures the optional online MCP probe and test seams.
type DiagnosticCategory ¶ added in v1.0.0
type DiagnosticCategory string
DiagnosticCategory identifies the subsystem checked by doctor.
const ( DiagnosticConfiguration DiagnosticCategory = "configuration" DiagnosticCredentials DiagnosticCategory = "credentials" DiagnosticIdentity DiagnosticCategory = "identity" DiagnosticNetwork DiagnosticCategory = "network" DiagnosticUpstream DiagnosticCategory = "upstream_mcp" )
Diagnostic categories are stable values used to select the CLI exit code.
type DiagnosticCheck ¶ added in v1.0.0
type DiagnosticCheck struct {
Name *string `json:"name,omitempty"`
Status *DiagnosticStatus `json:"status,omitempty"`
Category *DiagnosticCategory `json:"category,omitempty"`
Profile *string `json:"profile,omitempty"`
Message *string `json:"message,omitempty"`
Remediation *string `json:"remediation,omitempty"`
Detail *string `json:"technical_detail,omitempty"`
Source *string `json:"credential_source,omitempty"`
ExpiresAt *time.Time `json:"expires_at,omitempty"`
Account *string `json:"account,omitempty"`
ARN *string `json:"arn,omitempty"`
UserID *string `json:"user_id,omitempty"`
ToolCount *int `json:"tool_count,omitempty"`
}
DiagnosticCheck represents one redacted doctor check result.
type DiagnosticReport ¶ added in v1.0.0
type DiagnosticReport struct {
Healthy *bool `json:"healthy,omitempty"`
Endpoint *string `json:"endpoint,omitempty"`
ProbeRequested *bool `json:"probe_requested,omitempty"`
Checks []DiagnosticCheck `json:"checks"`
}
DiagnosticReport contains the ordered results of a doctor run.
func Diagnose ¶ added in v1.0.0
func Diagnose(ctx context.Context, cfg Config, options DiagnoseOptions) DiagnosticReport
Diagnose validates proxy configuration and AWS identity without modifying credentials or AWS configuration. It contacts the configured MCP endpoint only when DiagnoseOptions.Probe is true.
Example ¶
ExampleDiagnose demonstrates an offline configuration preflight. Omit SkipAuth for signed endpoints, and set DiagnoseOptions.Probe to contact the configured MCP endpoint after credentials and identity checks pass.
package main
import (
"context"
"fmt"
"github.com/ajbeck/go-aws-mcp-proxy/proxy"
)
func main() {
report := proxy.Diagnose(context.Background(), proxy.Config{
Endpoint: new("https://aws-mcp.us-east-1.api.aws/mcp"),
SkipAuth: new(true),
}, proxy.DiagnoseOptions{})
fmt.Println(*report.Healthy)
for _, check := range report.Checks {
fmt.Printf("%s: %s\n", *check.Name, *check.Status)
}
}
Output: true configuration: pass credentials: skip identity: skip mcp_probe: skip
func (DiagnosticReport) Validate ¶ added in v1.0.0
func (r DiagnosticReport) Validate() error
Validate reports whether all required report fields are populated.
type DiagnosticStatus ¶ added in v1.0.0
type DiagnosticStatus string
DiagnosticStatus describes the outcome of one doctor check.
const ( DiagnosticPass DiagnosticStatus = "pass" DiagnosticWarning DiagnosticStatus = "warning" DiagnosticFail DiagnosticStatus = "fail" DiagnosticSkip DiagnosticStatus = "skip" )
Diagnostic statuses are stable values in the JSON doctor report.
type RunOptions ¶
type RunOptions struct {
// Connector replaces the default Streamable HTTP upstream connector.
Connector UpstreamConnector
// HTTPClient is used by the default upstream connector.
HTTPClient *http.Client
// Logger receives proxy and request logs.
Logger *slog.Logger
// Transport is the MCP server transport. It defaults to stdio.
Transport mcp.Transport
// Version is reported in MCP implementation metadata and user-agent data.
Version string
// contains filtered or unexported fields
}
RunOptions configures embedding and test seams for Run.
type UpstreamConnector ¶
type UpstreamConnector interface {
Connect(context.Context, Config, *mcp.InitializeParams) (UpstreamSession, error)
}
UpstreamConnector opens an MCP client session to the configured upstream.
type UpstreamSession ¶
type UpstreamSession interface {
CallTool(context.Context, *mcp.CallToolParams) (*mcp.CallToolResult, error)
Close() error
InitializeResult() *mcp.InitializeResult
ListTools(context.Context, *mcp.ListToolsParams) (*mcp.ListToolsResult, error)
}
UpstreamSession is the upstream MCP session behavior used by the proxy.