MCPcopy
hub / github.com/apache/answer / MCPSemanticSearchHandler

Method MCPSemanticSearchHandler

internal/controller/mcp_controller.go:358–484  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

356}
357
358func (c *MCPController) MCPSemanticSearchHandler() func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
359 return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
360 if err := c.ensureMCPEnabled(ctx); err != nil {
361 return nil, err
362 }
363 cond := schema.NewMCPSemanticSearchCond(request)
364 if len(cond.Query) == 0 {
365 return mcp.NewToolResultText("Query is required for semantic search."), nil
366 }
367
368 siteGeneral, err := c.siteInfoService.GetSiteGeneral(ctx)
369 if err != nil {
370 log.Errorf("get site general info failed: %v", err)
371 return nil, err
372 }
373
374 results, err := c.embeddingService.SearchSimilar(ctx, cond.Query, cond.TopK)
375 if err != nil {
376 log.Errorf("semantic search failed: %v", err)
377 return mcp.NewToolResultText("Semantic search is not available. Embedding may not be configured."), nil
378 }
379 if len(results) == 0 {
380 return mcp.NewToolResultText("No semantically similar content found."), nil
381 }
382
383 resp := make([]*schema.MCPSemanticSearchResp, 0, len(results))
384 for _, r := range results {
385 var meta plugin.VectorSearchMetadata
386 _ = json.Unmarshal([]byte(r.Metadata), &meta)
387
388 item := &schema.MCPSemanticSearchResp{
389 ObjectID: r.ObjectID,
390 ObjectType: r.ObjectType,
391 Score: r.Score,
392 }
393
394 // Compose link from metadata
395 if r.ObjectType == "answer" && meta.AnswerID != "" {
396 item.Link = fmt.Sprintf("%s/questions/%s/%s", siteGeneral.SiteUrl, meta.QuestionID, meta.AnswerID)
397 } else {
398 item.Link = fmt.Sprintf("%s/questions/%s", siteGeneral.SiteUrl, meta.QuestionID)
399 }
400
401 // Query content from DB using IDs stored in metadata
402 if r.ObjectType == "question" {
403 question, qErr := c.questioncommon.Info(ctx, meta.QuestionID, "")
404 if qErr != nil {
405 log.Warnf("get question %s for semantic search failed: %v", meta.QuestionID, qErr)
406 } else {
407 item.Title = question.Title
408 item.Content = question.Content
409 }
410
411 // Fetch answers by ID from metadata
412 for _, a := range meta.Answers {
413 answerEntity, exist, aErr := c.answerRepo.GetAnswer(ctx, a.AnswerID)
414 if aErr != nil || !exist {
415 continue

Callers 1

callMCPToolMethod · 0.80

Calls 7

ensureMCPEnabledMethod · 0.95
NewMCPSemanticSearchCondFunction · 0.92
GetSiteGeneralMethod · 0.65
SearchSimilarMethod · 0.65
InfoMethod · 0.65
GetAnswerMethod · 0.65
GetCommentMethod · 0.65

Tested by

no test coverage detected