Skip to main content
Glama
gregario

onepiece-oracle

search_cards

Find One Piece TCG cards by name, color, type, cost, power, rarity, or set. Filter results to get card details and effects for deck building.

Instructions

Search One Piece TCG cards by name, color, type, cost, power, rarity, attribute, character type, or set. Returns card details with effects.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryNoSearch card name, number, effect text, or character type
colorNoCard color: Red, Blue, Green, Purple, Yellow, Black
card_typeNoCard type: LEADER, CHARACTER, EVENT, STAGE
costNoExact cost value
cost_minNoMinimum cost
cost_maxNoMaximum cost
power_minNoMinimum power
power_maxNoMaximum power
rarityNoRarity: C, UC, R, SR, SEC, L, SP CARD, P, TR
attributeNoAttribute: Slash, Strike, Ranged, Special, Wisdom
typeNoCharacter type (e.g., "Straw Hat Crew", "Navy", "Supernovas")
setNoSet name or code (e.g., "OP-01", "ROMANCE DAWN")
has_counterNoFilter cards with/without counter value
limitNoMax results (default 10)
offsetNoOffset for pagination

Implementation Reference

  • The handler for the `search_cards` tool. It processes the request by calling `searchCards` and formatting the output.
    async (args) => {
      const result = searchCards(args);
    
      if (result.total === 0) {
        return {
          isError: true,
          content: [
            {
              type: 'text' as const,
              text: 'No cards found matching your search. Try broader filters or check spelling.',
            },
          ],
        };
      }
    
      const start = (args.offset ?? 0) + 1;
      const end = start + result.cards.length - 1;
      const header = `Found ${result.total} card${result.total !== 1 ? 's' : ''} (showing ${start}-${end})\n`;
      const cards = result.cards.map((c) => formatCard(c)).join('\n\n---\n\n');
    
      return {
        content: [{ type: 'text' as const, text: header + '\n' + cards }],
      };
    },
  • The core logic implementation for searching cards based on filters.
    export function searchCards(filters: SearchFilters): SearchResult {
      let cards = getCards();
    
      if (filters.query) {
        const q = filters.query;
        cards = cards.filter((c) => matchesQuery(c, q));
      }
    
      if (filters.color) {
        const color = filters.color.toLowerCase();
        cards = cards.filter((c) =>
          c.colors.some((cl) => cl.toLowerCase() === color),
        );
      }
    
      if (filters.card_type) {
        const ct = filters.card_type.toUpperCase();
        cards = cards.filter((c) => c.card_type === ct);
      }
    
      if (filters.cost !== undefined) {
        cards = cards.filter((c) => parseNumeric(c.cost) === filters.cost);
      }
    
      if (filters.cost_min !== undefined) {
        cards = cards.filter((c) => {
          const n = parseNumeric(c.cost);
          return n !== null && n >= filters.cost_min!;
        });
      }
    
      if (filters.cost_max !== undefined) {
        cards = cards.filter((c) => {
          const n = parseNumeric(c.cost);
          return n !== null && n <= filters.cost_max!;
        });
      }
    
      if (filters.power_min !== undefined) {
        cards = cards.filter((c) => {
          const n = parseNumeric(c.power);
          return n !== null && n >= filters.power_min!;
        });
      }
    
      if (filters.power_max !== undefined) {
        cards = cards.filter((c) => {
          const n = parseNumeric(c.power);
          return n !== null && n <= filters.power_max!;
        });
      }
    
      if (filters.rarity) {
        const r = filters.rarity.toUpperCase();
        cards = cards.filter((c) => c.rarity === r);
      }
    
      if (filters.attribute) {
        const attr = filters.attribute.toLowerCase();
        cards = cards.filter((c) =>
          c.attributes.some((a) => a.toLowerCase() === attr),
        );
      }
    
      if (filters.type) {
        const t = filters.type.toLowerCase();
        cards = cards.filter((c) =>
          c.types.some((tp) => tp.toLowerCase().includes(t)),
        );
      }
    
      if (filters.set) {
        const s = filters.set.toLowerCase();
        cards = cards.filter((c) => c.card_sets.toLowerCase().includes(s));
      }
    
      if (filters.has_counter !== undefined) {
        if (filters.has_counter) {
          cards = cards.filter((c) => c.counter !== '-' && c.counter !== '');
        } else {
          cards = cards.filter((c) => c.counter === '-' || c.counter === '');
        }
      }
    
      const total = cards.length;
      const limit = filters.limit ?? 20;
      const offset = filters.offset ?? 0;
    
      return {
        cards: cards.slice(offset, offset + limit),
        total,
      };
    }
  • Registration of the `search_cards` tool on the McpServer.
    export function registerSearchCards(server: McpServer): void {
      server.registerTool(
        'search_cards',
        {
          description:
            'Search One Piece TCG cards by name, color, type, cost, power, rarity, attribute, character type, or set. Returns card details with effects.',
          inputSchema: {
            query: z.string().optional().describe('Search card name, number, effect text, or character type'),
            color: z.string().optional().describe('Card color: Red, Blue, Green, Purple, Yellow, Black'),
            card_type: z.string().optional().describe('Card type: LEADER, CHARACTER, EVENT, STAGE'),
            cost: z.number().optional().describe('Exact cost value'),
            cost_min: z.number().optional().describe('Minimum cost'),
            cost_max: z.number().optional().describe('Maximum cost'),
            power_min: z.number().optional().describe('Minimum power'),
            power_max: z.number().optional().describe('Maximum power'),
            rarity: z.string().optional().describe('Rarity: C, UC, R, SR, SEC, L, SP CARD, P, TR'),
            attribute: z.string().optional().describe('Attribute: Slash, Strike, Ranged, Special, Wisdom'),
            type: z.string().optional().describe('Character type (e.g., "Straw Hat Crew", "Navy", "Supernovas")'),
            set: z.string().optional().describe('Set name or code (e.g., "OP-01", "ROMANCE DAWN")'),
            has_counter: z.boolean().optional().describe('Filter cards with/without counter value'),
            limit: z.number().min(1).max(50).optional().default(10).describe('Max results (default 10)'),
            offset: z.number().min(0).optional().default(0).describe('Offset for pagination'),
          },
        },
        async (args) => {
          const result = searchCards(args);
    
          if (result.total === 0) {
            return {
              isError: true,
              content: [
                {
                  type: 'text' as const,
                  text: 'No cards found matching your search. Try broader filters or check spelling.',
                },
              ],
            };
          }
    
          const start = (args.offset ?? 0) + 1;
          const end = start + result.cards.length - 1;
          const header = `Found ${result.total} card${result.total !== 1 ? 's' : ''} (showing ${start}-${end})\n`;
          const cards = result.cards.map((c) => formatCard(c)).join('\n\n---\n\n');
    
          return {
            content: [{ type: 'text' as const, text: header + '\n' + cards }],
          };
        },
      );

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

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