Skip to main content
Glama

part.search

Search UI components like buttons, cards, and links using text queries with hybrid semantic and full-text search. Filter results by component type and search mode to find design elements.

Instructions

UIコンポーネントパーツ(ボタン、カード、リンク等)をセマンティック検索します。テキストクエリ(e5-base + full-text)によるハイブリッド検索を提供。partType(16種類)やsearchMode(visual/text/hybrid)でフィルタリング可能です。 / Search UI component parts (buttons, cards, links, etc.) by text query. Provides hybrid search via e5-base + full-text. Filterable by partType (16 types) and searchMode (visual/text/hybrid).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryNoテキスト検索クエリ(1-500文字) / Text search query (1-500 chars)
image_urlNo画像URLによるビジュアル検索(将来対応予定) / Visual search by image URL (future support)
part_typeNoパーツタイプでフィルター(16種類) / Filter by part type (16 types)
web_page_idNoWebページIDでフィルター / Filter by web page ID
limitNo取得件数(1-100、デフォルト: 20) / Result limit (1-100, default: 20)
offsetNoオフセット(0以上、デフォルト: 0) / Offset (0+, default: 0)
search_modeNo検索モード(デフォルト: hybrid) / Search mode (default: hybrid)hybrid
min_similarityNo最小類似度閾値(0-1、デフォルト: 0.3) / Min similarity threshold (0-1, default: 0.3)

Implementation Reference

  • The main handler function for the part.search MCP tool, responsible for input validation, calling the search service, and formatting the response.
    export async function partSearchHandler(input: unknown): Promise<PartSearchOutput> {
      const startTime = Date.now();
    
      if (isDevelopment()) {
        logger.info("[MCP Tool] part.search called", {
          query: (input as Record<string, unknown>)?.query,
          image_url: (input as Record<string, unknown>)?.image_url ? "(provided)" : undefined,
        });
      }
    
      // 入力バリデーション / Input validation
      let validated: PartSearchInput;
      try {
        validated = partSearchInputSchema.parse(input);
      } catch (error) {
        if (error instanceof ZodError) {
          const errorMessage = error.errors.map((e) => `${e.path.join(".")}: ${e.message}`).join(", ");
    
          logger.warn("[MCP Tool] part.search validation error", {
            errors: error.errors,
          });
    
          return {
            success: false,
            error: {
              code: PART_SEARCH_ERROR_CODES.VALIDATION_ERROR,
              message: `Validation error: ${errorMessage}`,
            },
          };
        }
        throw error;
      }
    
      // サービス取得 / Get service
      let searchService: ReturnType<typeof getPartSearchService>;
      try {
        searchService = getPartSearchService();
      } catch {
        return {
          success: false,
          error: {
            code: PART_SEARCH_ERROR_CODES.SERVICE_UNAVAILABLE,
            message: "Part search service is not available",
          },
        };
      }
    
      try {
        // 検索オプション構築 / Build search options
        // exactOptionalPropertyTypes: undefinedを明示的に渡さない
        const options: PartSearchOptions = {
          limit: validated.limit,
          offset: validated.offset,
          minSimilarity: validated.min_similarity,
          searchMode: validated.search_mode,
        };
        if (validated.part_type) {
          options.partType = validated.part_type;
        }
    
        // WebページIDフィルタはPartSearchOptionsにないため、
        // 将来的な拡張ポイントとして保持
        // webPageId filter is not in PartSearchOptions yet,
        // kept as future extension point
    
        let result: PartSearchResult;
    
        if (validated.search_mode === "visual" && validated.image_url) {
          // ビジュアル検索: imageUrlをreferencePartIdとして使用できるか確認
          // 現在の実装は referencePartId(既存パーツID)のみ対応
          // Visual search: currently only supports referencePartId (existing part ID)
          // imageUrl direct search is a future extension
          return {
            success: false,
            error: {
              code: PART_SEARCH_ERROR_CODES.VALIDATION_ERROR,
              message:
                "Visual search by imageUrl is not yet supported. Use text or hybrid mode, or provide an existing part ID via part.inspect + visual search.",
            },
          };
        }
    
        if (validated.query) {
          // テキストまたはハイブリッド検索 / Text or hybrid search
          const embedding = await searchService.generateQueryEmbedding(validated.query);
    
          if (embedding && validated.search_mode !== "text") {
            // ハイブリッド検索: ベクトル + 全文検索 / Hybrid: vector + fulltext
            result = await searchService.searchPartsHybrid(validated.query, embedding, options);
          } else if (embedding) {
            // テキストベクトル検索のみ / Text vector search only
            result = await searchService.searchParts(embedding, options);
          } else {
            // Embedding生成失敗 / Embedding generation failed
            if (isDevelopment()) {
              logger.warn(
                "[MCP Tool] part.search: embedding generation failed, returning empty results"
              );
            }
    
            return {
              success: true,
              data: {
                results: [],
                total: 0,
                query: { text: validated.query },
                searchTimeMs: Date.now() - startTime,
              },
            };
          }
        } else {
          // queryもimageUrlもない場合(Zodの.refineで防がれるはず)
          // Neither query nor imageUrl (should be prevented by Zod .refine())
          return {
            success: true,
            data: {
              results: [],
              total: 0,
              query: {},
              searchTimeMs: Date.now() - startTime,
            },
          };
        }
    
        // 結果フォーマット / Format results
        // include_styles/include_html はスキーマに未定義のためデフォルトfalse
        // Currently partSearchInputSchema doesn't have include_styles/include_html
        // Part search results omit computedStyles and htmlSnippet by default
        const mappedResults = formatSearchResult(result, false, false);
    
        const searchTimeMs = Date.now() - startTime;
    
        if (isDevelopment()) {
          logger.info("[MCP Tool] part.search completed", {
            query: validated.query,
            searchMode: validated.search_mode,
            resultCount: mappedResults.length,
            total: result.total,
            searchTimeMs,
          });
        }
    
        return {
          success: true,
          data: {
            results: mappedResults,
            total: result.total,
            query: {
              ...(validated.query ? { text: validated.query } : {}),
              ...(validated.image_url ? { imageUrl: validated.image_url } : {}),
            },
            searchTimeMs,
          },
        };
      } catch (error) {
        const errorInstance = error instanceof Error ? error : new Error(String(error));
        const errorCode = mapErrorToCode(errorInstance);
    
        logger.warn("[MCP Tool] part.search error", {
          code: errorCode,
          error: sanitizePartSearchError(error),
        });
    
        return {
          success: false,
          error: {
            code: errorCode,
            message: sanitizePartSearchError(error),
          },
        };
      }
    }
  • The definition of the part.search tool, including its schema and description.
    export const partSearchToolDefinition = {
      name: "part.search",
      description:
        "UIコンポーネントパーツ(ボタン、カード、リンク等)をセマンティック検索します。" +
        "テキストクエリ(e5-base + full-text)によるハイブリッド検索を提供。" +
        "partType(16種類)やsearchMode(visual/text/hybrid)でフィルタリング可能です。" +
        " / Search UI component parts (buttons, cards, links, etc.) by text query. " +
        "Provides hybrid search via e5-base + full-text. " +
        "Filterable by partType (16 types) and searchMode (visual/text/hybrid).",
      annotations: {
        title: "Part Search",
        readOnlyHint: true,
        idempotentHint: true,
        openWorldHint: false,
      },
      inputSchema: {
        type: "object" as const,
        properties: {
          query: {
            type: "string",
            description: "テキスト検索クエリ(1-500文字) / Text search query (1-500 chars)",
            minLength: 1,
            maxLength: 500,
          },
          image_url: {
            type: "string",
            format: "uri",
            description:
              "画像URLによるビジュアル検索(将来対応予定) / Visual search by image URL (future support)",
          },
          part_type: {
            type: "string",
            enum: [
              "button",
              "link",
              "image",
              "video",
              "form",
              "input",
              "heading",
              "card",
              "navigation",
              "footer",
              "cta",
              "hero_image",
              "icon",
              "badge",
              "tag",
              "avatar",
            ],
            description: "パーツタイプでフィルター(16種類) / Filter by part type (16 types)",
          },
          web_page_id: {
            type: "string",
            format: "uuid",
            description: "WebページIDでフィルター / Filter by web page ID",
          },
          limit: {
            type: "number",
            description: "取得件数(1-100、デフォルト: 20) / Result limit (1-100, default: 20)",
            minimum: 1,
            maximum: 100,
            default: 20,
          },
          offset: {
            type: "number",
            description: "オフセット(0以上、デフォルト: 0) / Offset (0+, default: 0)",
            minimum: 0,
            default: 0,
          },
          search_mode: {
            type: "string",
            enum: ["visual", "text", "hybrid"],
            default: "hybrid",
            description: "検索モード(デフォルト: hybrid) / Search mode (default: hybrid)",
          },
          min_similarity: {
            type: "number",
            description:
              "最小類似度閾値(0-1、デフォルト: 0.3) / Min similarity threshold (0-1, default: 0.3)",
            minimum: 0,
            maximum: 1,
            default: 0.3,
          },
        },
      },
    };
  • The registration of the part.search tool in the main tools index file.
    "part.search": partSearchHandler,

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/TKMD/reftrix-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server