diff --git a/.github/workflows/test-sdk-packages.yml b/.github/workflows/test-sdk-packages.yml
index 72628a2a..c529facd 100644
--- a/.github/workflows/test-sdk-packages.yml
+++ b/.github/workflows/test-sdk-packages.yml
@@ -55,3 +55,15 @@ jobs:
       sdkName: 'eppo/ruby-sdk'
       sdkRelayDir: 'ruby-sdk-relay'
     secrets: inherit
+
+  test-go-sdk:
+    strategy:
+      fail-fast: false
+      matrix:
+        platform: ['linux']
+    uses: ./.github/workflows/test-server-sdk.yml
+    with:
+      platform: ${{ matrix.platform }}
+      sdkName: 'go-sdk'
+      sdkRelayDir: 'go-sdk-relay'
+    secrets: inherit
diff --git a/package-testing/go-sdk-relay/.gitignore b/package-testing/go-sdk-relay/.gitignore
new file mode 100644
index 00000000..51a41ee3
--- /dev/null
+++ b/package-testing/go-sdk-relay/.gitignore
@@ -0,0 +1,2 @@
+.env
+bin/
diff --git a/package-testing/go-sdk-relay/Dockerfile b/package-testing/go-sdk-relay/Dockerfile
new file mode 100644
index 00000000..42bf96b3
--- /dev/null
+++ b/package-testing/go-sdk-relay/Dockerfile
@@ -0,0 +1,18 @@
+FROM golang:1.23
+
+WORKDIR /app
+
+# Copy go mod and sum files
+COPY . .
+
+# Download all dependencies
+RUN go mod download
+
+# Copy the source code
+COPY . .
+
+# Build the application
+RUN go build -o main .
+
+# Run the application
+CMD ["./main"]
diff --git a/package-testing/go-sdk-relay/README.md b/package-testing/go-sdk-relay/README.md
new file mode 100644
index 00000000..f1571962
--- /dev/null
+++ b/package-testing/go-sdk-relay/README.md
@@ -0,0 +1,29 @@
+# Go Testing Server
+
+Post test case files to this server and check the results against what's expected.
+
+## Running locally with Docker
+
+Build the docker image:
+
+```shell
+docker build -t Eppo-exp/go-sdk-relay .
+```
+
+Run the docker container:
+
+```shell
+./docker-run.sh
+```
+
+## Development
+
+1. Install dependencies:
+```shell
+go mod download
+```
+
+2. Run the server:
+```shell
+go run main.go
+```
diff --git a/package-testing/go-sdk-relay/docker-run.sh b/package-testing/go-sdk-relay/docker-run.sh
new file mode 100755
index 00000000..163b7a1c
--- /dev/null
+++ b/package-testing/go-sdk-relay/docker-run.sh
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+
+# Default is to use the latest build
+VERSION="${1:-latest}"
+
+echo "Starting deployment with version: $VERSION"
+
+if [ -e .env ]; then
+  echo "Loading environment variables from .env file"
+  source .env
+fi
+
+echo "Stopping existing container..."
+docker stop go-relay
+echo "Removing existing container..."
+docker remove go-relay
+
+echo "Building new image..."
+docker build . -t Eppo-exp/go-sdk-relay:$VERSION
+
+echo "Starting new container..."
+docker run -p $SDK_RELAY_PORT:$SDK_RELAY_PORT \
+  --add-host host.docker.internal:host-gateway \
+  -e SDK_REF \
+  -e EPPO_BASE_URL \
+  -e SDK_RELAY_PORT \
+  --name go-relay \
+  --rm \
+  -t Eppo-exp/go-sdk-relay:$VERSION 
diff --git a/package-testing/go-sdk-relay/go.mod b/package-testing/go-sdk-relay/go.mod
new file mode 100644
index 00000000..324fe2f0
--- /dev/null
+++ b/package-testing/go-sdk-relay/go.mod
@@ -0,0 +1,12 @@
+module github.com/eppo/go-sdk-relay
+
+go 1.23.1
+
+require github.com/Eppo-exp/golang-sdk/v6 v6.1.0
+
+require (
+	github.com/Masterminds/semver/v3 v3.2.1 // indirect
+	github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
+	go.uber.org/multierr v1.11.0 // indirect
+	go.uber.org/zap v1.27.0 // indirect
+)
diff --git a/package-testing/go-sdk-relay/go.sum b/package-testing/go-sdk-relay/go.sum
new file mode 100644
index 00000000..954c4ec5
--- /dev/null
+++ b/package-testing/go-sdk-relay/go.sum
@@ -0,0 +1,10 @@
+github.com/Eppo-exp/golang-sdk/v6 v6.1.0 h1:a9nEXYnc/r4cNRMeV8CHc1c/VXbcXS5KiFPDpsTDTH8=
+github.com/Eppo-exp/golang-sdk/v6 v6.1.0/go.mod h1:UZ385Go97q/BmPG4wsnaSGbdQE4LAiIo25oQVbJrm20=
+github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0=
+github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
+github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
+github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
+go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
+go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
+go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
+go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
diff --git a/package-testing/go-sdk-relay/main.go b/package-testing/go-sdk-relay/main.go
new file mode 100644
index 00000000..9f116caf
--- /dev/null
+++ b/package-testing/go-sdk-relay/main.go
@@ -0,0 +1,234 @@
+package main
+
+import (
+	"encoding/json"
+	"fmt"
+	"log"
+	"net/http"
+	"os"
+	"strconv"
+	"time"
+
+	"github.com/Eppo-exp/golang-sdk/v6/eppoclient"
+)
+
+type AssignmentRequest struct {
+	Flag              string                 `json:"flag"`
+	SubjectKey        string                 `json:"subjectKey"`
+	SubjectAttributes map[string]interface{} `json:"subjectAttributes"`
+	AssignmentType    string                 `json:"assignmentType"`
+	DefaultValue      interface{}            `json:"defaultValue"`
+}
+
+type AssignmentResponse struct {
+	Result        interface{} `json:"result"`
+	AssignmentLog []string    `json:"assignmentLog"`
+	BanditLog     []string    `json:"banditLog"`
+	Error         *string     `json:"error"`
+}
+
+type SDKDetails struct {
+	SDKName               string `json:"sdkName"`
+	SDKVersion            string `json:"sdkVersion"`
+	SupportsBandits       bool   `json:"supportsBandits"`
+	SupportsDynamicTyping bool   `json:"supportsDynamicTyping"`
+}
+
+var eppoClient *eppoclient.EppoClient
+
+func initializeClient() error {
+	apiKey := os.Getenv("EPPO_API_KEY")
+	if apiKey == "" {
+		apiKey = "NOKEYSPECIFIED"
+	}
+
+	baseURL := os.Getenv("EPPO_BASE_URL")
+	if baseURL == "" {
+		baseURL = "http://localhost:5000/api"
+	}
+
+	// Create configuration
+	config := eppoclient.Config{
+		SdkKey:  apiKey,
+		BaseUrl: baseURL,
+	}
+
+	// Initialize client
+	client, err := eppoclient.InitClient(config)
+	if err != nil {
+		return fmt.Errorf("failed to create client: %v", err)
+	}
+
+	// Wait for initialization with timeout
+	initChan := make(chan struct{})
+	go func() {
+		<-client.Initialized()
+		close(initChan)
+	}()
+
+	select {
+	case <-initChan:
+		log.Printf("Eppo client initialized successfully")
+	case <-time.After(5 * time.Second):
+		log.Printf("Warning: Timed out waiting for Eppo SDK to initialize")
+	}
+
+	eppoClient = client
+	return nil
+}
+
+func handleHealthCheck(w http.ResponseWriter, r *http.Request) {
+	fmt.Fprint(w, "OK")
+}
+
+func handleSDKDetails(w http.ResponseWriter, r *http.Request) {
+	details := SDKDetails{
+		SDKName:               "go-sdk",
+		SDKVersion:            "6.1.0",
+		SupportsBandits:       false,
+		SupportsDynamicTyping: false,
+	}
+	json.NewEncoder(w).Encode(details)
+}
+
+func handleReset(w http.ResponseWriter, r *http.Request) {
+	err := initializeClient()
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+	fmt.Fprint(w, "Reset complete")
+}
+
+func handleAssignment(w http.ResponseWriter, r *http.Request) {
+	var req AssignmentRequest
+	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
+		http.Error(w, err.Error(), http.StatusBadRequest)
+		return
+	}
+
+	// Always prepare a response with default values
+	response := AssignmentResponse{
+		Result:        nil,
+		AssignmentLog: []string{},
+		BanditLog:     []string{},
+	}
+
+	if eppoClient == nil {
+		errStr := "client not initialized"
+		response.Error = &errStr
+		w.Header().Set("Content-Type", "application/json")
+		json.NewEncoder(w).Encode(response)
+		return
+	}
+
+	var err error
+	defer func() {
+		if r := recover(); r != nil {
+			errStr := fmt.Sprintf("panic recovered: %v", r)
+			response.Error = &errStr
+			response.Result = req.DefaultValue
+			w.Header().Set("Content-Type", "application/json")
+			json.NewEncoder(w).Encode(response)
+		}
+	}()
+
+	switch req.AssignmentType {
+	case "BOOLEAN":
+		defaultVal := false
+		if v, ok := req.DefaultValue.(bool); ok {
+			defaultVal = v
+		} else if v, ok := req.DefaultValue.(float64); ok {
+			defaultVal = v != 0
+		}
+		result, _ := eppoClient.GetBoolAssignment(req.Flag, req.SubjectKey, req.SubjectAttributes, defaultVal)
+		response.Result = result
+
+	case "STRING":
+		defaultVal := ""
+		if v, ok := req.DefaultValue.(string); ok {
+			defaultVal = v
+		}
+		result, _ := eppoClient.GetStringAssignment(req.Flag, req.SubjectKey, req.SubjectAttributes, defaultVal)
+		response.Result = result
+
+	case "NUMERIC":
+		defaultVal := 0.0
+		switch v := req.DefaultValue.(type) {
+		case float64:
+			defaultVal = v
+		case int:
+			defaultVal = float64(v)
+		case string:
+			defaultVal, _ = strconv.ParseFloat(v, 64)
+		}
+		result, _ := eppoClient.GetNumericAssignment(req.Flag, req.SubjectKey, req.SubjectAttributes, defaultVal)
+		response.Result = result
+
+	case "INTEGER":
+		defaultVal := int64(0)
+		switch v := req.DefaultValue.(type) {
+		case float64:
+			defaultVal = int64(v)
+		case int:
+			defaultVal = int64(v)
+		case int64:
+			defaultVal = v
+		}
+		result, _ := eppoClient.GetIntegerAssignment(req.Flag, req.SubjectKey, req.SubjectAttributes, defaultVal)
+		response.Result = float64(result)
+
+	case "JSON":
+		result, _ := eppoClient.GetJSONAssignment(req.Flag, req.SubjectKey, req.SubjectAttributes, req.DefaultValue)
+		response.Result = result
+
+	default:
+		errStr := fmt.Sprintf("unsupported assignment type: %s", req.AssignmentType)
+		response.Error = &errStr
+	}
+
+	if err != nil {
+		errStr := err.Error()
+		response.Error = &errStr
+	}
+
+	w.Header().Set("Content-Type", "application/json")
+	json.NewEncoder(w).Encode(response)
+}
+
+func handleBanditAction(w http.ResponseWriter, r *http.Request) {
+	// TODO: Implement bandit logic
+	response := AssignmentResponse{
+		Result:        "action",
+		AssignmentLog: []string{},
+		BanditLog:     []string{},
+	}
+	w.Header().Set("Content-Type", "application/json")
+	json.NewEncoder(w).Encode(response)
+}
+
+func main() {
+	if err := initializeClient(); err != nil {
+		log.Fatalf("Failed to initialize client: %v", err)
+	}
+
+	http.HandleFunc("/", handleHealthCheck)
+	http.HandleFunc("/sdk/details", handleSDKDetails)
+	http.HandleFunc("/sdk/reset", handleReset)
+	http.HandleFunc("/flags/v1/assignment", handleAssignment)
+	http.HandleFunc("/bandits/v1/action", handleBanditAction)
+
+	port := os.Getenv("SDK_RELAY_PORT")
+	if port == "" {
+		port = "7001"
+	}
+
+	host := os.Getenv("SDK_RELAY_HOST")
+	if host == "" {
+		host = "0.0.0.0"
+	}
+
+	addr := fmt.Sprintf("%s:%s", host, port)
+	log.Printf("Starting server on %s", addr)
+	log.Fatal(http.ListenAndServe(addr, nil))
+}