Skip to main content
Glama
ericyangpan

Scan QRCode MCP Server

by ericyangpan

decode_qrcode_image_url

Extract text from QR codes by providing an image URL. This tool processes HTTP(S) links to QR images and returns decoded content.

Instructions

Decode a QR code from an HTTP(S) image URL

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
imageUrlYesHTTP(S) URL to the QR image.

Implementation Reference

  • Fetches the QR code image from the HTTP(S) URL, validates protocol, fetches and converts to buffer, then decodes using decodeQrFromBuffer.
    export async function decodeQrFromUrl(url: string): Promise<DecodeResult> {
      if (!/^https?:\/\//i.test(url)) {
        throw new Error('Only http(s) URLs are supported for imageUrl');
      }
      const res = await fetch(url);
      if (!res.ok) {
        throw new Error(`Failed to fetch image: ${res.status} ${res.statusText}`);
      }
      const arrayBuffer = await res.arrayBuffer();
      const buffer = Buffer.from(arrayBuffer);
      return decodeQrFromBuffer(buffer);
    }
  • Main dispatcher function that routes to imageUrl decoder (decodeQrFromUrl) or dataUrl decoder based on input.
    export async function decodeQr(input: DecodeInput): Promise<DecodeResult> {
      if ('imageDataUrl' in input && input.imageDataUrl) {
        return decodeQrFromDataUrl(input.imageDataUrl);
      }
      if ('imageUrl' in input && input.imageUrl) {
        return decodeQrFromUrl(input.imageUrl);
      }
      throw new Error('Provide either imageDataUrl or imageUrl');
    }
  • MCP server handler for CallToolRequest of 'decode_qrcode_image_url': validates imageUrl arg and calls decodeQr service.
    if (name === 'decode_qrcode_image_url') {
      if (!args.imageUrl || typeof args.imageUrl !== 'string') {
        throw new Error('Missing required argument: imageUrl');
      }
      const result = await decodeQr({ imageUrl: args.imageUrl });
      return { content: [{ type: 'text', text: result.text }] };
    }
  • src/server.ts:44-55 (registration)
    Registers the 'decode_qrcode_image_url' tool in ListToolsResponse with name, description, and inputSchema.
    {
      name: 'decode_qrcode_image_url',
      description: 'Decode a QR code from an HTTP(S) image URL',
      inputSchema: {
        type: 'object',
        required: ['imageUrl'],
        properties: {
          imageUrl: { type: 'string', description: 'HTTP(S) URL to the QR image.' },
        },
        additionalProperties: false,
      },
    },
  • Low-level helper that loads image buffer with Jimp, prepares data for jsQR, detects and decodes the QR code.
    export async function decodeQrFromBuffer(buffer: Buffer): Promise<DecodeResult> {
      const image = await Jimp.read(buffer);
      const { data, width, height } = image.bitmap;
    
      // Jimp gives a Node Buffer; jsQR expects a Uint8ClampedArray in RGBA order (same layout as Canvas ImageData).
      const clamped = new Uint8ClampedArray(data.buffer, data.byteOffset, data.byteLength);
      const qr = (
        jsQR as unknown as (
          data: Uint8ClampedArray,
          width: number,
          height: number,
        ) => { data: string } | null
      )(clamped, width, height);
      if (!qr) {
        throw new Error('No QR code detected in image');
      }
      return { text: qr.data };
    }

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/ericyangpan/scan-qrcode-mcp'

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