diff --git a/main.go b/main.go
index b1b5883..eaaf96e 100644
--- a/main.go
+++ b/main.go
@@ -10,12 +10,11 @@ import (
 	"os"
 	"os/exec"
 	"os/signal"
-	"os/user"
-	"path"
 	"strings"
 
 	"github.com/arduino/arduino-language-server/ls"
 	"github.com/arduino/arduino-language-server/streams"
+	"github.com/arduino/arduino-language-server/utils"
 	"github.com/arduino/go-paths-helper"
 	"github.com/mattn/go-isatty"
 )
@@ -101,8 +100,8 @@ func main() {
 		}
 	} else {
 		if *cliConfigPath == "" {
-			if user, _ := user.Current(); user != nil {
-				candidate := path.Join(user.HomeDir, ".arduino15/arduino-cli.yaml")
+			candidate := utils.GetDefaultCliConfigPath()
+			if candidate != "" {
 				if _, err := os.Stat(candidate); err == nil {
 					*cliConfigPath = candidate
 					log.Printf("ArduinoCLI config file found at %s\n", candidate)
diff --git a/utils/path.go b/utils/path.go
new file mode 100644
index 0000000..e8df153
--- /dev/null
+++ b/utils/path.go
@@ -0,0 +1,30 @@
+package utils
+
+import (
+	"os/user"
+	"path"
+	"runtime"
+)
+
+// package-level variables for mocking in tests
+var (
+	userCurrent = user.Current
+	getGOOS     = runtime.GOOS
+)
+
+// GetDefaultCliConfigPath returns the default path for the ArduinoCLI configuration file.
+func GetDefaultCliConfigPath() string {
+	if user, _ := userCurrent(); user != nil {
+		return path.Join(user.HomeDir, func() string {
+			switch getGOOS {
+			case "darwin":
+				return "Library/Arduino15"
+			case "windows":
+				return "AppData\\Local\\Arduino15"
+			default:
+				return ".arduino15"
+			}
+		}(), "arduino-cli.yaml")
+	}
+	return ""
+}
diff --git a/utils/path_test.go b/utils/path_test.go
new file mode 100644
index 0000000..972de24
--- /dev/null
+++ b/utils/path_test.go
@@ -0,0 +1,60 @@
+package utils
+
+import (
+	"os/user"
+	"path"
+	"testing"
+)
+
+func TestGetDefaultCliConfigPath(t *testing.T) {
+	// Save original GOOS getter and restore after test
+	originalGetGOOS := getGOOS
+	defer func() { getGOOS = originalGetGOOS }()
+
+	tests := []struct {
+		name     string
+		goos     string
+		wantPath string
+		user     *user.User
+	}{
+		{
+			name:     "darwin path",
+			goos:     "darwin",
+			user:     &user.User{HomeDir: "/Users/test"},
+			wantPath: path.Join("/Users/test", "Library/Arduino15", "arduino-cli.yaml"),
+		},
+		{
+			name:     "linux path",
+			goos:     "linux",
+			user:     &user.User{HomeDir: "/home/test"},
+			wantPath: path.Join("/home/test", ".arduino15", "arduino-cli.yaml"),
+		},
+		{
+			name:     "windows path",
+			goos:     "windows",
+			user:     &user.User{HomeDir: "C:\\Users\\test"},
+			wantPath: path.Join("C:\\Users\\test", "AppData\\Local\\Arduino15", "arduino-cli.yaml"),
+		},
+		{
+			name:     "nil user",
+			goos:     "linux",
+			user:     nil,
+			wantPath: "",
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			// mocks
+			getGOOS = tt.goos
+			userCurrent = func() (*user.User, error) {
+				return tt.user, nil
+			}
+
+			got := GetDefaultCliConfigPath()
+			if got != tt.wantPath {
+				t.Errorf("GetDefaultCliConfigPath() = %v, want %v", got, tt.wantPath)
+			}
+		})
+	}
+}