Skip to main content
Glama

tomtom-static-map

Generate static maps with customizable parameters like center coordinates, zoom level, size, style, and layer type using the TomTom MCP Server. Supports multiple formats and geopolitical views for precise map rendering.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
bboxNoBounding box in format [west, south, east, north]. Alternative to center+zoom. Example: [-122.42, 37.77, -122.40, 37.79] for part of San Francisco.
centerYesMap center coordinates. Use results from geocoding or search operations for best positioning.
formatNoImage format: 'png' (better quality, supports transparency), 'jpg' (smaller file size).
heightNoMap height in pixels (50-2048). Examples: 300-500 (preview), 800-1200 (detailed). Default: 512.
languageNoLanguage for map labels (IETF language tag). Examples: 'en-US', 'es-ES', 'fr-FR'.
layerNoMap layer type: 'basic' (streets), 'labels' (text only, transparent background), 'hybrid' (satellite with labels).
styleNoMap style: 'main' (default daytime), 'night' (dark theme).
viewNoGeopolitical view for border disputes and territories. 'Unified' is the international standard view.
widthNoMap width in pixels (50-2048). Examples: 300-500 (preview), 800-1200 (detailed). Default: 512.
zoomNoZoom level (0-22). Examples: 3 (continent), 6 (country), 10 (city), 15 (neighborhood), 18 (street). Default: 15.

Implementation Reference

  • Factory function creating the MCP tool handler for tomtom-static-map. Processes input parameters, fetches the static map image via service, and returns it as base64 image content or error.
    export function createStaticMapHandler() { return async (params: any) => { logger.info(`🗺️ Generating static map: (${params.center.lat}, ${params.center.lon})`); try { const { base64, contentType } = await getStaticMapImage(params); logger.info(`✅ Static map generated successfully`); return { content: [{ type: "image" as const, data: base64, mimeType: contentType }], }; } catch (error: any) { logger.error(`❌ Static map generation failed: ${error.message}`); return { content: [{ type: "text" as const, text: JSON.stringify({ error: error.message }) }], isError: true, }; } }; }
  • Zod schema definition for input validation of tomtom-static-map tool parameters including center, bbox, zoom, dimensions, styles, layers, etc.
    export const tomtomMapSchema = { center: coordinateSchema.describe( "Map center coordinates. Use results from geocoding or search operations for best positioning." ), // Fix: Use z.array() instead of z.tuple() bbox: z .array(z.number()) .length(4) .optional() .describe( "Bounding box in format [west, south, east, north]. Alternative to center+zoom. Example: [-122.42, 37.77, -122.40, 37.79] for part of San Francisco." ), zoom: z .number() .min(0) .max(22) .optional() .describe( "Zoom level (0-22). Examples: 3 (continent), 6 (country), 10 (city), 15 (neighborhood), 18 (street). Default: 15." ), width: z .number() .min(50) .max(2048) .optional() .describe( "Map width in pixels (50-2048). Examples: 300-500 (preview), 800-1200 (detailed). Default: 512." ), height: z .number() .min(50) .max(2048) .optional() .describe( "Map height in pixels (50-2048). Examples: 300-500 (preview), 800-1200 (detailed). Default: 512." ), style: z .enum(["main", "night"]) .optional() .describe("Map style: 'main' (default daytime), 'night' (dark theme)."), layer: z .enum(["basic", "labels", "hybrid"]) .optional() .describe( "Map layer type: 'basic' (streets), 'labels' (text only, transparent background), 'hybrid' (satellite with labels)." ), format: z .enum(["png", "jpg"]) .optional() .describe( "Image format: 'png' (better quality, supports transparency), 'jpg' (smaller file size)." ), view: z .enum(["Unified", "IL", "IN", "MA", "PK", "AR", "Arabic", "RU", "TR", "CN", "US"]) .optional() .describe( "Geopolitical view for border disputes and territories. 'Unified' is the international standard view." ), language: z .string() .optional() .describe("Language for map labels (IETF language tag). Examples: 'en-US', 'es-ES', 'fr-FR'."), };
  • Registration of the tomtom-static-map tool with MCP server, linking schema and handler.
    server.registerTool( "tomtom-static-map", { title: "TomTom Static Map", description: "Generate custom map images from TomTom Maps with specified center coordinates, zoom levels, and style options", inputSchema: schemas.tomtomMapSchema, }, createStaticMapHandler() );
  • Core service function that constructs the TomTom Static Maps API URL, fetches the image, adds copyright overlay if canvas available, and returns base64-encoded image data used by the handler.
    export async function getStaticMapImage( options: MapOptions ): Promise<{ base64: string; contentType: string }> { try { // Get the URL first const mapUrl = getStaticMapUrl(options); // Log the URL before making the request logger.info(`Making static map request to: ${tomtomClient.defaults.baseURL}${mapUrl}`); // Use tomtomClient to download the image (it automatically includes proper headers) const response = await tomtomClient.get(mapUrl, { responseType: "arraybuffer", }); // Log the actual URL that was requested (including any modifications made by axios) if (response.config && response.config.url) { logger.info(`Full request URL was: ${response.config.url}`); } if (!response.status || response.status >= 400) { throw new Error(`Failed to fetch map image: HTTP ${response.status}`); } // Get the content type from the response headers const contentType = response.headers?.["content-type"] || "image/png"; // The image data is already in the response const imageBuffer = response.data; // Add copyright overlay to the static map image let finalImageBuffer = imageBuffer; // Try to load Canvas dynamically const canvasAvailable = await loadCanvasIfAvailable(); if (canvasAvailable) { try { // Fetch Genesis copyright text (static maps are Genesis only) const copyrightText = await fetchCopyrightCaption(false); logger.info(`📄 Static map copyright text: ${copyrightText}`); // Get image dimensions from options const width = options.width || DEFAULT_MAP_OPTIONS.width; const height = options.height || DEFAULT_MAP_OPTIONS.height; // Create canvas and load the original image const canvas = createCanvas(width, height); const ctx = canvas.getContext('2d'); // Load and draw the original image const buffer = Buffer.from(imageBuffer); const { loadImage } = await import('canvas'); const img = await loadImage(buffer); ctx.drawImage(img, 0, 0, width, height); // Add copyright overlay using shared utility addCopyrightOverlay(ctx, copyrightText, width, height); // Convert canvas back to buffer finalImageBuffer = canvas.toBuffer('image/png'); logger.debug(`Added copyright overlay to static map image`); } catch (overlayError: any) { logger.error(`Failed to add copyright overlay to static map: ${overlayError.message}. Using original image.`); // Use original image if overlay fails finalImageBuffer = imageBuffer; } } else { logger.debug('Canvas not available, skipping copyright overlay for static map'); } // Convert the buffer to base64 const base64 = Buffer.from(finalImageBuffer).toString("base64"); logger.debug(`Downloaded and processed static map image (${(finalImageBuffer.byteLength / 1024).toFixed(2)} KB)`); return { base64, contentType }; } catch (error) { logger.error(`Failed to download static map: ${error}`); throw error; } }

Other Tools

Related 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/tomtom-international/tomtom-mcp'

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