diff --git a/arduino/cores/cores.go b/arduino/cores/cores.go
index 0c836c20f8d..c3e09adac79 100644
--- a/arduino/cores/cores.go
+++ b/arduino/cores/cores.go
@@ -75,6 +75,7 @@ type PlatformRelease struct {
 	PluggableDiscoveryAware bool                          `json:"-"` // true if the Platform supports pluggable discovery (no compatibility layer required)
 	Monitors                map[string]*MonitorDependency `json:"-"`
 	MonitorsDevRecipes      map[string]string             `json:"-"`
+	Compatible              bool                          `json:"-"` // true if at all ToolDependencies are available for the current OS/ARCH.
 }
 
 // BoardManifest contains information about a board. These metadata are usually
@@ -229,6 +230,21 @@ func (platform *Platform) GetLatestRelease() *PlatformRelease {
 	return platform.FindReleaseWithVersion(latestVersion)
 }
 
+// GetLatestCompatibleRelease returns the latest compatible release of this platform, or nil if no
+// compatible releases are available.
+func (platform *Platform) GetLatestCompatibleRelease() *PlatformRelease {
+	var maximum *PlatformRelease
+	for _, release := range platform.Releases {
+		if !release.IsCompatible() {
+			continue
+		}
+		if maximum == nil || release.Version.GreaterThan(maximum.Version) {
+			maximum = release
+		}
+	}
+	return maximum
+}
+
 // GetAllReleases returns all the releases of this platform, or an empty
 // slice if no releases are available
 func (platform *Platform) GetAllReleases() []*PlatformRelease {
@@ -249,6 +265,18 @@ func (platform *Platform) GetAllReleasesVersions() []*semver.Version {
 	return versions
 }
 
+// GetAllCompatibleReleasesVersions returns all the version numbers in this Platform Package that contains compatible tools.
+func (platform *Platform) GetAllCompatibleReleasesVersions() []*semver.Version {
+	versions := []*semver.Version{}
+	for _, release := range platform.Releases {
+		if !release.IsCompatible() {
+			continue
+		}
+		versions = append(versions, release.Version)
+	}
+	return versions
+}
+
 // latestReleaseVersion obtains latest version number, or nil if no release available
 func (platform *Platform) latestReleaseVersion() *semver.Version {
 	// TODO: Cache latest version using a field in Platform
@@ -266,6 +294,18 @@ func (platform *Platform) latestReleaseVersion() *semver.Version {
 	return max
 }
 
+// latestCompatibleReleaseVersion obtains latest version number, for platforms that contains compatible tools, or nil if no release available
+func (platform *Platform) latestCompatibleReleaseVersion() *semver.Version {
+	versions := platform.GetAllCompatibleReleasesVersions()
+	var maxVer *semver.Version
+	for _, v := range versions {
+		if maxVer == nil || v.GreaterThan(maxVer) {
+			maxVer = v
+		}
+	}
+	return maxVer
+}
+
 // GetAllInstalled returns all installed PlatformRelease
 func (platform *Platform) GetAllInstalled() []*PlatformRelease {
 	res := []*PlatformRelease{}
@@ -422,3 +462,9 @@ func (release *PlatformRelease) HasMetadata() bool {
 	installedJSONPath := release.InstallDir.Join("installed.json")
 	return installedJSONPath.Exist()
 }
+
+// IsCompatible returns true if all the tools dependencies of a PlatformRelease
+// are available in the current OS/ARCH.
+func (release *PlatformRelease) IsCompatible() bool {
+	return release.Compatible
+}
diff --git a/arduino/cores/packagemanager/download.go b/arduino/cores/packagemanager/download.go
index f3a5877c8a6..43d13c11ea0 100644
--- a/arduino/cores/packagemanager/download.go
+++ b/arduino/cores/packagemanager/download.go
@@ -87,9 +87,9 @@ func (pme *Explorer) FindPlatformReleaseDependencies(item *PlatformReference) (*
 			return nil, nil, fmt.Errorf(tr("required version %[1]s not found for platform %[2]s"), item.PlatformVersion, platform.String())
 		}
 	} else {
-		release = platform.GetLatestRelease()
+		release = platform.GetLatestCompatibleRelease()
 		if release == nil {
-			return nil, nil, fmt.Errorf(tr("platform %s has no available releases"), platform.String())
+			return nil, nil, fmt.Errorf(tr("platform is not available for your OS"))
 		}
 	}
 
diff --git a/arduino/cores/packagemanager/install_uninstall.go b/arduino/cores/packagemanager/install_uninstall.go
index 0d8332cb2be..2f396894fa5 100644
--- a/arduino/cores/packagemanager/install_uninstall.go
+++ b/arduino/cores/packagemanager/install_uninstall.go
@@ -53,7 +53,7 @@ func (pme *Explorer) DownloadAndInstallPlatformUpgrades(
 	if installed == nil {
 		return nil, &arduino.PlatformNotFoundError{Platform: platformRef.String()}
 	}
-	latest := platform.GetLatestRelease()
+	latest := platform.GetLatestCompatibleRelease()
 	if !latest.Version.GreaterThan(installed.Version) {
 		return installed, &arduino.PlatformAlreadyAtTheLatestVersionError{Platform: platformRef.String()}
 	}
diff --git a/arduino/cores/packagemanager/package_manager.go b/arduino/cores/packagemanager/package_manager.go
index 1d6ac17aac0..1f2b380e08a 100644
--- a/arduino/cores/packagemanager/package_manager.go
+++ b/arduino/cores/packagemanager/package_manager.go
@@ -121,6 +121,42 @@ func (pmb *Builder) Build() *PackageManager {
 	}
 }
 
+// calculate Compatible PlatformRelease
+func (pmb *Builder) calculateCompatibleReleases() {
+	for _, op := range pmb.packages {
+		for _, p := range op.Platforms {
+			for _, pr := range p.Releases {
+				platformHasAllCompatibleTools := func() bool {
+					for _, td := range pr.ToolDependencies {
+						if td == nil {
+							return false
+						}
+
+						_, ok := pmb.packages[td.ToolPackager]
+						if !ok {
+							return false
+						}
+						tool := pmb.packages[td.ToolPackager].Tools[td.ToolName]
+						if tool == nil {
+							return false
+						}
+						tr := tool.Releases[td.ToolVersion.NormalizedString()]
+						if tr == nil {
+							return false
+						}
+
+						if tr.GetCompatibleFlavour() == nil {
+							return false
+						}
+					}
+					return true
+				}
+				pr.Compatible = platformHasAllCompatibleTools()
+			}
+		}
+	}
+}
+
 // NewBuilder creates a Builder with the same configuration
 // of this PackageManager. A "commit" function callback is returned: calling
 // this function will make the builder write the new configuration into this
@@ -128,6 +164,7 @@ func (pmb *Builder) Build() *PackageManager {
 func (pm *PackageManager) NewBuilder() (builder *Builder, commit func()) {
 	pmb := NewBuilder(pm.IndexDir, pm.PackagesDir, pm.DownloadDir, pm.tempDir, pm.userAgent)
 	return pmb, func() {
+		pmb.calculateCompatibleReleases()
 		pmb.BuildIntoExistingPackageManager(pm)
 	}
 }
diff --git a/arduino/cores/packagemanager/package_manager_test.go b/arduino/cores/packagemanager/package_manager_test.go
index c02fa34eaa6..8a5fc877850 100644
--- a/arduino/cores/packagemanager/package_manager_test.go
+++ b/arduino/cores/packagemanager/package_manager_test.go
@@ -744,6 +744,7 @@ func TestFindToolsRequiredFromPlatformRelease(t *testing.T) {
 func TestFindPlatformReleaseDependencies(t *testing.T) {
 	pmb := NewBuilder(nil, nil, nil, nil, "test")
 	pmb.LoadPackageIndexFromFile(paths.New("testdata", "package_tooltest_index.json"))
+	pmb.calculateCompatibleReleases()
 	pm := pmb.Build()
 	pme, release := pm.NewExplorer()
 	defer release()
diff --git a/commands/board/search.go b/commands/board/search.go
index 007867775e3..bd8702504d7 100644
--- a/commands/board/search.go
+++ b/commands/board/search.go
@@ -41,7 +41,7 @@ func Search(ctx context.Context, req *rpc.BoardSearchRequest) (*rpc.BoardSearchR
 	foundBoards := []*rpc.BoardListItem{}
 	for _, targetPackage := range pme.GetPackages() {
 		for _, platform := range targetPackage.Platforms {
-			latestPlatformRelease := platform.GetLatestRelease()
+			latestPlatformRelease := platform.GetLatestCompatibleRelease()
 			installedPlatformRelease := pme.GetInstalledPlatformRelease(platform)
 
 			if latestPlatformRelease == nil && installedPlatformRelease == nil {
diff --git a/commands/core.go b/commands/core.go
index 14dc3360e4c..1881519ef38 100644
--- a/commands/core.go
+++ b/commands/core.go
@@ -74,5 +74,6 @@ func PlatformReleaseToRPC(platformRelease *cores.PlatformRelease) *rpc.PlatformR
 		MissingMetadata: missingMetadata,
 		Type:            []string{platformRelease.Category},
 		Deprecated:      platformRelease.Deprecated,
+		Compatible:      platformRelease.IsCompatible(),
 	}
 }
diff --git a/commands/core/search.go b/commands/core/search.go
index 7d0b5662f31..c0341b40a91 100644
--- a/commands/core/search.go
+++ b/commands/core/search.go
@@ -55,10 +55,7 @@ func PlatformSearch(req *rpc.PlatformSearchRequest) (*rpc.PlatformSearchResponse
 
 				// Discard platforms with no releases
 				latestRelease := platform.GetLatestRelease()
-				if latestRelease == nil {
-					continue
-				}
-				if latestRelease.Name == "" {
+				if latestRelease == nil || latestRelease.Name == "" {
 					continue
 				}
 
@@ -86,41 +83,25 @@ func PlatformSearch(req *rpc.PlatformSearchRequest) (*rpc.PlatformSearchResponse
 	out := []*rpc.PlatformSummary{}
 	for _, platform := range res {
 		rpcPlatformSummary := &rpc.PlatformSummary{
+			Metadata: commands.PlatformToRPCPlatformMetadata(platform),
 			Releases: map[string]*rpc.PlatformRelease{},
 		}
-
-		rpcPlatformSummary.Metadata = commands.PlatformToRPCPlatformMetadata(platform)
-
-		installed := pme.GetInstalledPlatformRelease(platform)
-		latest := platform.GetLatestRelease()
-		if installed != nil {
+		if installed := pme.GetInstalledPlatformRelease(platform); installed != nil {
 			rpcPlatformSummary.InstalledVersion = installed.Version.String()
 		}
-		if latest != nil {
-			rpcPlatformSummary.LatestVersion = latest.Version.String()
+		if latestCompatible := platform.GetLatestCompatibleRelease(); latestCompatible != nil {
+			rpcPlatformSummary.LatestVersion = latestCompatible.Version.String()
 		}
-		if req.AllVersions {
-			for _, platformRelease := range platform.GetAllReleases() {
-				rpcPlatformRelease := commands.PlatformReleaseToRPC(platformRelease)
-				rpcPlatformSummary.Releases[rpcPlatformRelease.Version] = rpcPlatformRelease
-			}
-		} else {
-			if installed != nil {
-				rpcPlatformRelease := commands.PlatformReleaseToRPC(installed)
-				rpcPlatformSummary.Releases[installed.Version.String()] = rpcPlatformRelease
-			}
-			if latest != nil {
-				rpcPlatformRelease := commands.PlatformReleaseToRPC(latest)
-				rpcPlatformSummary.Releases[latest.Version.String()] = rpcPlatformRelease
-			}
+		for _, platformRelease := range platform.GetAllReleases() {
+			rpcPlatformRelease := commands.PlatformReleaseToRPC(platformRelease)
+			rpcPlatformSummary.Releases[rpcPlatformRelease.Version] = rpcPlatformRelease
 		}
 		out = append(out, rpcPlatformSummary)
 	}
 
 	// Sort result alphabetically and put deprecated platforms at the bottom
 	sort.Slice(out, func(i, j int) bool {
-		return strings.ToLower(out[i].GetReleases()[out[i].GetLatestVersion()].Name) <
-			strings.ToLower(out[j].GetReleases()[out[j].GetLatestVersion()].Name)
+		return strings.ToLower(out[i].GetMetadata().GetId()) < strings.ToLower(out[j].GetMetadata().GetId())
 	})
 	sort.SliceStable(out, func(i, j int) bool {
 		return !out[i].GetMetadata().Deprecated && out[j].GetMetadata().Deprecated
diff --git a/commands/core/search_test.go b/commands/core/search_test.go
index a695acbd6b4..ea3fdc4ef9d 100644
--- a/commands/core/search_test.go
+++ b/commands/core/search_test.go
@@ -43,9 +43,8 @@ func TestPlatformSearch(t *testing.T) {
 
 	t.Run("SearchAllVersions", func(t *testing.T) {
 		res, stat := PlatformSearch(&rpc.PlatformSearchRequest{
-			Instance:    inst,
-			SearchArgs:  "retrokit",
-			AllVersions: true,
+			Instance:   inst,
+			SearchArgs: "retrokit",
 		})
 		require.Nil(t, stat)
 		require.NotNil(t, res)
@@ -61,64 +60,32 @@ func TestPlatformSearch(t *testing.T) {
 			},
 			Releases: map[string]*rpc.PlatformRelease{
 				"1.0.5": {
-					Name:      "RK002",
-					Type:      []string{"Contributed"},
-					Installed: false,
-					Version:   "1.0.5",
-					Boards:    []*rpc.Board{{Name: "RK002"}},
-					Help:      &rpc.HelpResources{Online: "https://www.retrokits.com/rk002/arduino"},
-				},
-				"1.0.6": {
-					Name:      "RK002",
-					Type:      []string{"Contributed"},
-					Installed: false,
-					Version:   "1.0.6",
-					Boards:    []*rpc.Board{{Name: "RK002"}},
-					Help:      &rpc.HelpResources{Online: "https://www.retrokits.com/rk002/arduino"},
+					Name:       "RK002",
+					Type:       []string{"Contributed"},
+					Installed:  false,
+					Version:    "1.0.5",
+					Boards:     []*rpc.Board{{Name: "RK002"}},
+					Help:       &rpc.HelpResources{Online: "https://www.retrokits.com/rk002/arduino"},
+					Compatible: false,
 				},
-			},
-			InstalledVersion: "",
-			LatestVersion:    "1.0.6",
-		})
-	})
-
-	t.Run("SearchNoAllVersions", func(t *testing.T) {
-		res, stat := PlatformSearch(&rpc.PlatformSearchRequest{
-			Instance:    inst,
-			SearchArgs:  "retrokit",
-			AllVersions: false,
-		})
-		require.Nil(t, stat)
-		require.NotNil(t, res)
-		require.Len(t, res.SearchOutput, 1)
-		require.Contains(t, res.SearchOutput, &rpc.PlatformSummary{
-			Metadata: &rpc.PlatformMetadata{
-				Id:         "Retrokits-RK002:arm",
-				Maintainer: "Retrokits (www.retrokits.com)",
-				Website:    "https://www.retrokits.com",
-				Email:      "info@retrokits.com",
-				Indexed:    true,
-			},
-			Releases: map[string]*rpc.PlatformRelease{
 				"1.0.6": {
-					Name:      "RK002",
-					Type:      []string{"Contributed"},
-					Installed: false,
-					Version:   "1.0.6",
-					Boards:    []*rpc.Board{{Name: "RK002"}},
-					Help:      &rpc.HelpResources{Online: "https://www.retrokits.com/rk002/arduino"},
+					Name:       "RK002",
+					Type:       []string{"Contributed"},
+					Installed:  false,
+					Version:    "1.0.6",
+					Boards:     []*rpc.Board{{Name: "RK002"}},
+					Help:       &rpc.HelpResources{Online: "https://www.retrokits.com/rk002/arduino"},
+					Compatible: false,
 				},
 			},
 			InstalledVersion: "",
-			LatestVersion:    "1.0.6",
 		})
 	})
 
 	t.Run("SearchThePackageMaintainer", func(t *testing.T) {
 		res, stat := PlatformSearch(&rpc.PlatformSearchRequest{
-			Instance:    inst,
-			SearchArgs:  "Retrokits (www.retrokits.com)",
-			AllVersions: true,
+			Instance:   inst,
+			SearchArgs: "Retrokits (www.retrokits.com)",
 		})
 		require.Nil(t, stat)
 		require.NotNil(t, res)
@@ -133,32 +100,32 @@ func TestPlatformSearch(t *testing.T) {
 			},
 			Releases: map[string]*rpc.PlatformRelease{
 				"1.0.5": {
-					Name:      "RK002",
-					Type:      []string{"Contributed"},
-					Installed: false,
-					Version:   "1.0.5",
-					Boards:    []*rpc.Board{{Name: "RK002"}},
-					Help:      &rpc.HelpResources{Online: "https://www.retrokits.com/rk002/arduino"},
+					Name:       "RK002",
+					Type:       []string{"Contributed"},
+					Installed:  false,
+					Version:    "1.0.5",
+					Boards:     []*rpc.Board{{Name: "RK002"}},
+					Help:       &rpc.HelpResources{Online: "https://www.retrokits.com/rk002/arduino"},
+					Compatible: false,
 				},
 				"1.0.6": {
-					Name:      "RK002",
-					Type:      []string{"Contributed"},
-					Installed: false,
-					Version:   "1.0.6",
-					Boards:    []*rpc.Board{{Name: "RK002"}},
-					Help:      &rpc.HelpResources{Online: "https://www.retrokits.com/rk002/arduino"},
+					Name:       "RK002",
+					Type:       []string{"Contributed"},
+					Installed:  false,
+					Version:    "1.0.6",
+					Boards:     []*rpc.Board{{Name: "RK002"}},
+					Help:       &rpc.HelpResources{Online: "https://www.retrokits.com/rk002/arduino"},
+					Compatible: false,
 				},
 			},
 			InstalledVersion: "",
-			LatestVersion:    "1.0.6",
 		})
 	})
 
 	t.Run("SearchPackageName", func(t *testing.T) {
 		res, stat := PlatformSearch(&rpc.PlatformSearchRequest{
-			Instance:    inst,
-			SearchArgs:  "Retrokits-RK002",
-			AllVersions: true,
+			Instance:   inst,
+			SearchArgs: "Retrokits-RK002",
 		})
 		require.Nil(t, stat)
 		require.NotNil(t, res)
@@ -173,32 +140,32 @@ func TestPlatformSearch(t *testing.T) {
 			},
 			Releases: map[string]*rpc.PlatformRelease{
 				"1.0.5": {
-					Name:      "RK002",
-					Type:      []string{"Contributed"},
-					Installed: false,
-					Version:   "1.0.5",
-					Boards:    []*rpc.Board{{Name: "RK002"}},
-					Help:      &rpc.HelpResources{Online: "https://www.retrokits.com/rk002/arduino"},
+					Name:       "RK002",
+					Type:       []string{"Contributed"},
+					Installed:  false,
+					Version:    "1.0.5",
+					Boards:     []*rpc.Board{{Name: "RK002"}},
+					Help:       &rpc.HelpResources{Online: "https://www.retrokits.com/rk002/arduino"},
+					Compatible: false,
 				},
 				"1.0.6": {
-					Name:      "RK002",
-					Type:      []string{"Contributed"},
-					Installed: false,
-					Version:   "1.0.6",
-					Boards:    []*rpc.Board{{Name: "RK002"}},
-					Help:      &rpc.HelpResources{Online: "https://www.retrokits.com/rk002/arduino"},
+					Name:       "RK002",
+					Type:       []string{"Contributed"},
+					Installed:  false,
+					Version:    "1.0.6",
+					Boards:     []*rpc.Board{{Name: "RK002"}},
+					Help:       &rpc.HelpResources{Online: "https://www.retrokits.com/rk002/arduino"},
+					Compatible: false,
 				},
 			},
 			InstalledVersion: "",
-			LatestVersion:    "1.0.6",
 		})
 	})
 
 	t.Run("SearchPlatformName", func(t *testing.T) {
 		res, stat := PlatformSearch(&rpc.PlatformSearchRequest{
-			Instance:    inst,
-			SearchArgs:  "rk002",
-			AllVersions: true,
+			Instance:   inst,
+			SearchArgs: "rk002",
 		})
 		require.Nil(t, stat)
 		require.NotNil(t, res)
@@ -213,32 +180,32 @@ func TestPlatformSearch(t *testing.T) {
 			},
 			Releases: map[string]*rpc.PlatformRelease{
 				"1.0.5": {
-					Name:      "RK002",
-					Type:      []string{"Contributed"},
-					Installed: false,
-					Version:   "1.0.5",
-					Boards:    []*rpc.Board{{Name: "RK002"}},
-					Help:      &rpc.HelpResources{Online: "https://www.retrokits.com/rk002/arduino"},
+					Name:       "RK002",
+					Type:       []string{"Contributed"},
+					Installed:  false,
+					Version:    "1.0.5",
+					Boards:     []*rpc.Board{{Name: "RK002"}},
+					Help:       &rpc.HelpResources{Online: "https://www.retrokits.com/rk002/arduino"},
+					Compatible: false,
 				},
 				"1.0.6": {
-					Name:      "RK002",
-					Type:      []string{"Contributed"},
-					Installed: false,
-					Version:   "1.0.6",
-					Boards:    []*rpc.Board{{Name: "RK002"}},
-					Help:      &rpc.HelpResources{Online: "https://www.retrokits.com/rk002/arduino"},
+					Name:       "RK002",
+					Type:       []string{"Contributed"},
+					Installed:  false,
+					Version:    "1.0.6",
+					Boards:     []*rpc.Board{{Name: "RK002"}},
+					Help:       &rpc.HelpResources{Online: "https://www.retrokits.com/rk002/arduino"},
+					Compatible: false,
 				},
 			},
 			InstalledVersion: "",
-			LatestVersion:    "1.0.6",
 		})
 	})
 
 	t.Run("SearchBoardName", func(t *testing.T) {
 		res, stat := PlatformSearch(&rpc.PlatformSearchRequest{
-			Instance:    inst,
-			SearchArgs:  "Yún",
-			AllVersions: true,
+			Instance:   inst,
+			SearchArgs: "Yún",
 		})
 		require.Nil(t, stat)
 		require.NotNil(t, res)
@@ -285,19 +252,18 @@ func TestPlatformSearch(t *testing.T) {
 						{Name: "Arduino Industrial 101"},
 						{Name: "Linino One"},
 					},
-					Help: &rpc.HelpResources{Online: "http://www.arduino.cc/en/Reference/HomePage"},
+					Help:       &rpc.HelpResources{Online: "http://www.arduino.cc/en/Reference/HomePage"},
+					Compatible: false,
 				},
 			},
 			InstalledVersion: "",
-			LatestVersion:    "1.8.3",
 		})
 	})
 
 	t.Run("SearchBoardName2", func(t *testing.T) {
 		res, stat := PlatformSearch(&rpc.PlatformSearchRequest{
-			Instance:    inst,
-			SearchArgs:  "yun",
-			AllVersions: true,
+			Instance:   inst,
+			SearchArgs: "yun",
 		})
 		require.Nil(t, stat)
 		require.NotNil(t, res)
@@ -344,11 +310,11 @@ func TestPlatformSearch(t *testing.T) {
 						{Name: "Arduino Industrial 101"},
 						{Name: "Linino One"},
 					},
-					Help: &rpc.HelpResources{Online: "http://www.arduino.cc/en/Reference/HomePage"},
+					Help:       &rpc.HelpResources{Online: "http://www.arduino.cc/en/Reference/HomePage"},
+					Compatible: false,
 				},
 			},
 			InstalledVersion: "",
-			LatestVersion:    "1.8.3",
 		})
 	})
 }
@@ -370,17 +336,16 @@ func TestPlatformSearchSorting(t *testing.T) {
 	require.NotNil(t, inst)
 
 	res, stat := PlatformSearch(&rpc.PlatformSearchRequest{
-		Instance:    inst,
-		SearchArgs:  "",
-		AllVersions: false,
+		Instance:   inst,
+		SearchArgs: "",
 	})
 	require.Nil(t, stat)
 	require.NotNil(t, res)
 
 	require.Len(t, res.SearchOutput, 3)
-	require.Equal(t, res.SearchOutput[0].GetLatestRelease().Name, "Arduino AVR Boards")
+	require.Equal(t, res.SearchOutput[0].GetSortedReleases()[0].Name, "Arduino AVR Boards")
 	require.Equal(t, res.SearchOutput[0].Metadata.Deprecated, false)
-	require.Equal(t, res.SearchOutput[1].GetLatestRelease().Name, "RK002")
+	require.Equal(t, res.SearchOutput[1].GetSortedReleases()[0].Name, "RK002")
 	require.Equal(t, res.SearchOutput[1].Metadata.Deprecated, false)
 	require.Equal(t, res.SearchOutput[2].GetLatestRelease().Name, "Platform")
 	require.Equal(t, res.SearchOutput[2].Metadata.Deprecated, true)
diff --git a/docs/UPGRADING.md b/docs/UPGRADING.md
index 037f4992058..8b8ebcf7790 100644
--- a/docs/UPGRADING.md
+++ b/docs/UPGRADING.md
@@ -4,6 +4,34 @@ Here you can find a list of migration guides to handle breaking changes between
 
 ## 0.36.0
 
+### The gRPC `cc.arduino.cli.commands.v1.PlatformRelease` has been changed.
+
+We've added a new field called `compatible`. This field indicates if the current platform release is installable or not.
+It may happen that a platform doesn't have a dependency available for an OS/ARCH, in such cases, if we try to install
+the platform it will fail. The new field can be used to know upfront if a specific release is installable.
+
+### The gRPC `cc.arduino.cli.commands.v1.PlatformSummary` has been changed.
+
+We've modified the behavior of `latest_version`. Now this field indicates the latest version that can be installed in
+the current OS/ARCH.
+
+### `core list` now returns only the latest version that can be installed.
+
+Previously, we showed the latest version without checking if all the dependencies were available in the current OS/ARCH.
+Now, the latest version will always point to an installable one even if a newer incompatible one is present.
+
+### `core search` now returns the latest installable version of a core.
+
+We now show in the `version` column the latest installable version. If none are available then we show a `n/a` label.
+The corresponding command with `--format json` now returns the same output of
+`arduino-cli core search --all --format json`.
+
+### `core upgrade` and `core install` will install the latest compatible version.
+
+Previously, we'd have tried the installation/upgrade of a core even if all the required tools weren't available in the
+current OS/ARCH. Now we check this upfront, and allowing the installation of incompatible versions only if a user
+explicitly provides it like: `core install arduino:renesas_uno@1.0.2`
+
 ### gRPC service `cc.arduino.cli.settings.v1` has been removed, and all RPC calls have been migrated to `cc.arduino.cli.commands.v1`
 
 The service `cc.arduino.cli.settings.v1` no longer exists and all existing RPC calls have been moved to the
diff --git a/internal/cli/arguments/completion.go b/internal/cli/arguments/completion.go
index 2139e415fe1..89423edd1a7 100644
--- a/internal/cli/arguments/completion.go
+++ b/internal/cli/arguments/completion.go
@@ -85,7 +85,6 @@ func GetUninstallableCores() []string {
 
 	platforms, _ := core.PlatformSearch(&rpc.PlatformSearchRequest{
 		Instance:          inst,
-		AllVersions:       false,
 		ManuallyInstalled: true,
 	})
 
@@ -106,14 +105,15 @@ func GetInstallableCores() []string {
 	inst := instance.CreateAndInit()
 
 	platforms, _ := core.PlatformSearch(&rpc.PlatformSearchRequest{
-		Instance:    inst,
-		SearchArgs:  "",
-		AllVersions: false,
+		Instance:   inst,
+		SearchArgs: "",
 	})
 	var res []string
 	// transform the data structure for the completion
-	for _, i := range platforms.SearchOutput {
-		res = append(res, i.GetMetadata().GetId()+"\t"+i.GetReleases()[i.GetLatestVersion()].GetName())
+	for _, i := range platforms.GetSearchOutput() {
+		if latest := i.GetLatestRelease(); latest != nil {
+			res = append(res, i.GetMetadata().GetId()+"\t"+latest.GetName())
+		}
 	}
 	return res
 }
diff --git a/internal/cli/arguments/reference.go b/internal/cli/arguments/reference.go
index f9d8737d415..ed6152af5b8 100644
--- a/internal/cli/arguments/reference.go
+++ b/internal/cli/arguments/reference.go
@@ -96,8 +96,7 @@ func ParseReference(arg string) (*Reference, error) {
 	// try to use core.PlatformList to optimize what the user typed
 	// (by replacing the PackageName and Architecture in ret with the content of core.GetPlatform())
 	platforms, _ := core.PlatformSearch(&rpc.PlatformSearchRequest{
-		Instance:    instance.CreateAndInit(),
-		AllVersions: false,
+		Instance: instance.CreateAndInit(),
 	})
 	foundPlatforms := []string{}
 	for _, platform := range platforms.GetSearchOutput() {
diff --git a/internal/cli/compile/compile.go b/internal/cli/compile/compile.go
index 1204b529f17..7cd66de7663 100644
--- a/internal/cli/compile/compile.go
+++ b/internal/cli/compile/compile.go
@@ -370,9 +370,8 @@ func runCompileCommand(cmd *cobra.Command, args []string) {
 				res.Error += fmt.Sprintln()
 
 				if platform, err := core.PlatformSearch(&rpc.PlatformSearchRequest{
-					Instance:    inst,
-					SearchArgs:  platformErr.Platform,
-					AllVersions: false,
+					Instance:   inst,
+					SearchArgs: platformErr.Platform,
 				}); err != nil {
 					res.Error += err.Error()
 				} else if len(platform.GetSearchOutput()) > 0 {
diff --git a/internal/cli/core/list.go b/internal/cli/core/list.go
index 1adda2f26bc..40ac933f027 100644
--- a/internal/cli/core/list.go
+++ b/internal/cli/core/list.go
@@ -16,7 +16,6 @@
 package core
 
 import (
-	"fmt"
 	"os"
 
 	"github.com/arduino/arduino-cli/commands/core"
@@ -56,14 +55,13 @@ func runListCommand(args []string, all bool, updatableOnly bool) {
 // List gets and prints a list of installed platforms.
 func List(inst *rpc.Instance, all bool, updatableOnly bool) {
 	platforms := GetList(inst, all, updatableOnly)
-	feedback.PrintResult(newCoreListResult(platforms))
+	feedback.PrintResult(newCoreListResult(platforms, updatableOnly))
 }
 
 // GetList returns a list of installed platforms.
 func GetList(inst *rpc.Instance, all bool, updatableOnly bool) []*rpc.PlatformSummary {
 	platforms, err := core.PlatformSearch(&rpc.PlatformSearchRequest{
 		Instance:          inst,
-		AllVersions:       true,
 		ManuallyInstalled: true,
 	})
 	if err != nil {
@@ -88,8 +86,8 @@ func GetList(inst *rpc.Instance, all bool, updatableOnly bool) []*rpc.PlatformSu
 	return result
 }
 
-func newCoreListResult(in []*rpc.PlatformSummary) *coreListResult {
-	res := &coreListResult{}
+func newCoreListResult(in []*rpc.PlatformSummary, updatableOnly bool) *coreListResult {
+	res := &coreListResult{updatableOnly: updatableOnly}
 	for _, platformSummary := range in {
 		res.platforms = append(res.platforms, result.NewPlatformSummary(platformSummary))
 	}
@@ -97,7 +95,8 @@ func newCoreListResult(in []*rpc.PlatformSummary) *coreListResult {
 }
 
 type coreListResult struct {
-	platforms []*result.PlatformSummary
+	platforms     []*result.PlatformSummary
+	updatableOnly bool
 }
 
 // Data implements Result interface
@@ -108,24 +107,19 @@ func (ir coreListResult) Data() interface{} {
 // String implements Result interface
 func (ir coreListResult) String() string {
 	if len(ir.platforms) == 0 {
+		if ir.updatableOnly {
+			return tr("All platforms are up to date.")
+		}
 		return tr("No platforms installed.")
 	}
 	t := table.New()
 	t.SetHeader(tr("ID"), tr("Installed"), tr("Latest"), tr("Name"))
 	for _, platform := range ir.platforms {
-		name := ""
-		if installed := platform.GetInstalledRelease(); installed != nil {
-			name = installed.Name
-		}
-		if name == "" {
-			if latest := platform.GetLatestRelease(); latest != nil {
-				name = latest.Name
-			}
-		}
-		if platform.Deprecated {
-			name = fmt.Sprintf("[%s] %s", tr("DEPRECATED"), name)
+		latestVersion := platform.LatestVersion.String()
+		if latestVersion == "" {
+			latestVersion = "n/a"
 		}
-		t.AddRow(platform.Id, platform.InstalledVersion, platform.LatestVersion, name)
+		t.AddRow(platform.Id, platform.InstalledVersion, latestVersion, platform.GetPlatformName())
 	}
 
 	return t.Render()
diff --git a/internal/cli/core/search.go b/internal/cli/core/search.go
index 30d4f749759..0fc2389cdd8 100644
--- a/internal/cli/core/search.go
+++ b/internal/cli/core/search.go
@@ -37,18 +37,17 @@ import (
 	"github.com/spf13/cobra"
 )
 
-var (
-	allVersions bool
-)
-
 func initSearchCommand() *cobra.Command {
+	var allVersions bool
 	searchCommand := &cobra.Command{
 		Use:     fmt.Sprintf("search <%s...>", tr("keywords")),
 		Short:   tr("Search for a core in Boards Manager."),
 		Long:    tr("Search for a core in Boards Manager using the specified keywords."),
 		Example: "  " + os.Args[0] + " core search MKRZero -a -v",
 		Args:    cobra.ArbitraryArgs,
-		Run:     runSearchCommand,
+		Run: func(cmd *cobra.Command, args []string) {
+			runSearchCommand(cmd, args, allVersions)
+		},
 	}
 	searchCommand.Flags().BoolVarP(&allVersions, "all", "a", false, tr("Show all available core versions."))
 
@@ -58,7 +57,7 @@ func initSearchCommand() *cobra.Command {
 // indexUpdateInterval specifies the time threshold over which indexes are updated
 const indexUpdateInterval = "24h"
 
-func runSearchCommand(cmd *cobra.Command, args []string) {
+func runSearchCommand(cmd *cobra.Command, args []string, allVersions bool) {
 	inst := instance.CreateAndInit()
 
 	if indexesNeedUpdating(indexUpdateInterval) {
@@ -73,28 +72,31 @@ func runSearchCommand(cmd *cobra.Command, args []string) {
 	logrus.Infof("Executing `arduino-cli core search` with args: '%s'", arguments)
 
 	resp, err := core.PlatformSearch(&rpc.PlatformSearchRequest{
-		Instance:    inst,
-		SearchArgs:  arguments,
-		AllVersions: allVersions,
+		Instance:   inst,
+		SearchArgs: arguments,
 	})
 	if err != nil {
 		feedback.Fatal(tr("Error searching for platforms: %v", err), feedback.ErrGeneric)
 	}
 
 	coreslist := resp.GetSearchOutput()
-	feedback.PrintResult(newSearchResult(coreslist))
+	feedback.PrintResult(newSearchResult(coreslist, allVersions))
 }
 
 // output from this command requires special formatting, let's create a dedicated
 // feedback.Result implementation
 type searchResults struct {
-	platforms []*result.PlatformSummary
+	platforms   []*result.PlatformSummary
+	allVersions bool
 }
 
-func newSearchResult(in []*rpc.PlatformSummary) *searchResults {
-	res := &searchResults{}
-	for _, platformSummary := range in {
-		res.platforms = append(res.platforms, result.NewPlatformSummary(platformSummary))
+func newSearchResult(in []*rpc.PlatformSummary, allVersions bool) *searchResults {
+	res := &searchResults{
+		platforms:   make([]*result.PlatformSummary, len(in)),
+		allVersions: allVersions,
+	}
+	for i, platformSummary := range in {
+		res.platforms[i] = result.NewPlatformSummary(platformSummary)
 	}
 	return res
 }
@@ -104,24 +106,33 @@ func (sr searchResults) Data() interface{} {
 }
 
 func (sr searchResults) String() string {
-	if len(sr.platforms) > 0 {
-		t := table.New()
-		t.SetHeader(tr("ID"), tr("Version"), tr("Name"))
-		for _, platform := range sr.platforms {
-			name := ""
-			if latest := platform.GetLatestRelease(); latest != nil {
-				name = latest.Name
-			}
-			if platform.Deprecated {
-				name = fmt.Sprintf("[%s] %s", tr("DEPRECATED"), name)
-			}
-			for _, version := range platform.Releases.Keys() {
-				t.AddRow(platform.Id, version, name)
-			}
+	if len(sr.platforms) == 0 {
+		return tr("No platforms matching your search.")
+	}
+
+	t := table.New()
+	t.SetHeader(tr("ID"), tr("Version"), tr("Name"))
+
+	addRow := func(platform *result.PlatformSummary, release *result.PlatformRelease) {
+		if release == nil {
+			t.AddRow(platform.Id, "n/a", platform.GetPlatformName())
+			return
+		}
+		t.AddRow(platform.Id, release.Version, release.FormatName())
+	}
+
+	for _, platform := range sr.platforms {
+		// When allVersions is not requested we only show the latest compatible version
+		if !sr.allVersions {
+			addRow(platform, platform.GetLatestRelease())
+			continue
+		}
+
+		for _, release := range platform.Releases.Values() {
+			addRow(platform, release)
 		}
-		return t.Render()
 	}
-	return tr("No platforms matching your search.")
+	return t.Render()
 }
 
 // indexesNeedUpdating returns whether one or more index files need updating.
diff --git a/internal/cli/core/upgrade.go b/internal/cli/core/upgrade.go
index 04045cc3bf6..93bc6c0720f 100644
--- a/internal/cli/core/upgrade.go
+++ b/internal/cli/core/upgrade.go
@@ -61,8 +61,7 @@ func Upgrade(inst *rpc.Instance, args []string, skipPostInstall bool, skipPreUni
 	// if no platform was passed, upgrade allthethings
 	if len(args) == 0 {
 		platforms, err := core.PlatformSearch(&rpc.PlatformSearchRequest{
-			Instance:    inst,
-			AllVersions: false,
+			Instance: inst,
 		})
 		if err != nil {
 			feedback.Fatal(tr("Error retrieving core list: %v", err), feedback.ErrGeneric)
@@ -73,14 +72,14 @@ func Upgrade(inst *rpc.Instance, args []string, skipPostInstall bool, skipPreUni
 			if platform.InstalledVersion == "" {
 				continue
 			}
-			if platform.InstalledVersion == platform.LatestVersion {
-				// if it's not updatable, skip it
-				continue
+			// if it's not updatable, skip it
+			latestRelease := platform.GetLatestRelease()
+			if latestRelease != nil && platform.InstalledVersion != latestRelease.Version {
+				targets = append(targets, &rpc.Platform{
+					Metadata: platform.GetMetadata(),
+					Release:  latestRelease,
+				})
 			}
-			targets = append(targets, &rpc.Platform{
-				Metadata: platform.GetMetadata(),
-				Release:  platform.GetLatestRelease(),
-			})
 		}
 
 		if len(targets) == 0 {
diff --git a/internal/cli/feedback/result/rpc.go b/internal/cli/feedback/result/rpc.go
index a632af7737c..63291754fe7 100644
--- a/internal/cli/feedback/result/rpc.go
+++ b/internal/cli/feedback/result/rpc.go
@@ -17,13 +17,17 @@ package result
 
 import (
 	"cmp"
+	"fmt"
 
+	"github.com/arduino/arduino-cli/i18n"
 	f "github.com/arduino/arduino-cli/internal/algorithms"
 	"github.com/arduino/arduino-cli/internal/orderedmap"
 	rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
 	semver "go.bug.st/relaxed-semver"
 )
 
+var tr = i18n.Tr
+
 // NewPlatformSummary creates a new result.PlatformSummary from rpc.PlatformSummary
 func NewPlatformSummary(in *rpc.PlatformSummary) *PlatformSummary {
 	if in == nil {
@@ -76,6 +80,23 @@ func (p *PlatformSummary) GetInstalledRelease() *PlatformRelease {
 	return p.Releases.Get(p.InstalledVersion)
 }
 
+// GetPlatformName compute the name of the platform based on the installed/available releases.
+func (p *PlatformSummary) GetPlatformName() string {
+	var name string
+	if installed := p.GetInstalledRelease(); installed != nil {
+		name = installed.FormatName()
+	}
+	if name == "" {
+		if latest := p.GetLatestRelease(); latest != nil {
+			name = latest.FormatName()
+		} else {
+			keys := p.Releases.Keys()
+			name = p.Releases.Get(keys[len(keys)-1]).FormatName()
+		}
+	}
+	return name
+}
+
 // NewPlatformRelease creates a new result.PlatformRelease from rpc.PlatformRelease
 func NewPlatformRelease(in *rpc.PlatformRelease) *PlatformRelease {
 	if in == nil {
@@ -103,6 +124,7 @@ func NewPlatformRelease(in *rpc.PlatformRelease) *PlatformRelease {
 		Help:            help,
 		MissingMetadata: in.MissingMetadata,
 		Deprecated:      in.Deprecated,
+		Compatible:      in.Compatible,
 	}
 	return res
 }
@@ -117,6 +139,14 @@ type PlatformRelease struct {
 	Help            *HelpResource `json:"help,omitempty"`
 	MissingMetadata bool          `json:"missing_metadata,omitempty"`
 	Deprecated      bool          `json:"deprecated,omitempty"`
+	Compatible      bool          `json:"compatible"`
+}
+
+func (p *PlatformRelease) FormatName() string {
+	if p.Deprecated {
+		return fmt.Sprintf("[%s] %s", tr("DEPRECATED"), p.Name)
+	}
+	return p.Name
 }
 
 // Board maps a rpc.Board
diff --git a/internal/cli/upload/upload.go b/internal/cli/upload/upload.go
index 73e6166aaaa..7bbc868bf9b 100644
--- a/internal/cli/upload/upload.go
+++ b/internal/cli/upload/upload.go
@@ -138,9 +138,8 @@ func runUploadCommand(args []string, uploadFieldsArgs map[string]string) {
 
 			msg += "\n"
 			if platform, err := core.PlatformSearch(&rpc.PlatformSearchRequest{
-				Instance:    inst,
-				SearchArgs:  platformErr.Platform,
-				AllVersions: false,
+				Instance:   inst,
+				SearchArgs: platformErr.Platform,
 			}); err != nil {
 				msg += err.Error()
 			} else if len(platform.GetSearchOutput()) > 0 {
diff --git a/internal/integrationtest/arduino-cli.go b/internal/integrationtest/arduino-cli.go
index 78ed4dbb3e9..c2b10f7e121 100644
--- a/internal/integrationtest/arduino-cli.go
+++ b/internal/integrationtest/arduino-cli.go
@@ -576,9 +576,8 @@ func (inst *ArduinoCLIInstance) PlatformUpgrade(ctx context.Context, packager, a
 // PlatformSearch calls the "PlatformSearch" gRPC method.
 func (inst *ArduinoCLIInstance) PlatformSearch(ctx context.Context, args string, all bool) (*commands.PlatformSearchResponse, error) {
 	req := &commands.PlatformSearchRequest{
-		Instance:    inst.instance,
-		SearchArgs:  args,
-		AllVersions: all,
+		Instance:   inst.instance,
+		SearchArgs: args,
 	}
 	logCallf(">>> PlatformSearch(%+v)\n", req)
 	resp, err := inst.cli.daemonClient.PlatformSearch(ctx, req)
diff --git a/internal/integrationtest/board/board_test.go b/internal/integrationtest/board/board_test.go
index 70c53de9039..e4163c749c6 100644
--- a/internal/integrationtest/board/board_test.go
+++ b/internal/integrationtest/board/board_test.go
@@ -16,8 +16,8 @@
 package board_test
 
 import (
-	"encoding/json"
 	"os"
+	"runtime"
 	"strings"
 	"testing"
 
@@ -25,7 +25,6 @@ import (
 	"github.com/go-git/go-git/v5"
 	"github.com/go-git/go-git/v5/plumbing"
 	"github.com/stretchr/testify/require"
-	semver "go.bug.st/relaxed-semver"
 	"go.bug.st/testifyjson/requirejson"
 )
 
@@ -182,26 +181,36 @@ func TestBoardListall(t *testing.T) {
 				"name": "Arduino Yún",
 				"fqbn": "arduino:avr:yun",
 				"platform": {
-					"id": "arduino:avr",
-					"installed": "1.8.3",
-					"name": "Arduino AVR Boards"
+					"metadata": {
+						"id": "arduino:avr"
+					},
+					"release": {
+						"name": "Arduino AVR Boards",
+						"version": "1.8.3",
+						"installed": true
+					}
 				}
 			},
 			{
 				"name": "Arduino Uno",
 				"fqbn": "arduino:avr:uno",
 				"platform": {
-					"id": "arduino:avr",
-					"installed": "1.8.3",
-					"name": "Arduino AVR Boards"
+					"metadata": {
+						"id": "arduino:avr"
+					},
+					"release": {
+						"name": "Arduino AVR Boards",
+						"version": "1.8.3",
+						"installed": true
+					}
 				}
 			}
 		]
 	}`)
 
-	// Check if the boards' "latest" value is not empty
+	// Check if the boards' "version" value is not empty
 	requirejson.Parse(t, stdout).
-		Query(`[ .boards | .[] | .platform | select(.latest == "") ]`).
+		Query(`[ .boards | .[] | .platform | select(.version == "") ]`).
 		MustBeEmpty()
 }
 
@@ -232,20 +241,28 @@ func TestBoardListallWithManuallyInstalledPlatform(t *testing.T) {
 				"name": "Arduino MKR1000",
 				"fqbn": "arduino-beta-development:samd:mkr1000",
 				"platform": {
-				  "id": "arduino-beta-development:samd",
-				  "installed": "1.8.11",
-				  "latest": "1.8.11",
-				  "name": "Arduino SAMD (32-bits ARM Cortex-M0+) Boards",
+					"metadata": {
+					  "id": "arduino-beta-development:samd",
+					},
+					"release": {
+						"installed": true,
+						"version": "1.8.11",
+						"name": "Arduino SAMD (32-bits ARM Cortex-M0+) Boards"
+					},
 				}
 			},
 			{
 				"name": "Arduino NANO 33 IoT",
       			"fqbn": "arduino-beta-development:samd:nano_33_iot",
       			"platform": {
-        			"id": "arduino-beta-development:samd",
-        			"installed": "1.8.11",
-        			"latest": "1.8.11",
-        			"name": "Arduino SAMD (32-bits ARM Cortex-M0+) Boards"
+					"metadata": {
+					  "id": "arduino-beta-development:samd",
+					},
+					"release": {
+						"installed": true,
+						"version": "1.8.11",
+						"name": "Arduino SAMD (32-bits ARM Cortex-M0+) Boards"
+					},
 				}
 			}
 		]
@@ -575,36 +592,6 @@ func TestBoardAttach(t *testing.T) {
 	}
 }
 
-func TestBoardSearchWithOutdatedCore(t *testing.T) {
-	env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t)
-	defer env.CleanUp()
-
-	_, _, err := cli.Run("update")
-	require.NoError(t, err)
-
-	// Install an old core version
-	_, _, err = cli.Run("core", "install", "arduino:samd@1.8.6")
-	require.NoError(t, err)
-
-	stdout, _, err := cli.Run("board", "search", "arduino:samd:mkrwifi1010", "--format", "json")
-	require.NoError(t, err)
-	requirejson.Len(t, stdout, 1)
-	var data []map[string]interface{}
-	err = json.Unmarshal(stdout, &data)
-	require.NoError(t, err)
-	board := data[0]
-	require.Equal(t, board["name"], "Arduino MKR WiFi 1010")
-	require.Equal(t, board["fqbn"], "arduino:samd:mkrwifi1010")
-	samdCore := board["platform"].(map[string]interface{})
-	require.Equal(t, samdCore["id"], "arduino:samd")
-	installedVersion, err := semver.Parse(samdCore["installed"].(string))
-	require.NoError(t, err)
-	latestVersion, err := semver.Parse(samdCore["latest"].(string))
-	require.NoError(t, err)
-	// Installed version must be older than latest
-	require.True(t, installedVersion.LessThan(latestVersion))
-}
-
 func TestBoardListWithFailedBuiltinInstallation(t *testing.T) {
 	env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t)
 	defer env.CleanUp()
@@ -616,10 +603,14 @@ func TestBoardListWithFailedBuiltinInstallation(t *testing.T) {
 	_, _, err = cli.Run("board", "list")
 	require.NoError(t, err)
 
+	ext := ""
+	if runtime.GOOS == "windows" {
+		ext = ".exe"
+	}
 	// remove files from serial-discovery directory to simulate a failed installation
 	serialDiscovery, err := cli.DataDir().Join("packages", "builtin", "tools", "serial-discovery").ReadDir()
 	require.NoError(t, err)
-	require.NoError(t, serialDiscovery[0].Join("serial-discovery.exe").Remove())
+	require.NoError(t, serialDiscovery[0].Join("serial-discovery"+ext).Remove())
 
 	// board list should install serial-discovery again
 	stdout, stderr, err := cli.Run("board", "list")
diff --git a/internal/integrationtest/core/core_test.go b/internal/integrationtest/core/core_test.go
index c5762d3beb6..c9db2e7701e 100644
--- a/internal/integrationtest/core/core_test.go
+++ b/internal/integrationtest/core/core_test.go
@@ -178,11 +178,11 @@ func TestCoreSearchNoArgs(t *testing.T) {
 	require.Contains(t, lines, []string{"test:x86", "2.0.0", "test_core"})
 	numPlatforms := len(lines) - 1
 
-	// same thing in JSON format, also check the number of platforms found is the same
+	// Same thing in JSON format, also check the number of platforms found is the same
 	stdout, _, err = cli.Run("core", "search", "--format", "json")
 	require.NoError(t, err)
 	requirejson.Contains(t, stdout, `[{"id": "test:x86", "releases": { "2.0.0": {"name":"test_core"}}}]`)
-	requirejson.Query(t, stdout, "length", fmt.Sprint(numPlatforms))
+	requirejson.Len(t, stdout, numPlatforms)
 
 	// list all with additional urls, check the test core is there
 	stdout, _, err = cli.Run("core", "search", "--additional-urls="+url.String())
@@ -191,17 +191,27 @@ func TestCoreSearchNoArgs(t *testing.T) {
 	for _, v := range strings.Split(strings.TrimSpace(string(stdout)), "\n") {
 		lines = append(lines, strings.Fields(strings.TrimSpace(v)))
 	}
-	// Check the presence of test:x86@3.0.0
-	require.Contains(t, lines, []string{"test:x86", "3.0.0", "test_core"})
+	// Check the absence of test:x86@3.0.0 because it contains incompatible deps. The latest available should be the 2.0.0
+	require.NotContains(t, lines, []string{"test:x86", "3.0.0", "test_core"})
+	require.Contains(t, lines, []string{"test:x86", "2.0.0", "test_core"})
 	numPlatforms = len(lines) - 1
 
 	// same thing in JSON format, also check the number of platforms found is the same
 	stdout, _, err = cli.Run("core", "search", "--format", "json", "--additional-urls="+url.String())
 	require.NoError(t, err)
-	requirejson.Contains(t, stdout, `[{"id": "test:x86", "releases": { "3.0.0": {"name":"test_core"}}}]`)
-	// A platform could contain multiple releases, we get the length of how many releases are present for each platform
-	// and we sum them to see if the expected numers matches.
-	requirejson.Query(t, stdout, `[.[].releases | length] | add`, fmt.Sprint(numPlatforms))
+	requirejson.Contains(t, stdout, `[
+		{
+			"id": "test:x86",
+			"installed_version": "2.0.0",
+			"latest_version": "2.0.0",
+			"releases": {
+				"1.0.0": {"name":"test_core", "compatible": true},
+				"2.0.0": {"name":"test_core", "compatible": true},
+				"3.0.0": {"name":"test_core", "compatible": false}
+			}
+		}
+	]`)
+	requirejson.Len(t, stdout, numPlatforms)
 }
 
 func TestCoreUpdateIndexUrlNotFound(t *testing.T) {
@@ -705,17 +715,17 @@ func TestCoreSearchSortedResults(t *testing.T) {
 	for _, v := range lines {
 		if strings.HasPrefix(v[2], "[DEPRECATED]") {
 			deprecated = append(deprecated, v)
-		} else {
-			notDeprecated = append(notDeprecated, v)
+			continue
 		}
+		notDeprecated = append(notDeprecated, v)
 	}
 
 	// verify that results are already sorted correctly
 	require.True(t, sort.SliceIsSorted(deprecated, func(i, j int) bool {
-		return strings.ToLower(deprecated[i][2]) < strings.ToLower(deprecated[j][2])
+		return strings.ToLower(deprecated[i][0]) < strings.ToLower(deprecated[j][0])
 	}))
 	require.True(t, sort.SliceIsSorted(notDeprecated, func(i, j int) bool {
-		return strings.ToLower(notDeprecated[i][2]) < strings.ToLower(notDeprecated[j][2])
+		return strings.ToLower(notDeprecated[i][0]) < strings.ToLower(notDeprecated[j][0])
 	}))
 
 	// verify that deprecated platforms are the last ones
@@ -727,20 +737,20 @@ func TestCoreSearchSortedResults(t *testing.T) {
 
 	// verify that results are already sorted correctly
 	sortedDeprecated := requirejson.Parse(t, stdout).Query(
-		"[ .[] | select(.deprecated == true) | {name: .releases[.latest_version].name} | .name |=ascii_downcase | .name] | sort").String()
+		"[ .[] | select(.deprecated == true) | .id |=ascii_downcase | .id] | sort").String()
 	notSortedDeprecated := requirejson.Parse(t, stdout).Query(
-		"[ .[] | select(.deprecated == true) | {name: .releases[.latest_version].name} | .name |=ascii_downcase | .name]").String()
+		"[ .[] | select(.deprecated == true) | .id |=ascii_downcase | .id]").String()
 	require.Equal(t, sortedDeprecated, notSortedDeprecated)
 
 	sortedNotDeprecated := requirejson.Parse(t, stdout).Query(
-		"[ .[] | select(.deprecated != true) | {name: .releases[.latest_version].name} | .name |=ascii_downcase | .name] | sort").String()
+		"[ .[] | select(.deprecated != true) | .id |=ascii_downcase | .id] | sort").String()
 	notSortedNotDeprecated := requirejson.Parse(t, stdout).Query(
-		"[ .[] | select(.deprecated != true) | {name: .releases[.latest_version].name} | .name |=ascii_downcase | .name]").String()
+		"[ .[] | select(.deprecated != true) | .id |=ascii_downcase | .id]").String()
 	require.Equal(t, sortedNotDeprecated, notSortedNotDeprecated)
 
 	// verify that deprecated platforms are the last ones
 	platform := requirejson.Parse(t, stdout).Query(
-		"[ .[] | {name: .releases[.latest_version].name} | .name |=ascii_downcase | .name]").String()
+		"[ .[] | .id |=ascii_downcase | .id]").String()
 	require.Equal(t, platform, strings.TrimRight(notSortedNotDeprecated, "]")+","+strings.TrimLeft(notSortedDeprecated, "["))
 }
 
@@ -783,10 +793,10 @@ func TestCoreListSortedResults(t *testing.T) {
 
 	// verify that results are already sorted correctly
 	require.True(t, sort.SliceIsSorted(deprecated, func(i, j int) bool {
-		return strings.ToLower(deprecated[i][3]) < strings.ToLower(deprecated[j][3])
+		return strings.ToLower(deprecated[i][0]) < strings.ToLower(deprecated[j][0])
 	}))
 	require.True(t, sort.SliceIsSorted(notDeprecated, func(i, j int) bool {
-		return strings.ToLower(notDeprecated[i][3]) < strings.ToLower(notDeprecated[j][3])
+		return strings.ToLower(notDeprecated[i][0]) < strings.ToLower(notDeprecated[j][0])
 	}))
 
 	// verify that deprecated platforms are the last ones
@@ -799,20 +809,20 @@ func TestCoreListSortedResults(t *testing.T) {
 
 	// verify that results are already sorted correctly
 	sortedDeprecated := requirejson.Parse(t, stdout).Query(
-		"[ .[] | select(.deprecated == true) | {name: .releases[.latest_version].name} | .name |=ascii_downcase | .name] | sort").String()
+		"[ .[] | select(.deprecated == true) | .id |=ascii_downcase | .id] | sort").String()
 	notSortedDeprecated := requirejson.Parse(t, stdout).Query(
-		"[ .[] | select(.deprecated == true) | {name: .releases[.latest_version].name} | .name |=ascii_downcase | .name]").String()
+		"[ .[] | select(.deprecated == true) | .id |=ascii_downcase | .id]").String()
 	require.Equal(t, sortedDeprecated, notSortedDeprecated)
 
 	sortedNotDeprecated := requirejson.Parse(t, stdout).Query(
-		"[ .[] | select(.deprecated != true) | {name: .releases[.latest_version].name} | .name |=ascii_downcase | .name] | sort").String()
+		"[ .[] | select(.deprecated != true) | .id |=ascii_downcase | .id] | sort").String()
 	notSortedNotDeprecated := requirejson.Parse(t, stdout).Query(
-		"[ .[] | select(.deprecated != true) | {name: .releases[.latest_version].name} | .name |=ascii_downcase | .name]").String()
+		"[ .[] | select(.deprecated != true) | .id |=ascii_downcase | .id]").String()
 	require.Equal(t, sortedNotDeprecated, notSortedNotDeprecated)
 
 	// verify that deprecated platforms are the last ones
 	platform := requirejson.Parse(t, stdout).Query(
-		"[ .[] | {name: .releases[.latest_version].name} | .name |=ascii_downcase | .name]").String()
+		"[ .[] | .id |=ascii_downcase | .id]").String()
 	require.Equal(t, platform, strings.TrimRight(notSortedNotDeprecated, "]")+","+strings.TrimLeft(notSortedDeprecated, "["))
 }
 
@@ -1111,3 +1121,128 @@ func TestCoreListWhenNoPlatformAreInstalled(t *testing.T) {
 	require.NoError(t, err)
 	require.Equal(t, "No platforms installed.\n", string(stdout))
 }
+
+func TestCoreHavingIncompatibleDepTools(t *testing.T) {
+	env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t)
+	defer env.CleanUp()
+
+	url := env.HTTPServeFile(8000, paths.New("..", "testdata", "test_index.json")).String()
+	additionalURLs := "--additional-urls=" + url
+
+	_, _, err := cli.Run("core", "update-index", additionalURLs)
+	require.NoError(t, err)
+
+	// the `latest_version` must point to an installable release. In the releases field the latest entry, points to an incompatible version.
+	stdout, _, err := cli.Run("core", "list", "--all", "--format", "json", additionalURLs)
+	require.NoError(t, err)
+	requirejson.Parse(t, stdout).
+		Query(`.[] | select(.id == "foo_vendor:avr")`).
+		MustContain(`{
+			"installed_version": "",
+			"latest_version": "1.0.1",
+			"releases": {
+				"1.0.0": {"compatible": true},
+				"1.0.1": {"compatible": true},
+				"1.0.2": {"compatible": false}
+			}
+		}`)
+
+	// install latest compatible version
+	_, _, err = cli.Run("core", "install", "foo_vendor:avr", additionalURLs)
+	require.NoError(t, err)
+	stdout, _, err = cli.Run("core", "list", "--all", "--format", "json", additionalURLs)
+	require.NoError(t, err)
+	requirejson.Parse(t, stdout).
+		Query(`.[] | select(.id == "foo_vendor:avr")`).
+		MustContain(`{
+			"latest_version": "1.0.1",
+			"installed_version": "1.0.1",
+			"releases": {"1.0.1": {"compatible": true}}
+		}`)
+
+	// install a specific incompatible version
+	_, stderr, err := cli.Run("core", "install", "foo_vendor:avr@1.0.2", additionalURLs)
+	require.Error(t, err)
+	require.Contains(t, string(stderr), "no versions available for the current OS")
+
+	// install a specific compatible version
+	_, _, err = cli.Run("core", "install", "foo_vendor:avr@1.0.0", additionalURLs)
+	require.NoError(t, err)
+	stdout, _, err = cli.Run("core", "list", "--format", "json", additionalURLs)
+	require.NoError(t, err)
+	requirejson.Parse(t, stdout).
+		Query(`.[] | select(.id == "foo_vendor:avr")`).
+		MustContain(`{"installed_version": "1.0.0", "releases": {"1.0.0": {"compatible": true}}}`)
+
+	// Lists all updatable cores
+	stdout, _, err = cli.Run("core", "list", "--updatable", "--format", "json", additionalURLs)
+	require.NoError(t, err)
+	requirejson.Parse(t, stdout).
+		Query(`.[] | select(.id == "foo_vendor:avr")`).
+		MustContain(`{"latest_version": "1.0.1", "releases": {"1.0.1": {"compatible": true}}}`)
+
+	// Show outdated cores, must show latest compatible
+	stdout, _, err = cli.Run("outdated", "--format", "json", additionalURLs)
+	require.NoError(t, err)
+	requirejson.Parse(t, stdout).
+		Query(`.platforms | .[] | select(.id == "foo_vendor:avr")`).
+		MustContain(`{"latest_version": "1.0.1", "releases":{"1.0.1": {"compatible": true}}}`)
+
+	// upgrade to latest compatible (1.0.0 -> 1.0.1)
+	_, _, err = cli.Run("core", "upgrade", "foo_vendor:avr", "--format", "json", additionalURLs)
+	require.NoError(t, err)
+	stdout, _, err = cli.Run("core", "list", "--format", "json", additionalURLs)
+	require.NoError(t, err)
+	requirejson.Parse(t, stdout).
+		Query(`.[] | select(.id == "foo_vendor:avr") | .releases[.installed_version]`).
+		MustContain(`{"version": "1.0.1", "compatible": true}`)
+
+	// upgrade to latest incompatible not possible (1.0.1 -> 1.0.2)
+	_, _, err = cli.Run("core", "upgrade", "foo_vendor:avr", "--format", "json", additionalURLs)
+	require.NoError(t, err)
+	stdout, _, err = cli.Run("core", "list", "--format", "json", additionalURLs)
+	require.NoError(t, err)
+	requirejson.Query(t, stdout, `.[] | select(.id == "foo_vendor:avr") | .installed_version`, `"1.0.1"`)
+
+	// When no compatible version are found return error
+	// When trying to install a platform with no compatible version fails
+	_, stderr, err = cli.Run("core", "install", "incompatible_vendor:avr", additionalURLs)
+	require.Error(t, err)
+	require.Contains(t, string(stderr), "is not available for your OS")
+
+	// Core search
+	{
+		// core search with and without --all produces the same results.
+		stdoutSearchAll, _, err := cli.Run("core", "search", "--all", "--format", "json", additionalURLs)
+		require.NoError(t, err)
+		stdoutSearch, _, err := cli.Run("core", "search", "--format", "json", additionalURLs)
+		require.NoError(t, err)
+		require.Equal(t, stdoutSearchAll, stdoutSearch)
+		for _, stdout := range [][]byte{stdoutSearchAll, stdoutSearch} {
+			requirejson.Parse(t, stdout).
+				Query(`.[] | select(.id == "foo_vendor:avr")`).
+				MustContain(`{
+					"latest_version": "1.0.1",
+					"releases": {
+						"1.0.0": {"compatible": true},
+						"1.0.1": {"compatible": true},
+						"1.0.2": {"compatible": false}
+					}
+				}`)
+			requirejson.Parse(t, stdout).
+				Query(`.[] | select(.id == "incompatible_vendor:avr")`).
+				MustContain(`{"latest_version": "", "releases": { "1.0.0": {"compatible": false}}}`)
+		}
+		// In text mode, core search shows `n/a` for core that doesn't have any compatible version
+		stdout, _, err := cli.Run("core", "search", additionalURLs)
+		require.NoError(t, err)
+		var lines [][]string
+		for _, v := range strings.Split(strings.TrimSpace(string(stdout)), "\n") {
+			lines = append(lines, strings.Fields(strings.TrimSpace(v)))
+			if strings.Contains(v, "incompatible_vendor:avr") {
+				t.Log(strings.Fields(strings.TrimSpace(v)))
+			}
+		}
+		require.Contains(t, lines, []string{"incompatible_vendor:avr", "n/a", "Incompatible", "Boards"})
+	}
+}
diff --git a/internal/integrationtest/testdata/test_index.json b/internal/integrationtest/testdata/test_index.json
index 70de2ac0fee..95d38d202d4 100644
--- a/internal/integrationtest/testdata/test_index.json
+++ b/internal/integrationtest/testdata/test_index.json
@@ -236,6 +236,174 @@
           ]
         }
       ]
+    },
+    {
+      "name": "foo_vendor",
+      "maintainer": "Foo Developer",
+      "websiteURL": "http://example.com",
+      "email": "test@example.com",
+      "help": {
+        "online": "http://example.com"
+      },
+      "platforms": [
+        {
+          "name": "Foo Boards",
+          "architecture": "avr",
+          "version": "1.0.0",
+          "category": "Contributed",
+          "help": {
+            "online": "http://example.com"
+          },
+          "url": "https://github.com/damellis/attiny/archive/702aa287455f7e052cf94fd4949398fec0ef21b8.zip",
+          "archiveFileName": "702aa287455f7e052cf94fd4949398fec0ef21b8.zip",
+          "checksum": "SHA-256:bfffa4a700e42ae993895f5eea22bc369ba5ac3ea36eca18ac5f72a05bb60ab5",
+          "size": "5005",
+          "boards": [],
+          "toolsDependencies": [
+            {
+              "packager": "foo_vendor",
+              "name": "some_tool",
+              "version": "1.0.0"
+            }
+          ]
+        },
+        {
+          "name": "Foo Boards",
+          "architecture": "avr",
+          "version": "1.0.1",
+          "category": "Contributed",
+          "help": {
+            "online": "http://example.com"
+          },
+          "url": "https://github.com/damellis/attiny/archive/76ca88ce3c195fcba8e8a645084e352965dc80e0.zip",
+          "archiveFileName": "76ca88ce3c195fcba8e8a645084e352965dc80e0.zip",
+          "checksum": "SHA-256:49a4dfc3796caf2533050b0b962ae0affb2471b8ded1283936d7b712cc1fdff1",
+          "size": "5719",
+          "boards": [],
+          "toolsDependencies": [
+            {
+              "packager": "foo_vendor",
+              "name": "some_tool",
+              "version": "1.0.0"
+            }
+          ]
+        },
+        {
+          "name": "Foo Boards",
+          "architecture": "avr",
+          "version": "1.0.2",
+          "category": "Contributed",
+          "help": {
+            "online": "http://example.com"
+          },
+          "url": "https://github.com/damellis/attiny/archive/76ca88ce3c195fcba8e8a645084e352965dc80e0.zip",
+          "archiveFileName": "76ca88ce3c195fcba8e8a645084e352965dc80e0.zip",
+          "checksum": "SHA-256:49a4dfc3796caf2533050b0b962ae0affb2471b8ded1283936d7b712cc1fdff1",
+          "size": "5719",
+          "boards": [],
+          "toolsDependencies": [
+            {
+              "packager": "foo_vendor",
+              "name": "incompatible_tool",
+              "version": "2.0.0"
+            }
+          ]
+        }
+      ],
+      "tools": [
+        {
+          "name": "some_tool",
+          "version": "1.0.0",
+          "systems": [
+            {
+              "size": "219631",
+              "checksum": "SHA-256:2a8e68c5d803aa6f902ef219f177ec3a4c28275d85cbe272962ad2cd374f50d1",
+              "host": "arm-linux-gnueabihf",
+              "archiveFileName": "avrdude-6.3.0-arduino17-armhf-pc-linux-gnu.tar.bz2",
+              "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino17-armhf-pc-linux-gnu.tar.bz2"
+            },
+            {
+              "size": "229852",
+              "checksum": "SHA-256:6cf948f751acfe7b96684537f2291c766ec8b54b4f7dc95539864821456fa9fc",
+              "host": "aarch64-linux-gnu",
+              "archiveFileName": "avrdude-6.3.0-arduino17-aarch64-pc-linux-gnu.tar.bz2",
+              "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino17-aarch64-pc-linux-gnu.tar.bz2"
+            },
+            {
+              "size": "279045",
+              "checksum": "SHA-256:120cc9edaae699e7e9ac50b1b8eb0e7d51fdfa555bac54233c2511e6ee5418c9",
+              "host": "x86_64-apple-darwin12",
+              "archiveFileName": "avrdude-6.3.0-arduino17-x86_64-apple-darwin12.tar.bz2",
+              "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino17-x86_64-apple-darwin12.tar.bz2"
+            },
+            {
+              "size": "254271",
+              "checksum": "SHA-256:accdfb920af2aabf4f7461d2ac73c0751760f525216dc4e7657427a78c60d13d",
+              "host": "x86_64-linux-gnu",
+              "archiveFileName": "avrdude-6.3.0-arduino17-x86_64-pc-linux-gnu.tar.bz2",
+              "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino17-x86_64-pc-linux-gnu.tar.bz2"
+            },
+            {
+              "size": "244550",
+              "checksum": "SHA-256:5c8cc6c17db9300e1451fe41cd7178b0442b4490ee6fdbc0aed9811aef96c05f",
+              "host": "i686-linux-gnu",
+              "archiveFileName": "avrdude-6.3.0-arduino17-i686-pc-linux-gnu.tar.bz2",
+              "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino17-i686-pc-linux-gnu.tar.bz2"
+            },
+            {
+              "size": "328460",
+              "checksum": "SHA-256:e99188873c7c5ad8f8f906f068c33600e758b2e36cce3adbd518a21bd266749d",
+              "host": "i686-mingw32",
+              "archiveFileName": "avrdude-6.3.0-arduino17-i686-w64-mingw32.zip",
+              "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino17-i686-w64-mingw32.zip"
+            }
+          ]
+        },
+        {
+          "name": "incompatible_tool",
+          "version": "2.0.0",
+          "systems": []
+        }
+      ]
+    },
+    {
+      "name": "incompatible_vendor",
+      "maintainer": "Incompatible Developer",
+      "websiteURL": "http://example.com",
+      "email": "test@example.com",
+      "help": {
+        "online": "http://example.com"
+      },
+      "platforms": [
+        {
+          "name": "Incompatible Boards",
+          "architecture": "avr",
+          "version": "1.0.0",
+          "category": "Contributed",
+          "help": {
+            "online": "http://example.com"
+          },
+          "url": "https://github.com/damellis/attiny/archive/702aa287455f7e052cf94fd4949398fec0ef21b8.zip",
+          "archiveFileName": "702aa287455f7e052cf94fd4949398fec0ef21b8.zip",
+          "checksum": "SHA-256:bfffa4a700e42ae993895f5eea22bc369ba5ac3ea36eca18ac5f72a05bb60ab5",
+          "size": "5005",
+          "boards": [],
+          "toolsDependencies": [
+            {
+              "packager": "incompatible_vendor",
+              "name": "incompatible_tool",
+              "version": "2.0.0"
+            }
+          ]
+        }
+      ],
+      "tools": [
+        {
+          "name": "incompatible_tool",
+          "version": "2.0.0",
+          "systems": []
+        }
+      ]
     }
   ]
 }
diff --git a/rpc/cc/arduino/cli/commands/v1/common.pb.go b/rpc/cc/arduino/cli/commands/v1/common.pb.go
index fe1f4e1f700..28bc1b6ed68 100644
--- a/rpc/cc/arduino/cli/commands/v1/common.pb.go
+++ b/rpc/cc/arduino/cli/commands/v1/common.pb.go
@@ -560,7 +560,8 @@ type PlatformSummary struct {
 	Releases map[string]*PlatformRelease `protobuf:"bytes,2,rep,name=releases,proto3" json:"releases,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
 	// The installed version of the platform, or empty string if none installed
 	InstalledVersion string `protobuf:"bytes,3,opt,name=installed_version,json=installedVersion,proto3" json:"installed_version,omitempty"`
-	// The latest available version of the platform, or empty if none available
+	// The latest available version of the platform that can be installable, or
+	// empty if none available.
 	LatestVersion string `protobuf:"bytes,4,opt,name=latest_version,json=latestVersion,proto3" json:"latest_version,omitempty"`
 }
 
@@ -761,6 +762,9 @@ type PlatformRelease struct {
 	MissingMetadata bool `protobuf:"varint,7,opt,name=missing_metadata,json=missingMetadata,proto3" json:"missing_metadata,omitempty"`
 	// True this release is deprecated
 	Deprecated bool `protobuf:"varint,8,opt,name=deprecated,proto3" json:"deprecated,omitempty"`
+	// True if the platform dependencies are available for the current OS/ARCH.
+	// This also means that the platform is installable.
+	Compatible bool `protobuf:"varint,9,opt,name=compatible,proto3" json:"compatible,omitempty"`
 }
 
 func (x *PlatformRelease) Reset() {
@@ -851,6 +855,13 @@ func (x *PlatformRelease) GetDeprecated() bool {
 	return false
 }
 
+func (x *PlatformRelease) GetCompatible() bool {
+	if x != nil {
+		return x.Compatible
+	}
+	return false
+}
+
 type InstalledPlatformReference struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
@@ -1188,7 +1199,7 @@ var file_cc_arduino_cli_commands_v1_common_proto_rawDesc = []byte{
 	0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28,
 	0x08, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x18, 0x0a,
 	0x07, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07,
-	0x69, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x22, 0xb6, 0x02, 0x0a, 0x0f, 0x50, 0x6c, 0x61, 0x74,
+	0x69, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x22, 0xd6, 0x02, 0x0a, 0x0f, 0x50, 0x6c, 0x61, 0x74,
 	0x66, 0x6f, 0x72, 0x6d, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e,
 	0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,
 	0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
@@ -1208,6 +1219,8 @@ var file_cc_arduino_cli_commands_v1_common_proto_rawDesc = []byte{
 	0x0f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
 	0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x08,
 	0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64,
+	0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x18, 0x09,
+	0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x6c, 0x65,
 	0x22, 0x88, 0x01, 0x0a, 0x1a, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x50, 0x6c,
 	0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12,
 	0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12,
diff --git a/rpc/cc/arduino/cli/commands/v1/common.proto b/rpc/cc/arduino/cli/commands/v1/common.proto
index fae80bab09b..9a324985d54 100644
--- a/rpc/cc/arduino/cli/commands/v1/common.proto
+++ b/rpc/cc/arduino/cli/commands/v1/common.proto
@@ -89,7 +89,8 @@ message PlatformSummary {
   map<string, PlatformRelease> releases = 2;
   // The installed version of the platform, or empty string if none installed
   string installed_version = 3;
-  // The latest available version of the platform, or empty if none available
+  // The latest available version of the platform that can be installable, or
+  // empty if none available.
   string latest_version = 4;
 }
 
@@ -141,6 +142,9 @@ message PlatformRelease {
   bool missing_metadata = 7;
   // True this release is deprecated
   bool deprecated = 8;
+  // True if the platform dependencies are available for the current OS/ARCH.
+  // This also means that the platform is installable.
+  bool compatible = 9;
 }
 
 message InstalledPlatformReference {
diff --git a/rpc/cc/arduino/cli/commands/v1/core.pb.go b/rpc/cc/arduino/cli/commands/v1/core.pb.go
index dca289c80fd..6c3bcb7c5ed 100644
--- a/rpc/cc/arduino/cli/commands/v1/core.pb.go
+++ b/rpc/cc/arduino/cli/commands/v1/core.pb.go
@@ -682,12 +682,9 @@ type PlatformSearchRequest struct {
 	Instance *Instance `protobuf:"bytes,1,opt,name=instance,proto3" json:"instance,omitempty"`
 	// Keywords for the search.
 	SearchArgs string `protobuf:"bytes,2,opt,name=search_args,json=searchArgs,proto3" json:"search_args,omitempty"`
-	// Whether to show all available versions. `false` causes only the newest
-	// versions of the cores to be listed in the search results.
-	AllVersions bool `protobuf:"varint,3,opt,name=all_versions,json=allVersions,proto3" json:"all_versions,omitempty"`
 	// Whether to show manually installed platforms. `false` causes to skip
 	// manually installed platforms.
-	ManuallyInstalled bool `protobuf:"varint,4,opt,name=manually_installed,json=manuallyInstalled,proto3" json:"manually_installed,omitempty"`
+	ManuallyInstalled bool `protobuf:"varint,3,opt,name=manually_installed,json=manuallyInstalled,proto3" json:"manually_installed,omitempty"`
 }
 
 func (x *PlatformSearchRequest) Reset() {
@@ -736,13 +733,6 @@ func (x *PlatformSearchRequest) GetSearchArgs() string {
 	return ""
 }
 
-func (x *PlatformSearchRequest) GetAllVersions() bool {
-	if x != nil {
-		return x.AllVersions
-	}
-	return false
-}
-
 func (x *PlatformSearchRequest) GetManuallyInstalled() bool {
 	if x != nil {
 		return x.ManuallyInstalled
@@ -913,7 +903,7 @@ var file_cc_arduino_cli_commands_v1_core_proto_rawDesc = []byte{
 	0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e,
 	0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63,
 	0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66,
-	0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x22, 0xcc, 0x01,
+	0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x22, 0xa9, 0x01,
 	0x0a, 0x15, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68,
 	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61,
 	0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x63, 0x2e, 0x61,
@@ -921,24 +911,22 @@ var file_cc_arduino_cli_commands_v1_core_proto_rawDesc = []byte{
 	0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52,
 	0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x61,
 	0x72, 0x63, 0x68, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a,
-	0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x41, 0x72, 0x67, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x6c,
-	0x6c, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08,
-	0x52, 0x0b, 0x61, 0x6c, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2d, 0x0a,
-	0x12, 0x6d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c,
-	0x6c, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x6d, 0x61, 0x6e, 0x75, 0x61,
-	0x6c, 0x6c, 0x79, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x22, 0x6a, 0x0a, 0x16,
-	0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65,
-	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x0d, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68,
-	0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e,
-	0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63,
-	0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66,
-	0x6f, 0x72, 0x6d, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x0c, 0x73, 0x65, 0x61, 0x72,
-	0x63, 0x68, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x42, 0x48, 0x5a, 0x46, 0x67, 0x69, 0x74, 0x68,
-	0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2f, 0x61,
-	0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2d, 0x63, 0x6c, 0x69, 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x63,
-	0x63, 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2f, 0x63, 0x6c, 0x69, 0x2f, 0x63, 0x6f,
-	0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2f, 0x76, 0x31, 0x3b, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
-	0x64, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x41, 0x72, 0x67, 0x73, 0x12, 0x2d, 0x0a, 0x12, 0x6d, 0x61,
+	0x6e, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64,
+	0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x6d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x6c, 0x79,
+	0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x22, 0x6a, 0x0a, 0x16, 0x50, 0x6c, 0x61,
+	0x74, 0x66, 0x6f, 0x72, 0x6d, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x0d, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x6f, 0x75,
+	0x74, 0x70, 0x75, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x63, 0x63, 0x2e,
+	0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d,
+	0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d,
+	0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x0c, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x4f,
+	0x75, 0x74, 0x70, 0x75, 0x74, 0x42, 0x48, 0x5a, 0x46, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
+	0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2f, 0x61, 0x72, 0x64, 0x75,
+	0x69, 0x6e, 0x6f, 0x2d, 0x63, 0x6c, 0x69, 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x63, 0x63, 0x2f, 0x61,
+	0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2f, 0x63, 0x6c, 0x69, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61,
+	0x6e, 0x64, 0x73, 0x2f, 0x76, 0x31, 0x3b, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x62,
+	0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
diff --git a/rpc/cc/arduino/cli/commands/v1/core.proto b/rpc/cc/arduino/cli/commands/v1/core.proto
index 67aa0b214c7..e44331dada8 100644
--- a/rpc/cc/arduino/cli/commands/v1/core.proto
+++ b/rpc/cc/arduino/cli/commands/v1/core.proto
@@ -115,12 +115,9 @@ message PlatformSearchRequest {
   Instance instance = 1;
   // Keywords for the search.
   string search_args = 2;
-  // Whether to show all available versions. `false` causes only the newest
-  // versions of the cores to be listed in the search results.
-  bool all_versions = 3;
   // Whether to show manually installed platforms. `false` causes to skip
   // manually installed platforms.
-  bool manually_installed = 4;
+  bool manually_installed = 3;
 }
 
 message PlatformSearchResponse {