Skip to main content
Glama

search

Search ASCII art and kaomoji by keyword, filter by type, or list categories. Get a random entry with the random option.

Instructions

Search ASCII art and kaomoji. Omit query to list all. Use random for a random entry. Use mode "categories" to list categories.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryNoSearch keyword (matches id, name, category, tags). Omit to list all.
typeNoFilter by type: "art", "kaomoji", or "all"all
randomNoReturn one random entry
modeNoMode: "search" (default) or "categories" to list categoriessearch

Implementation Reference

  • The handler function for the 'search' tool. Handles categories mode, random mode, list-all mode (no query), and search mode. Calls search(query) for ASCII art and searchKaomoji(query) for kaomoji.
    async ({ query, type, random, mode }) => {
      // Categories mode
      if (mode === 'categories') {
        const parts: string[] = [];
        if (type !== 'kaomoji') {
          parts.push('Art: ' + listCategories().join(', '));
        }
        if (type !== 'art') {
          parts.push('Kaomoji: ' + listKaomojiCategories().join(', '));
        }
        return { content: [{ type: 'text', text: parts.join('\n') }] };
      }
    
      // Random mode
      if (random) {
        if (type !== 'kaomoji') {
          const result = await toResult(getRandom());
          return { content: [{ type: 'text', text: `--- ${result.name} [${result.size}w ${result.width}x${result.height}] ---\n${result.art}` }] };
        }
        const k = getRandomKaomoji();
        return { content: [{ type: 'text', text: `${k.text}  — ${k.name} [${k.category}]` }] };
      }
    
      // List all (no query)
      if (!query) {
        const parts: string[] = [];
        if (type !== 'kaomoji') {
          const items = listAll().map((e) => {
            const desc = e.description ? ` — ${e.description}` : '';
            return `${e.id} — ${e.name} [${e.category}] (${e.size}w: ${e.width}x${e.height})${desc}`;
          });
          if (items.length > 0) parts.push(items.join('\n'));
        }
        if (type !== 'art') {
          const items = listAllKaomoji().map((k) => `${k.text}  — ${k.name} [${k.category}]`);
          if (items.length > 0) parts.push(items.join('\n'));
        }
        return { content: [{ type: 'text', text: parts.join('\n\n') }] };
      }
    
      // Search mode
      const parts: string[] = [];
    
      if (type !== 'kaomoji') {
        const results = search(query);
        const arts = await Promise.all(results.map((e) => toResult(e)));
        const text = arts.map((a) => {
          const desc = a.description ? `\n${a.description}` : '';
          return `--- ${a.name} (${a.id}) [${a.size}w ${a.width}x${a.height}] ---${desc}\n${a.art}`;
        }).join('\n\n');
        if (text) parts.push(text);
      }
    
      if (type !== 'art') {
        const kaomoji = searchKaomoji(query);
        const text = kaomoji.map((k) => `${k.text}  — ${k.name} [${k.category}]`).join('\n');
        if (text) parts.push(text);
      }
    
      if (parts.length === 0) {
        return { content: [{ type: 'text', text: `No results found for "${query}"` }] };
      }
      return { content: [{ type: 'text', text: parts.join('\n\n') }] };
    }
  • src/mcp.ts:30-38 (registration)
    Registration of the 'search' tool via server.tool() with name 'search', description, Zod schema for parameters (query, type, random, mode), and the async handler.
    server.tool(
      'search',
      'Search ASCII art and kaomoji. Omit query to list all. Use random for a random entry. Use mode "categories" to list categories.',
      {
        query: z.string().optional().describe('Search keyword (matches id, name, category, tags). Omit to list all.'),
        type: z.enum(['art', 'kaomoji', 'all']).default('all').describe('Filter by type: "art", "kaomoji", or "all"'),
        random: z.boolean().default(false).describe('Return one random entry'),
        mode: z.enum(['search', 'categories']).default('search').describe('Mode: "search" (default) or "categories" to list categories'),
      },
  • Zod schema definitions for the 'search' tool parameters: query (optional string), type (enum 'art'|'kaomoji'|'all'), random (boolean), and mode (enum 'search'|'categories').
    {
      query: z.string().optional().describe('Search keyword (matches id, name, category, tags). Omit to list all.'),
      type: z.enum(['art', 'kaomoji', 'all']).default('all').describe('Filter by type: "art", "kaomoji", or "all"'),
      random: z.boolean().default(false).describe('Return one random entry'),
      mode: z.enum(['search', 'categories']).default('search').describe('Mode: "search" (default) or "categories" to list categories'),
    },
  • The search() function in store.ts that queries ASCII art entries using matchQuery(). Delegates to the generic matchQuery utility with an extra match on description.
    export function search(query: string): ArtEntry[] {
      return matchQuery(entries, query, (e, q) => e.description?.toLowerCase().includes(q) ?? false);
    }
  • The searchKaomoji() function that queries kaomoji entries using matchQuery().
    export function searchKaomoji(query: string): KaomojiEntry[] {
      return matchQuery(entries, query);
    }
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, so description carries full burden. It implies read-only behavior (search, list) but does not explicitly state safety, authorization, or side effects. Minimal behavioral context beyond the modes.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with action, no redundancy. Every sentence adds meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 4 optional parameters, no nested objects, and no output schema, the description covers main use cases. However, it does not describe the return format (e.g., list of items), which could be inferred from the schema query description.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema covers 100% of parameters with descriptions. The description adds value by explaining how to use parameters together (e.g., 'omit query to list all', 'random' for randomness), providing usage context beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool searches 'ASCII art and kaomoji', with specific verbs and resource. It distinguishes from sibling tools like 'animate' or 'banner' by focusing on search functionality.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit usage scenarios: 'Omit query to list all', 'Use random for a random entry', 'Use mode categories to list categories'. Context is clear, though no when-not-to-use or alternatives are mentioned; sibling tools are distinct enough.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/rxolve/artscii'

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