MCPcopy Create free account
hub / github.com/bytebase/bytebase / elicitDatabaseChoice

Method elicitDatabaseChoice

backend/api/mcp/tool_resolve.go:203–255  ·  view source on GitHub ↗

elicitDatabaseChoice prompts the user to pick from ambiguous database matches using MCP elicitation. Returns an error if elicitation is unsupported, the user cancels/declines, or the selection is invalid.

(ctx context.Context, req *mcp.CallToolRequest, resolved *resolvedDatabase)

Source from the content-addressed store, hash-verified

201// using MCP elicitation. Returns an error if elicitation is unsupported, the user
202// cancels/declines, or the selection is invalid.
203func (*Server) elicitDatabaseChoice(ctx context.Context, req *mcp.CallToolRequest, resolved *resolvedDatabase) (*resolvedDatabase, error) {
204 if req == nil || req.Session == nil {
205 return nil, errors.New("elicitation unsupported: no session")
206 }
207
208 // Build enum values and a lookup map from display label to resource name.
209 enumValues := make([]any, 0, len(resolved.candidates))
210 resourceByLabel := make(map[string]string, len(resolved.candidates))
211 for _, c := range resolved.candidates {
212 label := fmt.Sprintf("%s (%s, %s)", c.Database, c.Instance, c.Engine)
213 enumValues = append(enumValues, label)
214 resourceByLabel[label] = c.Database
215 }
216
217 result, err := req.Session.Elicit(ctx, &mcp.ElicitParams{
218 Mode: "form",
219 Message: "Multiple databases match. Which one do you want to query?",
220 RequestedSchema: map[string]any{
221 "type": "object",
222 "properties": map[string]any{
223 "database": map[string]any{
224 "type": "string",
225 "enum": enumValues,
226 "description": "Select the target database",
227 },
228 },
229 "required": []string{"database"},
230 },
231 })
232 if err != nil {
233 return nil, err
234 }
235 if result.Action != "accept" {
236 return nil, errors.Errorf("user %sd database selection", result.Action)
237 }
238
239 selected, ok := result.Content["database"].(string)
240 if !ok {
241 return nil, errors.New("invalid database selection")
242 }
243
244 resourceName, ok := resourceByLabel[selected]
245 if !ok {
246 return nil, errors.Errorf("unknown database selection: %s", selected)
247 }
248
249 return &resolvedDatabase{
250 resourceName: resourceName,
251 dataSourceID: resolved.dataSourceIDs[resourceName],
252 engine: resolved.engines[resourceName],
253 project: resolved.projects[resourceName],
254 }, nil
255}
256
257// matchExact returns databases whose short name exactly matches the input.
258func matchExact(databases []databaseEntry, name string) []databaseEntry {

Callers 3

handleQueryDatabaseMethod · 0.95
resolveChangeTargetMethod · 0.95
resolveSchemaTargetMethod · 0.95

Calls 1

ErrorfMethod · 0.80

Tested by

no test coverage detected