diff --git a/pkg/mcp/transport_http.go b/pkg/mcp/transport_http.go index cd25417..8577060 100644 --- a/pkg/mcp/transport_http.go +++ b/pkg/mcp/transport_http.go @@ -82,12 +82,11 @@ func (s *Service) ServeHTTP(ctx context.Context, addr string) error { } // withAuth wraps an http.Handler with Bearer token authentication. -// If token is empty, requests are rejected. +// If token is empty, authentication is disabled for local development. func withAuth(token string, next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if strings.TrimSpace(token) == "" { - w.Header().Set("WWW-Authenticate", `Bearer`) - http.Error(w, `{"error":"authentication not configured"}`, http.StatusUnauthorized) + next.ServeHTTP(w, r) return } diff --git a/pkg/mcp/transport_http_test.go b/pkg/mcp/transport_http_test.go index ec8dc10..eeb91fa 100644 --- a/pkg/mcp/transport_http_test.go +++ b/pkg/mcp/transport_http_test.go @@ -107,6 +107,44 @@ func TestServeHTTP_Good_AuthRequired(t *testing.T) { <-errCh } +func TestServeHTTP_Good_NoAuthConfigured(t *testing.T) { + os.Unsetenv("MCP_AUTH_TOKEN") + + s, err := New(Options{}) + if err != nil { + t.Fatalf("Failed to create service: %v", err) + } + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + listener, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + t.Fatalf("Failed to find free port: %v", err) + } + addr := listener.Addr().String() + listener.Close() + + errCh := make(chan error, 1) + go func() { + errCh <- s.ServeHTTP(ctx, addr) + }() + + time.Sleep(100 * time.Millisecond) + + resp, err := http.Get(fmt.Sprintf("http://%s/mcp", addr)) + if err != nil { + t.Fatalf("request failed: %v", err) + } + resp.Body.Close() + if resp.StatusCode == 401 { + t.Fatalf("expected /mcp to be open without MCP_AUTH_TOKEN, got %d", resp.StatusCode) + } + + cancel() + <-errCh +} + func TestWithAuth_Good_ValidToken(t *testing.T) { handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) @@ -157,19 +195,18 @@ func TestWithAuth_Bad_MissingToken(t *testing.T) { } } -func TestWithAuth_Bad_EmptyConfiguredToken(t *testing.T) { +func TestWithAuth_Good_EmptyConfiguredToken_DisablesAuth(t *testing.T) { handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) }) - // Empty token now requires explicit configuration wrapped := withAuth("", handler) req, _ := http.NewRequest("GET", "/", nil) rr := &fakeResponseWriter{code: 200} wrapped.ServeHTTP(rr, req) - if rr.code != 401 { - t.Errorf("expected 401 with empty configured token, got %d", rr.code) + if rr.code != 200 { + t.Errorf("expected 200 with empty configured token, got %d", rr.code) } }