@houtini/gemini-mcp 1.4.5 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/README.md +314 -834
  2. package/claude_desktop_config_example.json +1 -0
  3. package/dist/config/index.d.ts.map +1 -1
  4. package/dist/config/index.js +8 -4
  5. package/dist/config/index.js.map +1 -1
  6. package/dist/config/types.d.ts +5 -0
  7. package/dist/config/types.d.ts.map +1 -1
  8. package/dist/image-viewer/image-viewer-app.html +180 -0
  9. package/dist/image-viewer/src/ui/image-viewer.html +324 -0
  10. package/dist/index-new.d.ts +3 -0
  11. package/dist/index-new.d.ts.map +1 -0
  12. package/dist/index-new.js +7 -0
  13. package/dist/index-new.js.map +1 -0
  14. package/dist/index.d.ts +3 -1
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +70 -172
  17. package/dist/index.js.map +1 -1
  18. package/dist/landing-page-viewer/src/ui/landing-page-viewer.html +330 -0
  19. package/dist/services/gemini/export.d.ts +5 -0
  20. package/dist/services/gemini/export.d.ts.map +1 -0
  21. package/dist/services/gemini/export.js +5 -0
  22. package/dist/services/gemini/export.js.map +1 -0
  23. package/dist/services/gemini/image-service.d.ts +45 -0
  24. package/dist/services/gemini/image-service.d.ts.map +1 -0
  25. package/dist/services/gemini/image-service.js +248 -0
  26. package/dist/services/gemini/image-service.js.map +1 -0
  27. package/dist/services/gemini/index.d.ts +7 -2
  28. package/dist/services/gemini/index.d.ts.map +1 -1
  29. package/dist/services/gemini/index.js +132 -56
  30. package/dist/services/gemini/index.js.map +1 -1
  31. package/dist/services/gemini/types.d.ts +32 -0
  32. package/dist/services/gemini/types.d.ts.map +1 -1
  33. package/dist/services/gemini/video-service.d.ts +58 -0
  34. package/dist/services/gemini/video-service.d.ts.map +1 -0
  35. package/dist/services/gemini/video-service.js +325 -0
  36. package/dist/services/gemini/video-service.js.map +1 -0
  37. package/dist/services/media-server.d.ts +28 -0
  38. package/dist/services/media-server.d.ts.map +1 -0
  39. package/dist/services/media-server.js +195 -0
  40. package/dist/services/media-server.js.map +1 -0
  41. package/dist/svg-viewer/src/ui/svg-viewer.html +325 -0
  42. package/dist/tools/gemini-chat.d.ts.map +1 -1
  43. package/dist/tools/gemini-chat.js +7 -1
  44. package/dist/tools/gemini-chat.js.map +1 -1
  45. package/dist/tools/gemini-deep-research.d.ts +1 -2
  46. package/dist/tools/gemini-deep-research.d.ts.map +1 -1
  47. package/dist/tools/gemini-deep-research.js +11 -51
  48. package/dist/tools/gemini-deep-research.js.map +1 -1
  49. package/dist/tools/gemini-help.d.ts +3 -0
  50. package/dist/tools/gemini-help.d.ts.map +1 -0
  51. package/dist/tools/gemini-help.js +534 -0
  52. package/dist/tools/gemini-help.js.map +1 -0
  53. package/dist/tools/gemini-prompt-assistant.d.ts +20 -0
  54. package/dist/tools/gemini-prompt-assistant.d.ts.map +1 -0
  55. package/dist/tools/gemini-prompt-assistant.js +129 -0
  56. package/dist/tools/gemini-prompt-assistant.js.map +1 -0
  57. package/dist/tools/generate-landing-page.d.ts +15 -0
  58. package/dist/tools/generate-landing-page.d.ts.map +1 -0
  59. package/dist/tools/generate-landing-page.js +66 -0
  60. package/dist/tools/generate-landing-page.js.map +1 -0
  61. package/dist/tools/generate-svg.d.ts +14 -0
  62. package/dist/tools/generate-svg.d.ts.map +1 -0
  63. package/dist/tools/generate-svg.js +106 -0
  64. package/dist/tools/generate-svg.js.map +1 -0
  65. package/dist/tools/generate-video.d.ts +24 -0
  66. package/dist/tools/generate-video.d.ts.map +1 -0
  67. package/dist/tools/generate-video.js +163 -0
  68. package/dist/tools/generate-video.js.map +1 -0
  69. package/dist/tools/image-prompt-assistant.d.ts +3 -0
  70. package/dist/tools/image-prompt-assistant.d.ts.map +1 -0
  71. package/dist/tools/image-prompt-assistant.js +790 -0
  72. package/dist/tools/image-prompt-assistant.js.map +1 -0
  73. package/dist/tools/load-image-from-path.d.ts +11 -0
  74. package/dist/tools/load-image-from-path.d.ts.map +1 -0
  75. package/dist/tools/load-image-from-path.js +100 -0
  76. package/dist/tools/load-image-from-path.js.map +1 -0
  77. package/dist/tools/prompt-library/charts.d.ts +325 -0
  78. package/dist/tools/prompt-library/charts.d.ts.map +1 -0
  79. package/dist/tools/prompt-library/charts.js +384 -0
  80. package/dist/tools/prompt-library/charts.js.map +1 -0
  81. package/dist/tools/prompt-library/index.d.ts +8 -0
  82. package/dist/tools/prompt-library/index.d.ts.map +1 -0
  83. package/dist/tools/prompt-library/index.js +10 -0
  84. package/dist/tools/prompt-library/index.js.map +1 -0
  85. package/dist/tools/register-analyze-image.d.ts +3 -0
  86. package/dist/tools/register-analyze-image.d.ts.map +1 -0
  87. package/dist/tools/register-analyze-image.js +67 -0
  88. package/dist/tools/register-analyze-image.js.map +1 -0
  89. package/dist/tools/register-chat.d.ts +3 -0
  90. package/dist/tools/register-chat.d.ts.map +1 -0
  91. package/dist/tools/register-chat.js +71 -0
  92. package/dist/tools/register-chat.js.map +1 -0
  93. package/dist/tools/register-deep-research.d.ts +3 -0
  94. package/dist/tools/register-deep-research.d.ts.map +1 -0
  95. package/dist/tools/register-deep-research.js +59 -0
  96. package/dist/tools/register-deep-research.js.map +1 -0
  97. package/dist/tools/register-describe-image.d.ts +3 -0
  98. package/dist/tools/register-describe-image.d.ts.map +1 -0
  99. package/dist/tools/register-describe-image.js +59 -0
  100. package/dist/tools/register-describe-image.js.map +1 -0
  101. package/dist/tools/register-image-gen.d.ts +3 -0
  102. package/dist/tools/register-image-gen.d.ts.map +1 -0
  103. package/dist/tools/register-image-gen.js +235 -0
  104. package/dist/tools/register-image-gen.js.map +1 -0
  105. package/dist/tools/register-landing-page.d.ts +3 -0
  106. package/dist/tools/register-landing-page.d.ts.map +1 -0
  107. package/dist/tools/register-landing-page.js +79 -0
  108. package/dist/tools/register-landing-page.js.map +1 -0
  109. package/dist/tools/register-list-models.d.ts +3 -0
  110. package/dist/tools/register-list-models.d.ts.map +1 -0
  111. package/dist/tools/register-list-models.js +33 -0
  112. package/dist/tools/register-list-models.js.map +1 -0
  113. package/dist/tools/register-load-image.d.ts +3 -0
  114. package/dist/tools/register-load-image.d.ts.map +1 -0
  115. package/dist/tools/register-load-image.js +66 -0
  116. package/dist/tools/register-load-image.js.map +1 -0
  117. package/dist/tools/register-svg.d.ts +3 -0
  118. package/dist/tools/register-svg.d.ts.map +1 -0
  119. package/dist/tools/register-svg.js +84 -0
  120. package/dist/tools/register-svg.js.map +1 -0
  121. package/dist/tools/register-video.d.ts +3 -0
  122. package/dist/tools/register-video.d.ts.map +1 -0
  123. package/dist/tools/register-video.js +118 -0
  124. package/dist/tools/register-video.js.map +1 -0
  125. package/dist/tools/register-viewers.d.ts +8 -0
  126. package/dist/tools/register-viewers.d.ts.map +1 -0
  127. package/dist/tools/register-viewers.js +89 -0
  128. package/dist/tools/register-viewers.js.map +1 -0
  129. package/dist/tools/schemas.d.ts +33 -0
  130. package/dist/tools/schemas.d.ts.map +1 -0
  131. package/dist/tools/schemas.js +39 -0
  132. package/dist/tools/schemas.js.map +1 -0
  133. package/dist/tools/types.d.ts +12 -0
  134. package/dist/tools/types.d.ts.map +1 -0
  135. package/dist/tools/types.js +2 -0
  136. package/dist/tools/types.js.map +1 -0
  137. package/dist/ui/image-viewer.d.ts +2 -0
  138. package/dist/ui/image-viewer.d.ts.map +1 -0
  139. package/dist/ui/image-viewer.js +42 -0
  140. package/dist/ui/image-viewer.js.map +1 -0
  141. package/dist/utils/chart-design-system.d.ts +92 -0
  142. package/dist/utils/chart-design-system.d.ts.map +1 -0
  143. package/dist/utils/chart-design-system.js +235 -0
  144. package/dist/utils/chart-design-system.js.map +1 -0
  145. package/dist/utils/image-compress.d.ts +9 -0
  146. package/dist/utils/image-compress.d.ts.map +1 -0
  147. package/dist/utils/image-compress.js +43 -0
  148. package/dist/utils/image-compress.js.map +1 -0
  149. package/dist/utils/image-utils.d.ts +9 -0
  150. package/dist/utils/image-utils.d.ts.map +1 -0
  151. package/dist/utils/image-utils.js +257 -0
  152. package/dist/utils/image-utils.js.map +1 -0
  153. package/dist/utils/resolve-images.d.ts +29 -0
  154. package/dist/utils/resolve-images.d.ts.map +1 -0
  155. package/dist/utils/resolve-images.js +56 -0
  156. package/dist/utils/resolve-images.js.map +1 -0
  157. package/dist/utils/tool-wrapper.d.ts +13 -0
  158. package/dist/utils/tool-wrapper.d.ts.map +1 -0
  159. package/dist/utils/tool-wrapper.js +22 -0
  160. package/dist/utils/tool-wrapper.js.map +1 -0
  161. package/dist/utils/video-utils.d.ts +16 -0
  162. package/dist/utils/video-utils.d.ts.map +1 -0
  163. package/dist/utils/video-utils.js +319 -0
  164. package/dist/utils/video-utils.js.map +1 -0
  165. package/dist/video-viewer/src/ui/video-viewer.html +310 -0
  166. package/package.json +21 -7
  167. package/server.json +30 -29
@@ -0,0 +1,84 @@
1
+ import * as z from 'zod';
2
+ import { registerAppTool } from '@modelcontextprotocol/ext-apps/server';
3
+ import { writeFile, mkdir } from 'fs/promises';
4
+ import { dirname, resolve } from 'path';
5
+ import logger from '../utils/logger.js';
6
+ import { McpError, createToolResult } from '../utils/error-handler.js';
7
+ import { savedFileMessage } from '../utils/tool-wrapper.js';
8
+ import { GenerateSVGTool } from './generate-svg.js';
9
+ export function register(ctx) {
10
+ const svgTool = new GenerateSVGTool(ctx.geminiService);
11
+ registerAppTool(ctx.server, 'generate_svg', {
12
+ title: 'Generate SVG Graphic',
13
+ description: 'Generate scalable vector graphics (SVG) using Gemini. ' +
14
+ 'Creates clean, production-ready SVG code for diagrams, illustrations, icons, and data visualizations. ' +
15
+ 'Returns inline preview with SVG viewer.',
16
+ inputSchema: {
17
+ prompt: z.string().describe('Description of the SVG graphic to generate'),
18
+ width: z.number()
19
+ .optional()
20
+ .default(800)
21
+ .describe('SVG width in pixels (default: 800)'),
22
+ height: z.number()
23
+ .optional()
24
+ .default(600)
25
+ .describe('SVG height in pixels (default: 600)'),
26
+ style: z.enum(['technical', 'artistic', 'minimal', 'data-viz'])
27
+ .optional()
28
+ .default('technical')
29
+ .describe('Visual style: technical (diagrams), artistic (illustrations), minimal (simple), data-viz (charts)'),
30
+ model: z.string()
31
+ .optional()
32
+ .describe('Gemini model to use (defaults to configured default)'),
33
+ outputPath: z.string()
34
+ .optional()
35
+ .describe('Optional file path to save the SVG (e.g. C:/output/diagram.svg)'),
36
+ },
37
+ _meta: {
38
+ ui: { resourceUri: 'ui://gemini/svg-viewer.html' }
39
+ }
40
+ }, async ({ prompt, width, height, style, model, outputPath }) => {
41
+ try {
42
+ logger.info('Executing generate_svg tool', { style, dimensions: `${width}x${height}`, model });
43
+ const svgContent = await svgTool.execute({
44
+ prompt,
45
+ width,
46
+ height,
47
+ style,
48
+ model,
49
+ });
50
+ const absolutePath = outputPath
51
+ ? resolve(outputPath)
52
+ : resolve(ctx.outputDir, `gemini-${Date.now()}.svg`);
53
+ await mkdir(dirname(absolutePath), { recursive: true });
54
+ await writeFile(absolutePath, svgContent, 'utf-8');
55
+ logger.info('SVG saved successfully', { savedPath: absolutePath });
56
+ return {
57
+ structuredContent: {
58
+ svgContent,
59
+ mimeType: 'image/svg+xml',
60
+ savedPath: absolutePath,
61
+ description: `${style} style SVG graphic (${width}x${height})`,
62
+ prompt
63
+ },
64
+ content: [
65
+ {
66
+ type: 'text',
67
+ text: savedFileMessage('SVG saved', absolutePath)
68
+ }
69
+ ]
70
+ };
71
+ }
72
+ catch (error) {
73
+ logger.error('generate_svg tool failed', { error });
74
+ const msg = error instanceof McpError
75
+ ? error.message
76
+ : `Failed to generate SVG: ${error.message}`;
77
+ return {
78
+ content: createToolResult(false, msg, error),
79
+ structuredContent: { content: msg, success: false },
80
+ };
81
+ }
82
+ });
83
+ }
84
+ //# sourceMappingURL=register-svg.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-svg.js","sourceRoot":"","sources":["../../src/tools/register-svg.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ToolContext } from './types.js';
2
+ export declare function register(ctx: ToolContext): void;
3
+ //# sourceMappingURL=register-video.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-video.d.ts","sourceRoot":"","sources":["../../src/tools/register-video.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,wBAAgB,QAAQ,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CA+H/C"}
@@ -0,0 +1,118 @@
1
+ import * as z from 'zod';
2
+ import { registerAppTool } from '@modelcontextprotocol/ext-apps/server';
3
+ import logger from '../utils/logger.js';
4
+ import { toolError } from '../utils/tool-wrapper.js';
5
+ import { GenerateVideoTool } from './generate-video.js';
6
+ import { imageInputSchema } from './schemas.js';
7
+ import { resolveImageInput } from '../utils/resolve-images.js';
8
+ export function register(ctx) {
9
+ registerAppTool(ctx.server, 'generate_video', {
10
+ title: 'Generate Video',
11
+ description: 'Generate videos using Google Veo 3.1 AI model. Creates realistic 4-8 second videos from text prompts ' +
12
+ 'with optional first-frame image and reference images for character/style consistency. ' +
13
+ 'Supports native audio generation. Processing time: 2-5 minutes for 1080p videos. ' +
14
+ 'Returns video file path with optional thumbnail and HTML preview player. ' +
15
+ '\u26a0\ufe0f IMPORTANT: Video generation is ASYNC and takes 2-5 minutes. The tool will poll for completion automatically.',
16
+ inputSchema: {
17
+ prompt: z.string().describe('Detailed description of the video to generate. Be specific about actions, camera movements, lighting, and style. ' +
18
+ 'Example: "A close-up shot of a futuristic coffee machine brewing a glowing blue espresso, with steam rising dramatically. Cinematic lighting, 4K quality."'),
19
+ model: z.string().optional().default('veo-3.1-generate-preview')
20
+ .describe('Video generation model (default: veo-3.1-generate-preview)'),
21
+ aspectRatio: z.enum(['16:9', '9:16']).optional().default('16:9')
22
+ .describe('Video aspect ratio: 16:9 (landscape) or 9:16 (portrait/vertical)'),
23
+ resolution: z.enum(['720p', '1080p', '4k']).optional().default('1080p')
24
+ .describe('Video resolution. Higher resolutions take longer to generate and result in larger files.'),
25
+ durationSeconds: z.union([z.literal(4), z.literal(6), z.literal(8)]).optional().default(8)
26
+ .describe('Video duration in seconds (4, 6, or 8 seconds)'),
27
+ generateAudio: z.boolean().optional().default(true)
28
+ .describe('Generate native synchronized audio effects and dialogue based on the prompt'),
29
+ sampleCount: z.number().min(1).max(4).optional().default(1)
30
+ .describe('Number of video samples to generate (1-4). Each sample is a separate generation.'),
31
+ seed: z.number().optional()
32
+ .describe('Optional seed for deterministic output. Use the same seed with the same prompt for consistent results.'),
33
+ outputPath: z.string().optional()
34
+ .describe('Optional custom output path for the video file (e.g., C:/videos/output.mp4). If not provided, saves to default output directory with timestamped filename.'),
35
+ generateThumbnail: z.boolean().optional().default(true)
36
+ .describe('Extract thumbnail from video (requires ffmpeg installed). Thumbnail is saved alongside video.'),
37
+ generateHTMLPlayer: z.boolean().optional().default(true)
38
+ .describe('Generate interactive HTML video player with preview and download options'),
39
+ firstFrameImage: imageInputSchema
40
+ .optional()
41
+ .describe('Starting frame image for image-to-video generation. Provide via filePath (local file) or data+mimeType (base64). ' +
42
+ 'The video will animate from this image. Supports JPEG, PNG, WebP.'),
43
+ referenceImages: z.array(z.object({
44
+ referenceType: z.enum(['asset', 'style']).describe('Type of reference: "asset" for character/object consistency, "style" for visual style transfer'),
45
+ image: imageInputSchema.describe('The reference image (filePath or base64 data)')
46
+ }))
47
+ .max(3)
48
+ .optional()
49
+ .describe('Up to 3 reference images for character/style consistency. Each needs a referenceType ("asset" or "style") and an image.')
50
+ },
51
+ _meta: {
52
+ ui: { resourceUri: 'ui://gemini/video-viewer.html' }
53
+ }
54
+ }, async ({ prompt, model, aspectRatio, resolution, durationSeconds, generateAudio, sampleCount, seed, outputPath, generateThumbnail, generateHTMLPlayer, firstFrameImage, referenceImages }) => {
55
+ try {
56
+ logger.info('Executing generate_video tool', {
57
+ prompt: prompt.slice(0, 100),
58
+ duration: durationSeconds || 8,
59
+ resolution: resolution || '1080p',
60
+ hasFirstFrame: !!firstFrameImage,
61
+ referenceImageCount: referenceImages?.length || 0
62
+ });
63
+ // Resolve first-frame image from filePath if provided
64
+ let resolvedFirstFrame;
65
+ if (firstFrameImage) {
66
+ const resolved = await resolveImageInput(firstFrameImage);
67
+ resolvedFirstFrame = { data: resolved.data, mimeType: resolved.mimeType };
68
+ }
69
+ // Resolve reference images from filePaths if provided
70
+ let resolvedReferenceImages;
71
+ if (referenceImages?.length) {
72
+ resolvedReferenceImages = await Promise.all(referenceImages.map(async (ref) => {
73
+ const resolved = await resolveImageInput(ref.image);
74
+ return {
75
+ referenceType: ref.referenceType,
76
+ image: { data: resolved.data, mimeType: resolved.mimeType }
77
+ };
78
+ }));
79
+ }
80
+ const videoTool = new GenerateVideoTool(ctx.geminiService);
81
+ const { content, metadata } = await videoTool.execute({
82
+ prompt,
83
+ model,
84
+ aspectRatio,
85
+ resolution,
86
+ durationSeconds,
87
+ generateAudio,
88
+ sampleCount,
89
+ seed,
90
+ outputPath,
91
+ generateThumbnail,
92
+ generateHTMLPlayer,
93
+ firstFrameImage: resolvedFirstFrame,
94
+ referenceImages: resolvedReferenceImages
95
+ });
96
+ // Enrich with media server URLs for inline playback in the viewer
97
+ const enriched = { ...metadata };
98
+ if (metadata.videoPath) {
99
+ const videoUrl = ctx.mediaServer.getFileUrl(metadata.videoPath);
100
+ if (videoUrl)
101
+ enriched.videoUrl = videoUrl;
102
+ }
103
+ if (metadata.thumbnailPath) {
104
+ const thumbUrl = ctx.mediaServer.getFileUrl(metadata.thumbnailPath);
105
+ if (thumbUrl)
106
+ enriched.thumbnailUrl = thumbUrl;
107
+ }
108
+ return {
109
+ content,
110
+ structuredContent: enriched
111
+ };
112
+ }
113
+ catch (error) {
114
+ return toolError('generate_video', error);
115
+ }
116
+ });
117
+ }
118
+ //# sourceMappingURL=register-video.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-video.js","sourceRoot":"","sources":["../../src/tools/register-video.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ /**
3
+ * Register all MCP App viewer resources from a data-driven spec.
4
+ * When a mediaServerPort is provided, viewers that need it get CSP whitelisting
5
+ * to load media from the localhost server.
6
+ */
7
+ export declare function registerViewers(server: McpServer, distDir: string, mediaServerPort?: number): Promise<void>;
8
+ //# sourceMappingURL=register-viewers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-viewers.d.ts","sourceRoot":"","sources":["../../src/tools/register-viewers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA+CpE;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,MAAM,EACf,eAAe,CAAC,EAAE,MAAM,GACvB,OAAO,CAAC,IAAI,CAAC,CAgEf"}
@@ -0,0 +1,89 @@
1
+ import { registerAppResource, RESOURCE_MIME_TYPE } from '@modelcontextprotocol/ext-apps/server';
2
+ import { readFile } from 'fs/promises';
3
+ import { join } from 'path';
4
+ import logger from '../utils/logger.js';
5
+ const VIEWERS = [
6
+ {
7
+ name: 'Image Viewer',
8
+ resourceId: 'gemini-image-viewer',
9
+ uri: 'ui://gemini/image-viewer.html',
10
+ segments: ['image-viewer', 'src', 'ui', 'image-viewer.html'],
11
+ },
12
+ {
13
+ name: 'Video Viewer',
14
+ resourceId: 'gemini-video-viewer',
15
+ uri: 'ui://gemini/video-viewer.html',
16
+ segments: ['video-viewer', 'src', 'ui', 'video-viewer.html'],
17
+ needsMediaServer: true,
18
+ },
19
+ {
20
+ name: 'SVG Viewer',
21
+ resourceId: 'gemini-svg-viewer',
22
+ uri: 'ui://gemini/svg-viewer.html',
23
+ segments: ['svg-viewer', 'src', 'ui', 'svg-viewer.html'],
24
+ },
25
+ {
26
+ name: 'Landing Page Viewer',
27
+ resourceId: 'gemini-landing-page-viewer',
28
+ uri: 'ui://gemini/landing-page-viewer.html',
29
+ segments: ['landing-page-viewer', 'src', 'ui', 'landing-page-viewer.html'],
30
+ },
31
+ ];
32
+ /**
33
+ * Register all MCP App viewer resources from a data-driven spec.
34
+ * When a mediaServerPort is provided, viewers that need it get CSP whitelisting
35
+ * to load media from the localhost server.
36
+ */
37
+ export async function registerViewers(server, distDir, mediaServerPort) {
38
+ const mediaOrigin = mediaServerPort
39
+ ? `http://127.0.0.1:${mediaServerPort}`
40
+ : undefined;
41
+ const results = await Promise.allSettled(VIEWERS.map(async (v) => {
42
+ const htmlPath = join(distDir, ...v.segments);
43
+ const html = await readFile(htmlPath, 'utf-8');
44
+ // Build CSP metadata for viewers that need media server access
45
+ const needsCsp = v.needsMediaServer && mediaOrigin;
46
+ const contentMeta = needsCsp
47
+ ? {
48
+ _meta: {
49
+ ui: {
50
+ csp: {
51
+ resourceDomains: [mediaOrigin],
52
+ connectDomains: [mediaOrigin],
53
+ },
54
+ },
55
+ },
56
+ }
57
+ : {};
58
+ registerAppResource(server, v.resourceId, v.uri, {}, async () => ({
59
+ contents: [{
60
+ uri: v.uri,
61
+ mimeType: RESOURCE_MIME_TYPE,
62
+ text: html,
63
+ ...contentMeta,
64
+ }],
65
+ }));
66
+ return v.name;
67
+ }));
68
+ const succeeded = results
69
+ .filter((r) => r.status === 'fulfilled')
70
+ .map((r) => r.value);
71
+ const failed = results
72
+ .map((r, i) => ({ result: r, spec: VIEWERS[i] }))
73
+ .filter((x) => x.result.status === 'rejected');
74
+ logger.info('Viewer registration complete', {
75
+ succeeded: succeeded.length,
76
+ failed: failed.length,
77
+ available: succeeded,
78
+ mediaServerCsp: mediaOrigin || 'none',
79
+ });
80
+ if (failed.length > 0) {
81
+ for (const { spec, result } of failed) {
82
+ logger.warn(`Failed to load ${spec.name} viewer - inline preview will not be available`, {
83
+ viewer: spec.name,
84
+ error: result.reason,
85
+ });
86
+ }
87
+ }
88
+ }
89
+ //# sourceMappingURL=register-viewers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-viewers.js","sourceRoot":"","sources":["../../src/tools/register-viewers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import * as z from 'zod';
2
+ /**
3
+ * Shared Zod schema for image input, used by describe_image, analyze_image,
4
+ * generate_image (reference images), and edit_image.
5
+ *
6
+ * Images can be provided in two ways:
7
+ * 1. Inline base64: set `data` (base64 string) and `mimeType`
8
+ * 2. File path: set `filePath` — the tool loads the image server-side,
9
+ * bypassing the MCP transport limit entirely.
10
+ *
11
+ * Use `filePath` for large images (>1 MB) to avoid MCP transport failures.
12
+ * The `load_image_from_path` tool returns a filePath you can pass directly.
13
+ */
14
+ export declare const imageInputSchema: z.ZodObject<{
15
+ data: z.ZodOptional<z.ZodString>;
16
+ filePath: z.ZodOptional<z.ZodString>;
17
+ mimeType: z.ZodOptional<z.ZodString>;
18
+ thoughtSignature: z.ZodOptional<z.ZodString>;
19
+ mediaResolution: z.ZodOptional<z.ZodEnum<["MEDIA_RESOLUTION_LOW", "MEDIA_RESOLUTION_MEDIUM", "MEDIA_RESOLUTION_HIGH", "MEDIA_RESOLUTION_ULTRA_HIGH"]>>;
20
+ }, "strip", z.ZodTypeAny, {
21
+ mimeType?: string;
22
+ data?: string;
23
+ thoughtSignature?: string;
24
+ mediaResolution?: "MEDIA_RESOLUTION_LOW" | "MEDIA_RESOLUTION_MEDIUM" | "MEDIA_RESOLUTION_HIGH" | "MEDIA_RESOLUTION_ULTRA_HIGH";
25
+ filePath?: string;
26
+ }, {
27
+ mimeType?: string;
28
+ data?: string;
29
+ thoughtSignature?: string;
30
+ mediaResolution?: "MEDIA_RESOLUTION_LOW" | "MEDIA_RESOLUTION_MEDIUM" | "MEDIA_RESOLUTION_HIGH" | "MEDIA_RESOLUTION_ULTRA_HIGH";
31
+ filePath?: string;
32
+ }>;
33
+ //# sourceMappingURL=schemas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/tools/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;EA8B3B,CAAC"}
@@ -0,0 +1,39 @@
1
+ import * as z from 'zod';
2
+ /**
3
+ * Shared Zod schema for image input, used by describe_image, analyze_image,
4
+ * generate_image (reference images), and edit_image.
5
+ *
6
+ * Images can be provided in two ways:
7
+ * 1. Inline base64: set `data` (base64 string) and `mimeType`
8
+ * 2. File path: set `filePath` — the tool loads the image server-side,
9
+ * bypassing the MCP transport limit entirely.
10
+ *
11
+ * Use `filePath` for large images (>1 MB) to avoid MCP transport failures.
12
+ * The `load_image_from_path` tool returns a filePath you can pass directly.
13
+ */
14
+ export const imageInputSchema = z.object({
15
+ data: z.string()
16
+ .optional()
17
+ .describe('Base64 encoded image data'),
18
+ filePath: z.string()
19
+ .optional()
20
+ .describe('Local file path to the image (alternative to base64 data). ' +
21
+ 'The image is loaded server-side, bypassing MCP transport limits. ' +
22
+ 'Use the filePath returned by load_image_from_path.'),
23
+ mimeType: z.string()
24
+ .optional()
25
+ .describe('MIME type of the image (e.g., image/png, image/jpeg). Required when using data, auto-detected from filePath.'),
26
+ thoughtSignature: z.string()
27
+ .optional()
28
+ .describe('Thought signature from a previous generate_image or edit_image call. ' +
29
+ 'Required for conversational editing with Gemini 3 Pro Image. ' +
30
+ 'Pass the thoughtSignature from the previous response to maintain edit context.'),
31
+ mediaResolution: z.enum([
32
+ 'MEDIA_RESOLUTION_LOW',
33
+ 'MEDIA_RESOLUTION_MEDIUM',
34
+ 'MEDIA_RESOLUTION_HIGH',
35
+ 'MEDIA_RESOLUTION_ULTRA_HIGH'
36
+ ]).optional().describe('Per-image resolution override. LOW=280 tokens (75% savings), MEDIUM=560 tokens (50% savings), ' +
37
+ 'HIGH=1120 tokens (default), ULTRA_HIGH=2000+ tokens (max detail, per-image only)')
38
+ });
39
+ //# sourceMappingURL=schemas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/tools/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;SACb,QAAQ,EAAE;SACV,QAAQ,CAAC,2BAA2B,CAAC;IACxC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;SACjB,QAAQ,EAAE;SACV,QAAQ,CACP,6DAA6D;QAC7D,mEAAmE;QACnE,oDAAoD,CACrD;IACH,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;SACjB,QAAQ,EAAE;SACV,QAAQ,CAAC,8GAA8G,CAAC;IAC3H,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE;SACzB,QAAQ,EAAE;SACV,QAAQ,CACP,uEAAuE;QACvE,+DAA+D;QAC/D,gFAAgF,CACjF;IACH,eAAe,EAAE,CAAC,CAAC,IAAI,CAAC;QACtB,sBAAsB;QACtB,yBAAyB;QACzB,uBAAuB;QACvB,6BAA6B;KAC9B,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CACpB,gGAAgG;QAChG,kFAAkF,CACnF;CACF,CAAC,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { GeminiService } from '../services/gemini/index.js';
3
+ import { GeminiImageService } from '../services/gemini/image-service.js';
4
+ import { MediaServer } from '../services/media-server.js';
5
+ export interface ToolContext {
6
+ server: McpServer;
7
+ geminiService: GeminiService;
8
+ imageService: GeminiImageService;
9
+ outputDir: string;
10
+ mediaServer: MediaServer;
11
+ }
12
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/tools/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAE1D,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,SAAS,CAAC;IAClB,aAAa,EAAE,aAAa,CAAC;IAC7B,YAAY,EAAE,kBAAkB,CAAC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,WAAW,CAAC;CAC1B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/tools/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=image-viewer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-viewer.d.ts","sourceRoot":"","sources":["../../src/ui/image-viewer.ts"],"names":[],"mappings":""}
@@ -0,0 +1,42 @@
1
+ import { App } from '@modelcontextprotocol/ext-apps';
2
+ const app = new App({ name: 'Gemini Image Viewer', version: '1.0.0' });
3
+ app.ontoolresult = (result) => {
4
+ const data = result.structuredContent;
5
+ if (!data || !data.base64Data)
6
+ return;
7
+ render(data);
8
+ };
9
+ app.connect();
10
+ function render(data) {
11
+ const loading = document.getElementById('loading');
12
+ const content = document.getElementById('content');
13
+ const img = document.getElementById('img');
14
+ const pathDisplay = document.getElementById('path-display');
15
+ const copyBtn = document.getElementById('copy-btn');
16
+ const descEl = document.getElementById('desc');
17
+ img.src = `data:${data.mimeType};base64,${data.base64Data}`;
18
+ if (data.savedPath) {
19
+ pathDisplay.textContent = data.savedPath;
20
+ copyBtn.style.display = 'block';
21
+ copyBtn.addEventListener('click', () => {
22
+ navigator.clipboard.writeText(data.savedPath).then(() => {
23
+ copyBtn.textContent = 'Copied!';
24
+ copyBtn.classList.add('copied');
25
+ setTimeout(() => {
26
+ copyBtn.textContent = 'Copy path';
27
+ copyBtn.classList.remove('copied');
28
+ }, 2000);
29
+ });
30
+ });
31
+ }
32
+ else {
33
+ pathDisplay.innerHTML = '<span class="no-path">Not saved to disk</span>';
34
+ }
35
+ if (data.description) {
36
+ descEl.textContent = data.description;
37
+ descEl.style.display = 'block';
38
+ }
39
+ loading.style.display = 'none';
40
+ content.style.display = 'block';
41
+ }
42
+ //# sourceMappingURL=image-viewer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-viewer.js","sourceRoot":"","sources":["../../src/ui/image-viewer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,gCAAgC,CAAC;AASrD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,EAAE,IAAI,EAAE,qBAAqB,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;AAEvE,GAAG,CAAC,YAAY,GAAG,CAAC,MAA2C,EAAE,EAAE;IACjE,MAAM,IAAI,GAAG,MAAM,CAAC,iBAAiB,CAAC;IACtC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU;QAAE,OAAO;IACtC,MAAM,CAAC,IAAI,CAAC,CAAC;AACf,CAAC,CAAC;AAEF,GAAG,CAAC,OAAO,EAAE,CAAC;AAEd,SAAS,MAAM,CAAC,IAAiB;IAC/B,MAAM,OAAO,GAAG,QAAQ,CAAC,cAAc,CAAC,SAAS,CAAE,CAAC;IACpD,MAAM,OAAO,GAAG,QAAQ,CAAC,cAAc,CAAC,SAAS,CAAE,CAAC;IACpD,MAAM,GAAG,GAAG,QAAQ,CAAC,cAAc,CAAC,KAAK,CAAqB,CAAC;IAC/D,MAAM,WAAW,GAAG,QAAQ,CAAC,cAAc,CAAC,cAAc,CAAE,CAAC;IAC7D,MAAM,OAAO,GAAG,QAAQ,CAAC,cAAc,CAAC,UAAU,CAAsB,CAAC;IACzE,MAAM,MAAM,GAAG,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAE,CAAC;IAEhD,GAAG,CAAC,GAAG,GAAG,QAAQ,IAAI,CAAC,QAAQ,WAAW,IAAI,CAAC,UAAU,EAAE,CAAC;IAE5D,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QACnB,WAAW,CAAC,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC;QACzC,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;QAChC,OAAO,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE;YACrC,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,SAAU,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;gBACvD,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;gBAChC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;gBAChC,UAAU,CAAC,GAAG,EAAE;oBACd,OAAO,CAAC,WAAW,GAAG,WAAW,CAAC;oBAClC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;gBACrC,CAAC,EAAE,IAAI,CAAC,CAAC;YACX,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,WAAW,CAAC,SAAS,GAAG,gDAAgD,CAAC;IAC3E,CAAC;IAED,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;QACtC,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;IACjC,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;IAC/B,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;AAClC,CAAC"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Professional Chart & Data Visualization Design System
3
+ *
4
+ * Based on research from Observable, D3.js, Information is Beautiful,
5
+ * and modern dashboard design systems.
6
+ *
7
+ * Purpose: Enhance prompts with professional design principles to avoid
8
+ * generic AI-generated aesthetics.
9
+ */
10
+ export interface ChartStyleOptions {
11
+ colorScheme?: 'professional' | 'editorial' | 'scientific' | 'minimal' | 'dark';
12
+ chartType?: 'line' | 'bar' | 'scatter' | 'area' | 'pie' | 'network' | 'heatmap' | 'treemap';
13
+ emphasis?: 'data-ink' | 'storytelling' | 'exploration' | 'presentation';
14
+ }
15
+ /**
16
+ * Professional color palettes based on industry standards
17
+ */
18
+ declare const COLOR_SYSTEMS: {
19
+ professional: {
20
+ primary: string[];
21
+ neutral: string[];
22
+ accent: string[];
23
+ description: string;
24
+ };
25
+ editorial: {
26
+ primary: string[];
27
+ neutral: string[];
28
+ accent: string[];
29
+ description: string;
30
+ };
31
+ scientific: {
32
+ primary: string[];
33
+ neutral: string[];
34
+ accent: string[];
35
+ description: string;
36
+ };
37
+ minimal: {
38
+ primary: string[];
39
+ neutral: string[];
40
+ accent: string[];
41
+ description: string;
42
+ };
43
+ dark: {
44
+ primary: string[];
45
+ neutral: string[];
46
+ accent: string[];
47
+ description: string;
48
+ };
49
+ };
50
+ /**
51
+ * Generate professional design prompt enhancement
52
+ */
53
+ export declare function enhanceChartPrompt(basePrompt: string, options?: ChartStyleOptions): string;
54
+ /**
55
+ * Get color palette for a specific scheme
56
+ */
57
+ export declare function getColorPalette(scheme: keyof typeof COLOR_SYSTEMS): {
58
+ primary: string[];
59
+ neutral: string[];
60
+ accent: string[];
61
+ description: string;
62
+ } | {
63
+ primary: string[];
64
+ neutral: string[];
65
+ accent: string[];
66
+ description: string;
67
+ } | {
68
+ primary: string[];
69
+ neutral: string[];
70
+ accent: string[];
71
+ description: string;
72
+ } | {
73
+ primary: string[];
74
+ neutral: string[];
75
+ accent: string[];
76
+ description: string;
77
+ } | {
78
+ primary: string[];
79
+ neutral: string[];
80
+ accent: string[];
81
+ description: string;
82
+ };
83
+ /**
84
+ * Validate chart design prompt for common issues
85
+ */
86
+ export declare function validateChartPrompt(prompt: string): {
87
+ valid: boolean;
88
+ warnings: string[];
89
+ suggestions: string[];
90
+ };
91
+ export {};
92
+ //# sourceMappingURL=chart-design-system.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chart-design-system.d.ts","sourceRoot":"","sources":["../../src/utils/chart-design-system.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,EAAE,cAAc,GAAG,WAAW,GAAG,YAAY,GAAG,SAAS,GAAG,MAAM,CAAC;IAC/E,SAAS,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;IAC5F,QAAQ,CAAC,EAAE,UAAU,GAAG,cAAc,GAAG,aAAa,GAAG,cAAc,CAAC;CACzE;AAED;;GAEG;AACH,QAAA,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+BlB,CAAC;AA+GF;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,iBAAsB,GAC9B,MAAM,CAuDR;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,OAAO,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;EAEjE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG;IACnD,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB,CA4BA"}