Skip to main content
Glama
gregario

lego-oracle

search_parts

Find LEGO bricks, plates, and elements by name, category, color, or material. Use this tool to locate specific part numbers for building projects or inventory management.

Instructions

Search for LEGO parts by name, category, colour, or material. Use this when looking for specific brick types, plates, tiles, or other elements. Returns part numbers and names: use get_part for full details.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryNoFree-text search (FTS5) across part names
categoryNoFilter by part category name
colorNoFilter by colour name or ID (finds parts available in this colour)
materialNoFilter by part material (e.g. "Plastic", "Rubber")
limitNoMax results (default 25, max 50)

Implementation Reference

  • The handler function for the search_parts tool, which performs the database query.
    export function handler(db: Database.Database, params: SearchPartsParams): SearchPartsResult {
      const limit = params.limit ?? 25;
      const conditions: string[] = [];
      const bindings: unknown[] = [];
      const joins: string[] = ['LEFT JOIN part_categories pc ON p.part_cat_id = pc.id'];
    
      let usesFts = false;
      if (params.query) {
        usesFts = true;
      }
    
      if (params.category) {
        conditions.push('LOWER(pc.name) = LOWER(?)');
        bindings.push(params.category);
      }
    
      if (params.material) {
        conditions.push('LOWER(p.part_material) = LOWER(?)');
        bindings.push(params.material);
      }
    
      // Colour filter: find parts that exist in inventory_parts with this colour
      let colorJoin = '';
      if (params.color) {
        const colorId = parseInt(params.color, 10);
        if (!isNaN(colorId)) {
          colorJoin = 'JOIN inventory_parts ip ON ip.part_num = p.part_num JOIN colors c ON ip.color_id = c.id';
          conditions.push('c.id = ?');
          bindings.push(colorId);
        } else {
          colorJoin = 'JOIN inventory_parts ip ON ip.part_num = p.part_num JOIN colors c ON ip.color_id = c.id';
          conditions.push('LOWER(c.name) = LOWER(?)');
          bindings.push(params.color);
        }
      }
    
      let sql: string;
      const allBindings: unknown[] = [];
    
      if (usesFts) {
        sql = `SELECT DISTINCT p.part_num, p.name, pc.name as category_name, p.part_material
               FROM parts_fts fts
               JOIN parts p ON p.rowid = fts.rowid
               ${joins.join(' ')}
               ${colorJoin}
               WHERE parts_fts MATCH ?`;
        allBindings.push(params.query!);
        for (const cond of conditions) {
          sql += ` AND ${cond}`;
        }
        allBindings.push(...bindings);
        sql += ' ORDER BY fts.rank LIMIT ?';
      } else {
        sql = `SELECT DISTINCT p.part_num, p.name, pc.name as category_name, p.part_material
               FROM parts p
               ${joins.join(' ')}
               ${colorJoin}`;
        if (conditions.length > 0) {
          sql += ' WHERE ' + conditions.join(' AND ');
          allBindings.push(...bindings);
        }
        sql += ' ORDER BY p.name LIMIT ?';
      }
      allBindings.push(limit);
    
      const rows = db.prepare(sql).all(...allBindings) as PartSummary[];
    
      return { parts: rows, total: rows.length };
    }
  • The zod schema defining the input parameters for the search_parts tool.
    export const SearchPartsInput = z.object({
      query: z.string().optional().describe('Free-text search (FTS5) across part names'),
      category: z.string().optional().describe('Filter by part category name'),
      color: z.string().optional().describe('Filter by colour name or ID (finds parts available in this colour)'),
      material: z.string().optional().describe('Filter by part material (e.g. "Plastic", "Rubber")'),
      limit: z.number().min(1).max(50).optional().describe('Max results (default 25, max 50)'),
    });
  • src/server.ts:103-115 (registration)
    The tool registration for search_parts in the MCP server.
    server.tool(
      'search_parts',
      'Search for LEGO parts by name, category, colour, or material. Use this when looking for specific brick types, plates, tiles, or other elements. Returns part numbers and names: use get_part for full details.',
      SearchPartsInput.shape,
      async (params) => {
        try {
          const result = searchPartsHandler(db, params);
          return { content: [{ type: 'text' as const, text: formatSearchParts(result) }] };
        } catch (err) {
          return { content: [{ type: 'text' as const, text: `Error searching parts: ${err instanceof Error ? err.message : String(err)}` }], isError: true };
        }
      },
    );

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/gregario/lego-oracle'

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