diff --git a/mcp/sse.go b/mcp/sse.go
index e57dad1..1dd640a 100644
--- a/mcp/sse.go
+++ b/mcp/sse.go
@@ -10,11 +10,13 @@ import (
 	"crypto/rand"
 	"fmt"
 	"io"
+	"net"
 	"net/http"
 	"net/url"
 	"sync"
 
 	"github.com/modelcontextprotocol/go-sdk/internal/jsonrpc2"
+	"github.com/modelcontextprotocol/go-sdk/internal/util"
 	"github.com/modelcontextprotocol/go-sdk/jsonrpc"
 )
 
@@ -52,9 +54,14 @@ type SSEHandler struct {
 }
 
 // SSEOptions specifies options for an [SSEHandler].
-// for now, it is empty, but may be extended in future.
-// https://github.com/modelcontextprotocol/go-sdk/issues/507
-type SSEOptions struct{}
+type SSEOptions struct {
+	// DisableLocalhostProtection disables automatic DNS rebinding protection.
+	// By default, requests arriving via a localhost address (127.0.0.1, [::1])
+	// that have a non-localhost Host header are rejected with 403 Forbidden.
+	//
+	// Only disable this if you understand the security implications.
+	DisableLocalhostProtection bool
+}
 
 // NewSSEHandler returns a new [SSEHandler] that creates and manages MCP
 // sessions created via incoming HTTP requests.
@@ -179,6 +186,16 @@ func (t *SSEServerTransport) Connect(context.Context) (Connection, error) {
 }
 
 func (h *SSEHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
+	// DNS rebinding protection: auto-enabled for localhost servers.
+	if !h.opts.DisableLocalhostProtection && disablelocalhostprotection != "1" {
+		if localAddr, ok := req.Context().Value(http.LocalAddrContextKey).(net.Addr); ok && localAddr != nil {
+			if util.IsLoopback(localAddr.String()) && !util.IsLoopback(req.Host) {
+				http.Error(w, fmt.Sprintf("Forbidden: invalid Host header %q", req.Host), http.StatusForbidden)
+				return
+			}
+		}
+	}
+
 	sessionID := req.URL.Query().Get("sessionid")
 
 	// TODO: consider checking Content-Type here. For now, we are lax.
diff --git a/mcp/sse_test.go b/mcp/sse_test.go
index 8746cc8..6162b97 100644
--- a/mcp/sse_test.go
+++ b/mcp/sse_test.go
@@ -9,6 +9,7 @@ import (
 	"context"
 	"fmt"
 	"io"
+	"net"
 	"net/http"
 	"net/http/httptest"
 	"sync/atomic"
@@ -221,3 +222,92 @@ func TestSSE405AllowHeader(t *testing.T) {
 		})
 	}
 }
+
+func TestSSELocalhostProtection(t *testing.T) {
+	server := NewServer(testImpl, nil)
+
+	tests := []struct {
+		name              string
+		method            string
+		listenAddr        string
+		hostHeader        string
+		disableProtection bool
+		wantStatus        int
+	}{
+		{
+			name:              "GET 127.0.0.1 accepts localhost",
+			method:            http.MethodGet,
+			listenAddr:        "127.0.0.1:0",
+			hostHeader:        "localhost:1234",
+			disableProtection: false,
+			wantStatus:        http.StatusOK,
+		},
+		{
+			name:              "POST 127.0.0.1 accepts localhost",
+			method:            http.MethodPost,
+			listenAddr:        "127.0.0.1:0",
+			hostHeader:        "localhost:1234",
+			disableProtection: false,
+			wantStatus:        http.StatusBadRequest,
+		},
+		{
+			name:              "POST 127.0.0.1 rejects evil.com",
+			method:            http.MethodPost,
+			listenAddr:        "127.0.0.1:0",
+			hostHeader:        "evil.com",
+			disableProtection: false,
+			wantStatus:        http.StatusForbidden,
+		},
+		{
+			name:              "POST 0.0.0.0 via localhost rejects evil.com",
+			method:            http.MethodPost,
+			listenAddr:        "0.0.0.0:0",
+			hostHeader:        "evil.com",
+			disableProtection: false,
+			wantStatus:        http.StatusForbidden,
+		},
+		{
+			name:              "POST disable protection accepts evil.com",
+			method:            http.MethodPost,
+			listenAddr:        "127.0.0.1:0",
+			hostHeader:        "evil.com",
+			disableProtection: true,
+			wantStatus:        http.StatusBadRequest,
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			handler := NewSSEHandler(
+				func(req *http.Request) *Server { return server },
+				&SSEOptions{DisableLocalhostProtection: tt.disableProtection},
+			)
+
+			listener, err := net.Listen("tcp", tt.listenAddr)
+			if err != nil {
+				t.Fatalf("Failed to listen on %s: %v", tt.listenAddr, err)
+			}
+			defer listener.Close()
+
+			srv := &http.Server{Handler: handler}
+			go srv.Serve(listener)
+			defer srv.Close()
+
+			req, err := http.NewRequest(tt.method, fmt.Sprintf("http://%s", listener.Addr().String()), bytes.NewReader(nil))
+			if err != nil {
+				t.Fatal(err)
+			}
+			req.Host = tt.hostHeader
+
+			resp, err := http.DefaultClient.Do(req)
+			if err != nil {
+				t.Fatal(err)
+			}
+			defer resp.Body.Close()
+
+			if got := resp.StatusCode; got != tt.wantStatus {
+				t.Errorf("Status code: got %d, want %d", got, tt.wantStatus)
+			}
+		})
+	}
+}
