@@ -122,27 +122,9 @@ func (c *AddCmd) run(cmd *cobra.Command, args []string) error {
122
122
return fmt .Errorf ("⚠️ Failed to get package '%s@%s' from registry: %w" , name , c .Version , err )
123
123
}
124
124
125
- requestedTools , err := filter . MatchRequestedSlice (c .Tools , pkg .Tools )
125
+ entry , err := parseServerEntry ( pkg , runtime . Runtime (c .Runtime ), c .Tools , c . MCPDSupportedRuntimes () )
126
126
if err != nil {
127
- return fmt .Errorf ("error matching requested tools: %w" , err )
128
- }
129
-
130
- selectedRuntime , runtimeErr := c .runtime (pkg )
131
- if runtimeErr != nil {
132
- return runtimeErr
133
- }
134
-
135
- version := "latest"
136
- if pkg .Version != "" {
137
- version = pkg .Version
138
- }
139
-
140
- runtimePackageVersion := fmt .Sprintf ("%s::%s@%s" , selectedRuntime , pkg .Name , version )
141
-
142
- entry := config.ServerEntry {
143
- Name : pkg .ID ,
144
- Package : runtimePackageVersion ,
145
- Tools : requestedTools ,
127
+ return fmt .Errorf ("error parsing server entry: %w" , err )
146
128
}
147
129
148
130
cfg , err := c .cfgLoader .Load (flags .ConfigFile )
@@ -160,41 +142,94 @@ func (c *AddCmd) run(cmd *cobra.Command, args []string) error {
160
142
cmd .OutOrStdout (),
161
143
"✓ Added server '%s' (version: %s), tools: %s\n " ,
162
144
name ,
163
- version ,
164
- strings .Join (requestedTools , ", " ),
145
+ entry . PackageVersion () ,
146
+ strings .Join (entry . Tools , ", " ),
165
147
)
166
148
if err != nil {
167
149
return err
168
150
}
169
- logger .Debug ("Server added" , "name" , name , "version" , version , "tools" , requestedTools )
151
+ logger .Debug ("Server added" , "name" , name , "version" , entry . PackageVersion () , "tools" , entry . Tools )
170
152
171
153
// Print the package info.
172
154
if err = c .packagePrinter .PrintPackage (pkg ); err != nil {
173
155
return err
174
156
}
175
157
158
+ _ , err = fmt .Fprintln (cmd .OutOrStdout ())
159
+ if err != nil {
160
+ return err
161
+ }
162
+
176
163
return nil
177
164
}
178
165
179
- func (c * AddCmd ) runtime (pkg packages.Package ) (runtime.Runtime , error ) {
180
- // TODO: Sort out preference for runtimes
181
- var selectedRuntime runtime.Runtime
182
- supportedRuntimes := runtime .DefaultSupportedRuntimes ()
183
- for k , v := range pkg .InstallationDetails {
184
- if _ , ok := supportedRuntimes [k ]; ok {
185
- // We'll always end up with a supported runtime,
186
- // and hopefully one of them is the recommended installation.
187
- selectedRuntime = k
188
- if v .Recommended {
189
- break
190
- }
166
+ // selectRuntime returns the most appropriate runtime from a set of installations,
167
+ // given a list of supported runtimes in priority order.
168
+ //
169
+ // It first searches for any supported runtime marked as `Recommended` and returns the first such match.
170
+ // If none are recommended, it returns the first matched runtime from the `supported` list.
171
+ //
172
+ // Returns an error if no supported runtime is found.
173
+ func selectRuntime (
174
+ installations map [runtime.Runtime ]packages.Installation ,
175
+ requestedRuntime runtime.Runtime ,
176
+ supported []runtime.Runtime ,
177
+ ) (runtime.Runtime , error ) {
178
+ // Try to select the recommended runtime if present.
179
+ for _ , rt := range supported {
180
+ if requestedRuntime != "" && rt != requestedRuntime {
181
+ continue
182
+ }
183
+ if inst , ok := installations [rt ]; ok && inst .Recommended {
184
+ return rt , nil
191
185
}
192
186
}
193
- // We shouldn't end up in this situation, but just in case.
194
- if selectedRuntime == "" {
195
- return "" , fmt .Errorf ("no supported runtimes found for '%s'" , pkg .Name )
187
+
188
+ // Fall back to the first supported runtime by priority.
189
+ for _ , rt := range supported {
190
+ if requestedRuntime != "" && rt != requestedRuntime {
191
+ continue
192
+ }
193
+ if _ , ok := installations [rt ]; ok {
194
+ return rt , nil
195
+ }
196
+ }
197
+
198
+ return "" , fmt .Errorf ("no supported runtimes found" )
199
+ }
200
+
201
+ func parseServerEntry (
202
+ pkg packages.Package ,
203
+ requestedRuntime runtime.Runtime ,
204
+ requestedTools []string ,
205
+ supportedRuntimes []runtime.Runtime ,
206
+ ) (config.ServerEntry , error ) {
207
+ requestedTools , err := filter .MatchRequestedSlice (requestedTools , pkg .Tools )
208
+ if err != nil {
209
+ return config.ServerEntry {}, fmt .Errorf ("error matching requested tools: %w" , err )
210
+ }
211
+
212
+ selectedRuntime , runtimeErr := selectRuntime (pkg .InstallationDetails , requestedRuntime , supportedRuntimes )
213
+ if runtimeErr != nil {
214
+ return config.ServerEntry {}, fmt .Errorf ("error selecting runtime from available installations: %w" , runtimeErr )
196
215
}
197
- return selectedRuntime , nil
216
+
217
+ v := "latest"
218
+ if pkg .Version != "" {
219
+ v = pkg .Version
220
+ }
221
+
222
+ runtimeSpecificName := pkg .InstallationDetails [selectedRuntime ].Package
223
+ if runtimeSpecificName == "" {
224
+ return config.ServerEntry {}, fmt .Errorf ("installation package name is missing for runtime '%s'" , selectedRuntime )
225
+ }
226
+ runtimePackageVersion := fmt .Sprintf ("%s::%s@%s" , selectedRuntime , runtimeSpecificName , v )
227
+
228
+ return config.ServerEntry {
229
+ Name : pkg .ID ,
230
+ Package : runtimePackageVersion ,
231
+ Tools : requestedTools ,
232
+ }, nil
198
233
}
199
234
200
235
func (c * AddCmd ) options () []regopts.ResolveOption {
0 commit comments