package tools import ( "context" "fmt" "strings" "github.com/google/uuid" "github.com/jackc/pgx/v5" "github.com/modelcontextprotocol/go-sdk/mcp" "git.warky.dev/wdevs/amcs/internal/session" "git.warky.dev/wdevs/amcs/internal/store" thoughttypes "git.warky.dev/wdevs/amcs/internal/types" ) func parseUUID(id string) (uuid.UUID, error) { parsed, err := uuid.Parse(strings.TrimSpace(id)) if err != nil { return uuid.Nil, fmt.Errorf("invalid id %q: %w", id, err) } return parsed, nil } func sessionID(req *mcp.CallToolRequest) (string, error) { if req == nil || req.Session == nil || req.Session.ID() == "" { return "", fmt.Errorf("tool requires an MCP session") } return req.Session.ID(), nil } func resolveProject(ctx context.Context, db *store.DB, sessions *session.ActiveProjects, req *mcp.CallToolRequest, raw string, required bool) (*thoughttypes.Project, error) { projectRef := strings.TrimSpace(raw) if projectRef == "" && sessions != nil && req != nil && req.Session != nil { if activeID, ok := sessions.Get(req.Session.ID()); ok { project, err := db.GetProject(ctx, activeID.String()) if err == nil { return &project, nil } if err != pgx.ErrNoRows { return nil, err } } } if projectRef == "" { if required { return nil, fmt.Errorf("project is required") } return nil, nil } project, err := db.GetProject(ctx, projectRef) if err != nil { if err == pgx.ErrNoRows { return nil, fmt.Errorf("project %q not found", projectRef) } return nil, err } return &project, nil } func formatContextBlock(header string, lines []string) string { if len(lines) == 0 { return header + "\n\nNo matching thoughts." } return header + "\n\n" + strings.Join(lines, "\n\n") } func thoughtContextLine(index int, content string, metadata thoughttypes.ThoughtMetadata, similarity float64) string { label := fmt.Sprintf("%d. %s", index+1, strings.TrimSpace(content)) parts := make([]string, 0, 3) if len(metadata.Topics) > 0 { parts = append(parts, "topics="+strings.Join(metadata.Topics, ", ")) } if metadata.Type != "" { parts = append(parts, "type="+metadata.Type) } if similarity > 0 { parts = append(parts, fmt.Sprintf("similarity=%.3f", similarity)) } if len(parts) == 0 { return label } return label + "\n[" + strings.Join(parts, " | ") + "]" }