create-watermark
Add customizable watermarks or logos to images by specifying URL, opacity, size, and position. Generate a watermarked image URL or save the file directly.
Instructions
Add watermarks/logos to images using QuickChart - get watermarked image URL or save watermarked image to file
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | Whether to get watermarked image URL or save as file | |
| imageHeight | No | Main image height in pixels | |
| imageWidth | No | Main image width in pixels | |
| mainImageUrl | Yes | URL of the main image to watermark | |
| margin | No | Margin from edges in pixels | |
| markHeight | No | Watermark height in pixels | |
| markImageUrl | Yes | URL of the watermark/logo image | |
| markRatio | No | Watermark size ratio relative to main image | |
| markWidth | No | Watermark width in pixels | |
| opacity | No | Watermark opacity (0.0 to 1.0) | |
| outputPath | No | Path where to save the file (only used with action=save_file) | |
| position | No | Watermark position | |
| positionX | No | Custom X position in pixels | |
| positionY | No | Custom Y position in pixels |
Implementation Reference
- src/tools/watermark.ts:284-397 (handler)The primary handler function that implements the core logic of the 'create-watermark' tool. It validates inputs, constructs the watermark configuration, interacts with QuickChart API to generate the watermarked image, handles base64 encoding, and optionally saves the image to a file.export async function handleWatermarkTool(args: any): Promise<any> { const mainImageUrl = args.mainImageUrl as string; const markImageUrl = args.markImageUrl as string; const action = args.action as string; validateMainImageUrl(mainImageUrl); validateMarkImageUrl(markImageUrl); validateAction(action); validateOutputPath(args.outputPath, action); validateOpacity(args.opacity); validateDimensions(args.imageWidth, args.imageHeight); validateDimensions(args.markWidth, args.markHeight); validatePosition(args.position); const config = buildWatermarkConfig(mainImageUrl, markImageUrl, { opacity: args.opacity as number, imageWidth: args.imageWidth as number, imageHeight: args.imageHeight as number, markWidth: args.markWidth as number, markHeight: args.markHeight as number, markRatio: args.markRatio as number, position: args.position as string, positionX: args.positionX as number, positionY: args.positionY as number, margin: args.margin as number, }); const watermarkUrl = buildWatermarkUrl(mainImageUrl, markImageUrl); const result: any = { content: [ { type: "text", text: "Below is the watermarked image URL:", }, { type: "text", text: watermarkUrl, }, ], metadata: { watermarkType: "image", generatedAt: new Date().toISOString(), watermarkUrl: watermarkUrl, }, }; let pngData: any = null; try { pngData = await fetchWatermarkContent(config); const pngBase64 = Buffer.from(pngData).toString("base64"); result.content.push( { type: "text", text: "Below is the PNG image:", }, { type: "image", data: pngBase64, mimeType: "image/png", } ); result.metadata.pngBase64 = pngBase64; } catch (error) { result.content.unshift({ type: "text", text: "⚠️ Failed to fetch watermarked image", }); result.content.push({ type: "text", text: `Error: ${error instanceof Error ? error.message : String(error)}`, }); result.metadata.error = error instanceof Error ? error.message : String(error); } if (action === "get_url") { return result; } const outputPath = getDownloadPath( args.outputPath as string | undefined, "png" ); try { const dir = path.dirname(outputPath); if (!fs.existsSync(dir)) { fs.mkdirSync(dir, { recursive: true }); } // If pngData is null, fetch it again for file saving const dataToSave = pngData || await fetchWatermarkContent(config); fs.writeFileSync(outputPath, dataToSave); result.metadata.savedPath = outputPath; result.content.push({ type: "text", text: "Below is the saved file path:", }); result.content.push({ type: "text", text: outputPath, }); return result; } catch (error) { throw new McpError( ErrorCode.InternalError, `Failed to save watermarked image: ${ error instanceof Error ? error.message : String(error) }` ); } }
- src/tools/watermark.ts:11-92 (schema)The Tool object definition including name, description, and complete inputSchema for parameter validation of the 'create-watermark' tool.export const CREATE_WATERMARK_TOOL: Tool = { name: "create-watermark", description: "Add watermarks/logos to images using QuickChart - get watermarked image URL or save watermarked image to file", inputSchema: { type: "object", properties: { action: { type: "string", enum: ["get_url", "save_file"], description: "Whether to get watermarked image URL or save as file", }, outputPath: { type: "string", description: "Path where to save the file (only used with action=save_file)", }, mainImageUrl: { type: "string", description: "URL of the main image to watermark", }, markImageUrl: { type: "string", description: "URL of the watermark/logo image", }, opacity: { type: "number", minimum: 0, maximum: 1, description: "Watermark opacity (0.0 to 1.0)", }, imageWidth: { type: "integer", description: "Main image width in pixels", }, imageHeight: { type: "integer", description: "Main image height in pixels", }, markWidth: { type: "integer", description: "Watermark width in pixels", }, markHeight: { type: "integer", description: "Watermark height in pixels", }, markRatio: { type: "number", description: "Watermark size ratio relative to main image", }, position: { type: "string", enum: [ "center", "topLeft", "topMiddle", "topRight", "middleLeft", "middleRight", "bottomLeft", "bottomMiddle", "bottomRight", ], description: "Watermark position", }, positionX: { type: "integer", description: "Custom X position in pixels", }, positionY: { type: "integer", description: "Custom Y position in pixels", }, margin: { type: "integer", description: "Margin from edges in pixels", }, }, required: ["action", "mainImageUrl", "markImageUrl"], }, };
- src/tools/index.ts:91-94 (registration)Registration of the handler function for 'create-watermark' in the central tool handlers mapping."create-watermark": { handler: handleWatermarkTool, toolName: ToolNames.WATERMARK, },
- src/tools/index.ts:46-46 (registration)Inclusion of the 'create-watermark' tool in the ALL_TOOLS array for conditional enabling and export.{ tool: CREATE_WATERMARK_TOOL, name: ToolNames.WATERMARK },
- src/tools/help.ts:398-418 (helper)Documentation and usage examples for the 'create-watermark' tool provided in the help tool data."create-watermark": { name: "create-watermark", description: "Add watermarks and logos to images - get watermarked image URL or save watermarked image to file", documentation: "https://quickchart.io/documentation/watermark-api/", additionalResources: { apiReference: "https://quickchart.io/documentation/watermark-api/", }, promptExamples: [ 'Document Protection: "Add company logo watermark to reports"', 'Brand Consistency: "Apply watermarks to all marketing materials"', 'Copyright Protection: "Add attribution to shared visualizations"', ], usageExample: { action: "save_file", mainImageUrl: "https://example.com/chart.png", watermarkImageUrl: "https://example.com/logo.png", position: "bottom-right", opacity: 0.7, }, },