Skip to main content
Glama
ewilderj

Fountain Pen Ink MCP Server

search_inks_by_color

Find fountain pen inks matching a specific color by entering a hex code to discover similar shades from the database.

Instructions

Find inks similar to a given color using RGB matching

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
colorYesHex color code (e.g., "#FF5733")
max_resultsNoMaximum number of results to return (default: 20)

Implementation Reference

  • The primary handler function for the 'search_inks_by_color' tool. Converts input hex color to RGB, finds closest matching inks using color distance, retrieves metadata, formats results as JSON, and returns MCPTextResponse.
    private searchInksByColor(colorHex: string, maxResults: number): MCPTextResponse {
      try {
        const targetRgb = hexToRgb(colorHex);
        const closestInks = findClosestInks(targetRgb, this.inkColors, maxResults);
    
        const results: SearchResult[] = closestInks.map((ink) => {
          const metadata = this.getInkMetadata(ink.ink_id);
          return createSearchResult(ink, metadata, ink.distance);
        });
    
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(
                {
                  target_color: colorHex,
                  target_rgb: targetRgb,
                  results_count: results.length,
                  results,
                },
                null,
                2,
              ),
            },
          ],
        } satisfies MCPTextResponse;
      } catch {
        throw new Error(`Invalid color format: ${colorHex}. Please use hex format like #FF5733`);
      }
    }
  • Tool schema definition in the ListTools response, specifying input parameters: color (required hex string) and optional max_results.
    {
      name: 'search_inks_by_color',
      description: 'Find inks similar to a given color using RGB matching',
      inputSchema: {
        type: 'object',
        properties: {
          color: {
            type: 'string',
            description: 'Hex color code (e.g., "#FF5733")',
          },
          max_results: {
            type: 'number',
            description: 'Maximum number of results to return (default: 20)',
            default: 20,
          },
        },
        required: ['color'],
      },
    },
  • src/index.ts:277-281 (registration)
    Dispatch registration in the CallToolRequestSchema handler switch statement, mapping tool calls to the searchInksByColor method.
    case 'search_inks_by_color':
      return this.searchInksByColor(
        args.color as string,
        (args.max_results as number) || 20,
      );
  • Core helper function that computes Euclidean RGB color distances for all inks against target, sorts by closeness, and returns top matches with distance.
    export function findClosestInks(
      targetRgb: [number, number, number],
      inkColors: InkColor[],
      maxResults: number = 20,
    ): InkWithDistance[] {
      const distances = inkColors.map((ink) => ({
        ...ink,
        distance: calculateColorDistance(targetRgb, ink.rgb), // Now both are RGB!
      }));
    
      // Sort by distance (closest first)
      distances.sort((a, b) => a.distance - b.distance);
    
      return distances.slice(0, maxResults);
    }
  • Utility function to parse hex color string to RGB array, used in the handler for input validation and conversion.
    export function hexToRgb(hex: string): [number, number, number] {
      const cleanHex = hex.replace(/^#/, '');
      if (cleanHex.length !== 6) {
        throw new Error('Invalid hex color string');
      }
    
      const bigint = parseInt(cleanHex, 16);
      const r = (bigint >> 16) & 255;
      const g = (bigint >> 8) & 255;
      const b = bigint & 255;
    
      return [r, g, b];
    }
Behavior2/5

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

No annotations are provided, so the description carries the full burden of behavioral disclosure. It states the tool finds inks 'similar to a given color using RGB matching', which implies a read-only search operation, but does not disclose details like how similarity is calculated, whether results are sorted, potential rate limits, or error handling. For a tool with no annotation coverage, this leaves significant gaps in understanding its behavior.

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?

The description is a single, efficient sentence that directly states the tool's function without any wasted words. It is front-loaded with the core purpose, making it easy to understand at a glance.

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

Completeness2/5

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

Given the complexity of a search tool with no annotations and no output schema, the description is incomplete. It does not explain what the return values might include (e.g., ink names, similarity scores), how results are structured, or any limitations. This leaves the agent with insufficient context to fully utilize the tool.

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

Parameters3/5

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

The schema description coverage is 100%, with clear descriptions for both parameters ('color' as a hex code and 'max_results' with a default). The description adds minimal value beyond the schema by mentioning 'RGB matching', which hints at the algorithm but does not provide additional syntax or format details. This meets the baseline for high schema coverage.

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

Purpose4/5

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

The description clearly states the tool's purpose with a specific verb ('Find') and resource ('inks similar to a given color'), and mentions the method ('RGB matching'). It distinguishes from siblings like 'search_inks_by_name' by focusing on color matching rather than name search. However, it doesn't explicitly differentiate from 'analyze_color' or 'get_color_palette', which might involve color-related operations.

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool versus alternatives like 'get_inks_by_maker' or 'search_inks_by_name'. It lacks context about scenarios where color-based search is preferred over other methods, and does not mention any prerequisites or exclusions for usage.

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/ewilderj/inks-mcp'

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