Skip to main content
Glama

search_equipment

Find D&D 5e equipment, weapons, armor, and magic items by name, category, cost, weight, properties, or rarity to equip characters effectively.

Instructions

Search D&D 5e SRD equipment, weapons, armor, and magic items. Filter by category, cost, weight, weapon properties, armor type, or rarity.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryNoSearch term for item name or description
categoryNoEquipment category (e.g. "Weapon", "Armor", "Adventuring Gear", "Tools")
cost_minNoMinimum cost in gold pieces
cost_maxNoMaximum cost in gold pieces
weight_maxNoMaximum weight in pounds
weapon_propertyNoWeapon property (e.g. "finesse", "heavy", "two-handed", "versatile")
armor_categoryNoArmor category (e.g. "Light", "Medium", "Heavy", "Shield")
rarityNoMagic item rarity (e.g. "common", "uncommon", "rare", "very rare", "legendary")
limitNoResults per page (max 50)
offsetNoOffset for pagination

Implementation Reference

  • The handler for the 'search_equipment' tool, which takes user filters, executes the search query, and formats the result.
    async ({
      query,
      category,
      cost_min,
      cost_max,
      weight_max,
      weapon_property,
      armor_category,
      rarity,
      limit,
      offset,
    }) => {
      const result = searchEquipment(db, {
        query,
        category,
        cost_min,
        cost_max,
        weight_max,
        weapon_property,
        armor_category,
        rarity,
        limit,
        offset,
      });
    
      if (result.rows.length === 0) {
        return {
          content: [
            {
              type: 'text' as const,
              text: 'No equipment found matching your criteria. Try a broader search — for example, remove some filters or use a partial name.',
            },
          ],
          isError: true,
        };
      }
    
      const start = (offset ?? 0) + 1;
      const end = (offset ?? 0) + result.rows.length;
      const header = `Found ${result.total} item${result.total === 1 ? '' : 's'} (showing ${start}-${end})\n`;
    
      const items = result.rows.map(formatEquipmentItem).join('\n\n---\n\n');
    
      return {
        content: [{ type: 'text' as const, text: header + '\n' + items }],
      };
    },
  • The schema definition for the 'search_equipment' tool, defining the input filters.
    inputSchema: {
      query: z.string().optional().describe('Search term for item name or description'),
      category: z
        .string()
        .optional()
        .describe('Equipment category (e.g. "Weapon", "Armor", "Adventuring Gear", "Tools")'),
      cost_min: z.number().optional().describe('Minimum cost in gold pieces'),
      cost_max: z.number().optional().describe('Maximum cost in gold pieces'),
      weight_max: z.number().optional().describe('Maximum weight in pounds'),
      weapon_property: z
        .string()
        .optional()
        .describe('Weapon property (e.g. "finesse", "heavy", "two-handed", "versatile")'),
      armor_category: z
        .string()
        .optional()
        .describe('Armor category (e.g. "Light", "Medium", "Heavy", "Shield")'),
      rarity: z
        .string()
        .optional()
        .describe('Magic item rarity (e.g. "common", "uncommon", "rare", "very rare", "legendary")'),
      limit: z.number().min(1).max(50).default(10).describe('Results per page (max 50)'),
      offset: z.number().min(0).default(0).describe('Offset for pagination'),
    },
  • The backend database query function that performs the actual SQL execution for searching equipment and magic items.
    export function searchEquipment(
      db: Database.Database,
      filters: EquipmentFilters,
    ): SearchResult<EquipmentRow | MagicItemRow> {
      // Search both equipment and magic_items tables
      if (filters.rarity) {
        // Rarity filter only applies to magic items
        return searchMagicItems(db, filters);
      }
    
      const conditions: string[] = [];
      const params: (string | number)[] = [];
    
      if (filters.query) {
        const ftsQuery = sanitizeFtsQuery(filters.query);
        if (ftsQuery.length > 0) {
          conditions.push(
            'e.id IN (SELECT rowid FROM equipment_fts WHERE equipment_fts MATCH ?)',
          );
          params.push(ftsQuery);
        }
      }
    
      if (filters.category) {
        conditions.push('LOWER(e.category) = LOWER(?)');
        params.push(filters.category);
      }
    
      if (filters.cost_min !== undefined) {
        conditions.push('e.cost_gp >= ?');
        params.push(filters.cost_min);
      }
    
      if (filters.cost_max !== undefined) {
        conditions.push('e.cost_gp <= ?');
        params.push(filters.cost_max);
      }
    
      if (filters.weight_max !== undefined) {
        conditions.push('e.weight <= ?');
        params.push(filters.weight_max);
      }
    
      if (filters.weapon_property) {
        conditions.push('LOWER(e.weapon_properties) LIKE LOWER(?)');
        params.push(`%${filters.weapon_property}%`);
      }
    
      if (filters.armor_category) {
        conditions.push('LOWER(e.armor_category) = LOWER(?)');
        params.push(filters.armor_category);
      }
    
      const where =
        conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
      const limit = filters.limit ?? 20;
      const offset = filters.offset ?? 0;
    
      const countRow = db
        .prepare(`SELECT COUNT(*) as count FROM equipment e ${where}`)
        .get(...params) as { count: number };
    
      const rows = db
        .prepare(
          `SELECT e.* FROM equipment e ${where} ORDER BY e.name ASC LIMIT ? OFFSET ?`,
        )
        .all(...params, limit, offset) as EquipmentRow[];
    
      return { rows, total: countRow.count };
    }

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/dnd-oracle'

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