How the Scoring Mechanism for Tool Search Results Works in FckSignups

The scoring mechanism counts how many query keywords appear across a tool's name, description, and tags, filtering for matches that contain all tokens and sorting by highest score followed by star count.

The BraveOPotato/FckSignups repository implements a keyword-matching algorithm to rank tools during search. Understanding this scoring mechanism for tool search results helps developers optimize tool metadata and debug ranking issues. The implementation lives primarily in src/hooks/useTools.ts and combines tokenization, exact-match filtering, and multi-criteria sorting.

Tokenizing the Search Query

Before scoring begins, the raw search string undergoes normalization in the tokenize function (lines 37-44). This process converts input to lowercase and splits it into alphanumeric tokens using the regex /[^a-z0-9]+/, ensuring that "video‑editor", "Video Editor", and "video_editor" are treated identically.

// src/hooks/useTools.ts (lines 37-44)
const tokenize = (query: string): string[] => {
  return query
    .toLowerCase()
    .split(/[^a-z0-9]+/)
    .filter(token => token.length > 0);
};

Calculating the Match Score

The matchScore function (lines 46-54) evaluates each tool by constructing a searchable "haystack" from three fields defined in src/types/index.ts: name, description, and tags. It then counts how many query tokens appear within this concatenated string.

// src/hooks/useTools.ts (lines 46-54)
const matchScore = (tool: Tool, keywords: string[]): number => {
  const haystack = `${tool.name} ${tool.description} ${tool.tags.join(' ')}`.toLowerCase();
  return keywords.filter(keyword => haystack.includes(keyword)).length;
};

For example, searching "video editor" produces tokens ["video", "editor"]. A tool named "Super Video Editor" with tags ["media"] generates the haystack "super video editor [description contents] media", yielding a score of 2 because both tokens are present.

Filtering and Ranking Results

After calculating scores, the system applies strict filtering and secondary sorting in the filteredTools memo (lines 101-110) to determine final result order.

Strict Filtering Requirements

A tool only passes the filter if its match score equals the total number of query tokens (score === keywords.length). This enforces an AND logic where every keyword must be present. If the query is empty, the filter returns all available tools from src/data/schema.js.

Secondary Sorting by Popularity

When multiple tools achieve identical scores, the sorting logic compares star counts in descending order (b.tool.stars - a.tool.stars). This ensures higher-popularity tools surface first when keyword relevance is equal.

// src/hooks/useTools.ts (lines 101-110)
const filteredTools = useMemo(() => {
  return tools
    .filter(tool => matchScore(tool, keywords) === keywords.length || keywords.length === 0)
    .sort((a, b) => {
      const scoreDiff = matchScore(b, keywords) - matchScore(a, keywords);
      if (scoreDiff !== 0) return scoreDiff;
      return b.tool.stars - a.tool.stars;
    });
}, [tools, keywords]);

Summary

  • The tokenize function normalizes queries to lowercase alphanumeric tokens to handle punctuation variations.
  • matchScore concatenates name, description, and tags into a haystring and counts keyword matches.
  • The filter requires tools to match all query tokens, implementing strict conjunctive search logic.
  • When scores tie, tools with higher star counts rank first according to the secondary sort in the filteredTools memo.

Frequently Asked Questions

How does the tokenization handle special characters?

The tokenize function splits the query using the regex /[^a-z0-9]+/, which treats any non-alphanumeric character as a delimiter. This means searches for "video-editor", "video_editor", or "Video.Editor" all generate the same token array ["video", "editor"].

What fields are included in the search scoring?

According to the source code in src/hooks/useTools.ts, the algorithm searches across three fields: name, description, and the tags array. These fields are concatenated into a single lowercase string before token matching occurs.

Why might a tool with matching keywords not appear in results?

The filtering logic requires the match score to equal the number of query tokens. If a user searches for "video editor" (two tokens) and a tool only contains "video" in its searchable fields, it receives a score of 1, which fails the strict equality check and excludes it from results.

How does the system break ties between equally relevant tools?

When multiple tools achieve the same match score, the sorting logic in lines 101-110 compares b.tool.stars - a.tool.stars. Tools with higher star counts are placed first in the results list, ensuring popular tools surface when keyword relevance is identical.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →