@houtini/gemini-mcp 1.4.2 → 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 (171) hide show
  1. package/README.md +314 -784
  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/logger.d.ts.map +1 -1
  154. package/dist/utils/logger.js +45 -11
  155. package/dist/utils/logger.js.map +1 -1
  156. package/dist/utils/resolve-images.d.ts +29 -0
  157. package/dist/utils/resolve-images.d.ts.map +1 -0
  158. package/dist/utils/resolve-images.js +56 -0
  159. package/dist/utils/resolve-images.js.map +1 -0
  160. package/dist/utils/tool-wrapper.d.ts +13 -0
  161. package/dist/utils/tool-wrapper.d.ts.map +1 -0
  162. package/dist/utils/tool-wrapper.js +22 -0
  163. package/dist/utils/tool-wrapper.js.map +1 -0
  164. package/dist/utils/video-utils.d.ts +16 -0
  165. package/dist/utils/video-utils.d.ts.map +1 -0
  166. package/dist/utils/video-utils.js +319 -0
  167. package/dist/utils/video-utils.js.map +1 -0
  168. package/dist/video-viewer/src/ui/video-viewer.html +310 -0
  169. package/houtini-logo.jpg +0 -0
  170. package/package.json +24 -8
  171. package/server.json +30 -0
@@ -0,0 +1,59 @@
1
+ import * as z from 'zod';
2
+ import logger from '../utils/logger.js';
3
+ import { toolError } from '../utils/tool-wrapper.js';
4
+ import { GeminiDeepResearchTool } from './gemini-deep-research.js';
5
+ export function register(ctx) {
6
+ ctx.server.registerTool('gemini_deep_research', {
7
+ title: 'Gemini Deep Research',
8
+ description: 'Conduct deep research on complex topics using iterative multi-step analysis with Gemini. ' +
9
+ 'This performs multiple searches and synthesizes comprehensive research reports (takes several minutes). ' +
10
+ '[MCP_RECOMMENDED_TIMEOUT_MS: 900000]',
11
+ inputSchema: {
12
+ research_question: z.string().describe('The complex research question or topic to investigate deeply'),
13
+ model: z.string()
14
+ .optional()
15
+ .describe('Model to use for deep research (defaults to latest available)'),
16
+ max_iterations: z.number()
17
+ .int()
18
+ .min(3)
19
+ .max(10)
20
+ .optional()
21
+ .default(5)
22
+ .describe('Number of research iterations (3-10, default 5). Environment guidance: ' +
23
+ 'Claude Desktop: use 3-4 (4-min timeout). ' +
24
+ 'Agent SDK/IDEs (VSCode, Cursor, Windsurf)/AI platforms (Cline, Roo-Cline): can use 7-10 (longer timeout tolerance)'),
25
+ focus_areas: z.array(z.string())
26
+ .optional()
27
+ .describe('Optional: specific areas to focus the research on')
28
+ },
29
+ outputSchema: {
30
+ content: z.string(),
31
+ success: z.boolean()
32
+ }
33
+ }, async ({ research_question, model, max_iterations, focus_areas }) => {
34
+ try {
35
+ logger.info('Starting deep research', {
36
+ question: research_question,
37
+ maxIterations: max_iterations || 5
38
+ });
39
+ const deepResearchTool = new GeminiDeepResearchTool(ctx.geminiService);
40
+ const result = await deepResearchTool.execute({
41
+ research_question,
42
+ model,
43
+ max_iterations,
44
+ focus_areas
45
+ });
46
+ return {
47
+ content: result,
48
+ structuredContent: {
49
+ content: result[0]?.text || 'Research completed',
50
+ success: true
51
+ }
52
+ };
53
+ }
54
+ catch (error) {
55
+ return toolError('gemini_deep_research', error);
56
+ }
57
+ });
58
+ }
59
+ //# sourceMappingURL=register-deep-research.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-deep-research.js","sourceRoot":"","sources":["../../src/tools/register-deep-research.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAGnE,MAAM,UAAU,QAAQ,CAAC,GAAgB;IACvC,GAAG,CAAC,MAAM,CAAC,YAAY,CACrB,sBAAsB,EACtB;QACE,KAAK,EAAE,sBAAsB;QAC7B,WAAW,EACT,2FAA2F;YAC3F,0GAA0G;YAC1G,sCAAsC;QACxC,WAAW,EAAE;YACX,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,8DAA8D,CAAC;YACtG,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;iBACd,QAAQ,EAAE;iBACV,QAAQ,CAAC,+DAA+D,CAAC;YAC5E,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE;iBACvB,GAAG,EAAE;iBACL,GAAG,CAAC,CAAC,CAAC;iBACN,GAAG,CAAC,EAAE,CAAC;iBACP,QAAQ,EAAE;iBACV,OAAO,CAAC,CAAC,CAAC;iBACV,QAAQ,CACP,yEAAyE;gBACzE,2CAA2C;gBAC3C,oHAAoH,CACrH;YACH,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;iBAC7B,QAAQ,EAAE;iBACV,QAAQ,CAAC,mDAAmD,CAAC;SACjE;QACD,YAAY,EAAE;YACZ,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;YACnB,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;SACrB;KACF,EACD,KAAK,EAAE,EAAE,iBAAiB,EAAE,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,EAAE,EAAE;QAClE,IAAI,CAAC;YACH,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE;gBACpC,QAAQ,EAAE,iBAAiB;gBAC3B,aAAa,EAAE,cAAc,IAAI,CAAC;aACnC,CAAC,CAAC;YAEH,MAAM,gBAAgB,GAAG,IAAI,sBAAsB,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;YACvE,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,OAAO,CAAC;gBAC5C,iBAAiB;gBACjB,KAAK;gBACL,cAAc;gBACd,WAAW;aACZ,CAAC,CAAC;YAEH,OAAO;gBACL,OAAO,EAAE,MAAM;gBACf,iBAAiB,EAAE;oBACjB,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,oBAAoB;oBAChD,OAAO,EAAE,IAAI;iBACd;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,SAAS,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;QAClD,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ToolContext } from './types.js';
2
+ export declare function register(ctx: ToolContext): void;
3
+ //# sourceMappingURL=register-describe-image.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-describe-image.d.ts","sourceRoot":"","sources":["../../src/tools/register-describe-image.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,wBAAgB,QAAQ,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CA0D/C"}
@@ -0,0 +1,59 @@
1
+ import * as z from 'zod';
2
+ import logger from '../utils/logger.js';
3
+ import { createToolResult } from '../utils/error-handler.js';
4
+ import { toolError } from '../utils/tool-wrapper.js';
5
+ import { resolveImageInputs } from '../utils/resolve-images.js';
6
+ import { imageInputSchema } from './schemas.js';
7
+ export function register(ctx) {
8
+ ctx.server.registerTool('describe_image', {
9
+ title: 'Describe Image (Nano Banana Pro)',
10
+ description: 'Analyze and describe one or more images using Google Gemini image models (Nano Banana Pro). ' +
11
+ 'Returns a text description — no image is generated. Default model: gemini-3-flash-preview.',
12
+ inputSchema: {
13
+ images: z.array(imageInputSchema)
14
+ .min(1)
15
+ .describe('One or more images to describe/analyze'),
16
+ prompt: z.string()
17
+ .optional()
18
+ .describe('Optional custom analysis prompt (default: general description)'),
19
+ model: z.string()
20
+ .optional()
21
+ .describe('Gemini image model to use (default: gemini-3-flash-preview)'),
22
+ global_media_resolution: z.enum([
23
+ 'MEDIA_RESOLUTION_LOW',
24
+ 'MEDIA_RESOLUTION_MEDIUM',
25
+ 'MEDIA_RESOLUTION_HIGH'
26
+ ])
27
+ .optional()
28
+ .describe('Global image quality for cost optimization. MEDIUM recommended for PDFs (50% savings).'),
29
+ },
30
+ outputSchema: {
31
+ content: z.string(),
32
+ success: z.boolean(),
33
+ },
34
+ }, async ({ images, prompt, model, global_media_resolution }) => {
35
+ try {
36
+ logger.info('Executing describe_image tool', {
37
+ model,
38
+ imageCount: images.length,
39
+ globalMediaResolution: global_media_resolution
40
+ });
41
+ // Resolve filePath references server-side (bypasses MCP transport)
42
+ const resolved = await resolveImageInputs(images);
43
+ const description = await ctx.imageService.describeImage({
44
+ images: resolved,
45
+ prompt,
46
+ model,
47
+ globalMediaResolution: global_media_resolution
48
+ });
49
+ return {
50
+ content: createToolResult(true, description),
51
+ structuredContent: { content: description, success: true },
52
+ };
53
+ }
54
+ catch (error) {
55
+ return toolError('describe_image', error);
56
+ }
57
+ });
58
+ }
59
+ //# sourceMappingURL=register-describe-image.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-describe-image.js","sourceRoot":"","sources":["../../src/tools/register-describe-image.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGhD,MAAM,UAAU,QAAQ,CAAC,GAAgB;IACvC,GAAG,CAAC,MAAM,CAAC,YAAY,CACrB,gBAAgB,EAChB;QACE,KAAK,EAAE,kCAAkC;QACzC,WAAW,EACT,8FAA8F;YAC9F,4FAA4F;QAC9F,WAAW,EAAE;YACX,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC;iBAC9B,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CAAC,wCAAwC,CAAC;YACrD,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;iBACf,QAAQ,EAAE;iBACV,QAAQ,CAAC,gEAAgE,CAAC;YAC7E,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;iBACd,QAAQ,EAAE;iBACV,QAAQ,CAAC,6DAA6D,CAAC;YAC1E,uBAAuB,EAAE,CAAC,CAAC,IAAI,CAAC;gBAC9B,sBAAsB;gBACtB,yBAAyB;gBACzB,uBAAuB;aACxB,CAAC;iBACC,QAAQ,EAAE;iBACV,QAAQ,CAAC,wFAAwF,CAAC;SACtG;QACD,YAAY,EAAE;YACZ,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;YACnB,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;SACrB;KACF,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,uBAAuB,EAAE,EAAE,EAAE;QAC3D,IAAI,CAAC;YACH,MAAM,CAAC,IAAI,CAAC,+BAA+B,EAAE;gBAC3C,KAAK;gBACL,UAAU,EAAE,MAAM,CAAC,MAAM;gBACzB,qBAAqB,EAAE,uBAAuB;aAC/C,CAAC,CAAC;YAEH,mEAAmE;YACnE,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC,MAAa,CAAC,CAAC;YAEzD,MAAM,WAAW,GAAG,MAAM,GAAG,CAAC,YAAY,CAAC,aAAa,CAAC;gBACvD,MAAM,EAAE,QAAe;gBACvB,MAAM;gBACN,KAAK;gBACL,qBAAqB,EAAE,uBAA8B;aACtD,CAAC,CAAC;YAEH,OAAO;gBACL,OAAO,EAAE,gBAAgB,CAAC,IAAI,EAAE,WAAW,CAAC;gBAC5C,iBAAiB,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE;aAC3D,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,SAAS,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ToolContext } from './types.js';
2
+ export declare function register(ctx: ToolContext): void;
3
+ //# sourceMappingURL=register-image-gen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-image-gen.d.ts","sourceRoot":"","sources":["../../src/tools/register-image-gen.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AA8B9C,wBAAgB,QAAQ,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CA0P/C"}
@@ -0,0 +1,235 @@
1
+ import * as z from 'zod';
2
+ import { registerAppTool } from '@modelcontextprotocol/ext-apps/server';
3
+ import { resolve } from 'path';
4
+ import logger from '../utils/logger.js';
5
+ import { McpError, createToolResult } from '../utils/error-handler.js';
6
+ import { processGeneratedImage } from '../utils/image-utils.js';
7
+ import { resolveImageInputs } from '../utils/resolve-images.js';
8
+ import { savedFileMessage } from '../utils/tool-wrapper.js';
9
+ import { imageInputSchema } from './schemas.js';
10
+ function buildTextLines(savedPath, previewPath, description, groundingSources, thoughtSignature) {
11
+ const lines = [];
12
+ if (savedPath)
13
+ lines.push(savedFileMessage('Image saved', savedPath));
14
+ if (previewPath)
15
+ lines.push(savedFileMessage('HTML preview', previewPath));
16
+ if (description)
17
+ lines.push(`\n${description}`);
18
+ if (groundingSources && groundingSources.length > 0) {
19
+ lines.push('\n**Sources used for grounding:**');
20
+ groundingSources.forEach((source, idx) => {
21
+ lines.push(`${idx + 1}. [${source.title}](${source.url})`);
22
+ });
23
+ }
24
+ // Surface thoughtSignature so Claude can pass it to subsequent edit_image calls
25
+ // for conversational editing with Gemini 3 Pro Image
26
+ if (thoughtSignature) {
27
+ lines.push(`\n**thoughtSignature** (for conversational editing — pass to edit_image): \`${thoughtSignature}\``);
28
+ }
29
+ return lines;
30
+ }
31
+ export function register(ctx) {
32
+ registerAppTool(ctx.server, 'generate_image', {
33
+ title: 'Generate Image with Gemini',
34
+ description: 'Generate an image using Google Gemini image models (Nano Banana Pro). ' +
35
+ 'Returns image with inline preview in Claude Desktop and saves full-resolution to disk. ' +
36
+ 'Default model: gemini-3-pro-image-preview.',
37
+ inputSchema: {
38
+ prompt: z.string().describe('Description of the image to generate'),
39
+ model: z.string()
40
+ .optional()
41
+ .describe('Gemini image model to use (default: gemini-3-pro-image-preview). ' +
42
+ 'Options: gemini-3-pro-image-preview, gemini-2.5-flash-image, nano-banana-pro-preview'),
43
+ aspectRatio: z.enum(['1:1', '3:4', '4:3', '9:16', '16:9'])
44
+ .optional()
45
+ .default('1:1')
46
+ .describe('Aspect ratio of the generated image'),
47
+ imageSize: z.enum(['1K', '2K', '4K'])
48
+ .optional()
49
+ .describe('Resolution of the generated image (only for image-specific models)'),
50
+ images: z.array(imageInputSchema)
51
+ .optional()
52
+ .describe('Optional reference images to guide generation'),
53
+ use_search: z.boolean()
54
+ .optional()
55
+ .default(false)
56
+ .describe('Enable Google Search grounding for data-driven image generation. ' +
57
+ 'Use for: weather forecasts, current events, stock prices, sports scores, statistics. ' +
58
+ 'The model will search the web for real-time data to inform image generation.'),
59
+ global_media_resolution: z.enum([
60
+ 'MEDIA_RESOLUTION_LOW',
61
+ 'MEDIA_RESOLUTION_MEDIUM',
62
+ 'MEDIA_RESOLUTION_HIGH'
63
+ ])
64
+ .optional()
65
+ .describe('Global image quality setting for cost optimization (default: HIGH). ' +
66
+ 'LOW (280 tokens, 75% savings) - Simple tasks, bulk operations. ' +
67
+ 'MEDIUM (560 tokens, 50% savings) - PDFs/documents (OCR saturates at medium). ' +
68
+ 'HIGH (1120 tokens) - Best quality, detailed analysis. ' +
69
+ 'Can be overridden per-image using mediaResolution in images array.'),
70
+ outputPath: z.string()
71
+ .optional()
72
+ .describe('Optional file path to save the generated image (e.g., ./output/image.png)'),
73
+ },
74
+ _meta: {
75
+ ui: { resourceUri: 'ui://gemini/image-viewer.html' }
76
+ }
77
+ }, async ({ prompt, model, aspectRatio, imageSize, images, use_search, global_media_resolution, outputPath }) => {
78
+ try {
79
+ logger.info('Executing generate_image tool', {
80
+ model,
81
+ promptLength: prompt.length,
82
+ useSearch: use_search,
83
+ globalMediaResolution: global_media_resolution
84
+ });
85
+ // Resolve any filePath references in input images server-side
86
+ const resolvedImages = images ? await resolveImageInputs(images) : undefined;
87
+ const result = await ctx.imageService.generateImage({
88
+ prompt,
89
+ model,
90
+ aspectRatio,
91
+ imageSize,
92
+ images: resolvedImages,
93
+ useSearch: use_search,
94
+ globalMediaResolution: global_media_resolution
95
+ });
96
+ const firstImage = result.parts.find(p => p.type === 'image' && p.base64Data);
97
+ const resolvedSavePath = outputPath
98
+ ? resolve(outputPath)
99
+ : resolve(ctx.outputDir, `gemini-${Date.now()}.png`);
100
+ let savedPath;
101
+ let previewPath;
102
+ let previewImageData;
103
+ if (firstImage?.base64Data) {
104
+ const processed = await processGeneratedImage(firstImage.base64Data, firstImage.mimeType || 'image/png', resolvedSavePath, prompt, result.description);
105
+ savedPath = processed.savedPath;
106
+ previewPath = processed.previewPath;
107
+ previewImageData = processed.previewImageData;
108
+ }
109
+ // Extract thoughtSignature from response parts for conversational editing
110
+ const thoughtSignature = result.parts.find(p => !!p.thoughtSignature)?.thoughtSignature;
111
+ const textLines = buildTextLines(savedPath, previewPath, result.description, result.groundingSources, thoughtSignature);
112
+ // Serve full-res image via media server (bypasses MCP 1MB limit)
113
+ const imageUrl = savedPath ? ctx.mediaServer.getFileUrl(savedPath) : undefined;
114
+ return {
115
+ structuredContent: {
116
+ imageUrl,
117
+ base64Data: previewImageData || '',
118
+ mimeType: 'image/jpeg',
119
+ savedPath,
120
+ previewPath,
121
+ description: result.description,
122
+ prompt,
123
+ groundingSources: result.groundingSources
124
+ },
125
+ content: [
126
+ {
127
+ type: 'text',
128
+ text: textLines.join('\n') || 'Image generated successfully'
129
+ }
130
+ ]
131
+ };
132
+ }
133
+ catch (error) {
134
+ logger.error('generate_image tool failed', { error });
135
+ const msg = error instanceof McpError
136
+ ? error.message
137
+ : `Failed to generate image: ${error.message}`;
138
+ return { content: createToolResult(false, msg, error) };
139
+ }
140
+ });
141
+ registerAppTool(ctx.server, 'edit_image', {
142
+ title: 'Edit Image with Gemini',
143
+ description: 'Edit one or more images using Google Gemini image models (Nano Banana Pro). ' +
144
+ 'Provide images and natural-language instructions for how to modify them. ' +
145
+ 'Returns edited image with inline preview and saves full-resolution to disk.',
146
+ inputSchema: {
147
+ prompt: z.string().describe('Instructions for how to edit the image(s)'),
148
+ images: z.array(imageInputSchema)
149
+ .min(1)
150
+ .describe('One or more images to edit'),
151
+ model: z.string()
152
+ .optional()
153
+ .describe('Gemini image model to use (default: gemini-3-pro-image-preview)'),
154
+ use_search: z.boolean()
155
+ .optional()
156
+ .default(false)
157
+ .describe('Enable Google Search grounding for data-driven editing'),
158
+ global_media_resolution: z.enum([
159
+ 'MEDIA_RESOLUTION_LOW',
160
+ 'MEDIA_RESOLUTION_MEDIUM',
161
+ 'MEDIA_RESOLUTION_HIGH'
162
+ ])
163
+ .optional()
164
+ .describe('Global image quality setting (default: HIGH). See generate_image for details.'),
165
+ outputPath: z.string()
166
+ .optional()
167
+ .describe('Optional file path to save the edited image (e.g., ./output/edited.png)'),
168
+ },
169
+ _meta: {
170
+ ui: { resourceUri: 'ui://gemini/image-viewer.html' }
171
+ }
172
+ }, async ({ prompt, images, model, use_search, global_media_resolution, outputPath }) => {
173
+ try {
174
+ logger.info('Executing edit_image tool', {
175
+ model,
176
+ imageCount: images.length,
177
+ useSearch: use_search,
178
+ globalMediaResolution: global_media_resolution
179
+ });
180
+ // Resolve any filePath references in input images server-side
181
+ const resolvedImages = await resolveImageInputs(images);
182
+ const result = await ctx.imageService.generateImage({
183
+ prompt,
184
+ model,
185
+ images: resolvedImages,
186
+ useSearch: use_search,
187
+ globalMediaResolution: global_media_resolution
188
+ });
189
+ const firstImage = result.parts.find(p => p.type === 'image' && p.base64Data);
190
+ const resolvedSavePath = outputPath
191
+ ? resolve(outputPath)
192
+ : resolve(ctx.outputDir, `gemini-edit-${Date.now()}.png`);
193
+ let savedPath;
194
+ let previewPath;
195
+ let previewImageData;
196
+ if (firstImage?.base64Data) {
197
+ const processed = await processGeneratedImage(firstImage.base64Data, firstImage.mimeType || 'image/png', resolvedSavePath, `[EDIT] ${prompt}`, result.description);
198
+ savedPath = processed.savedPath;
199
+ previewPath = processed.previewPath;
200
+ previewImageData = processed.previewImageData;
201
+ }
202
+ // Extract thoughtSignature from response parts for conversational editing
203
+ const thoughtSignature = result.parts.find(p => !!p.thoughtSignature)?.thoughtSignature;
204
+ const textLines = buildTextLines(savedPath, previewPath, result.description, result.groundingSources, thoughtSignature);
205
+ // Serve full-res image via media server (bypasses MCP 1MB limit)
206
+ const imageUrl = savedPath ? ctx.mediaServer.getFileUrl(savedPath) : undefined;
207
+ return {
208
+ structuredContent: {
209
+ imageUrl,
210
+ base64Data: previewImageData || '',
211
+ mimeType: 'image/jpeg',
212
+ savedPath,
213
+ previewPath,
214
+ description: result.description,
215
+ prompt: `[EDIT] ${prompt}`,
216
+ groundingSources: result.groundingSources
217
+ },
218
+ content: [
219
+ {
220
+ type: 'text',
221
+ text: textLines.join('\n') || 'Image edited successfully'
222
+ }
223
+ ]
224
+ };
225
+ }
226
+ catch (error) {
227
+ logger.error('edit_image tool failed', { error });
228
+ const msg = error instanceof McpError
229
+ ? error.message
230
+ : `Failed to edit image: ${error.message}`;
231
+ return { content: createToolResult(false, msg, error) };
232
+ }
233
+ });
234
+ }
235
+ //# sourceMappingURL=register-image-gen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-image-gen.js","sourceRoot":"","sources":["../../src/tools/register-image-gen.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-landing-page.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-landing-page.d.ts","sourceRoot":"","sources":["../../src/tools/register-landing-page.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,wBAAgB,QAAQ,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CAgF/C"}
@@ -0,0 +1,79 @@
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 { GenerateLandingPageTool } from './generate-landing-page.js';
9
+ export function register(ctx) {
10
+ const landingPageTool = new GenerateLandingPageTool(ctx.geminiService);
11
+ registerAppTool(ctx.server, 'generate_landing_page', {
12
+ title: 'Generate Landing Page',
13
+ description: 'Generate a complete, self-contained HTML landing page using Gemini. ' +
14
+ 'Returns inline preview with responsive viewport controls. ' +
15
+ 'No external dependencies; inline CSS and vanilla JS only.',
16
+ inputSchema: {
17
+ brief: z.string().describe('Description of the product/service and page goals'),
18
+ companyName: z.string().optional().describe('Company or product name'),
19
+ primaryColour: z.string().optional().describe('Primary brand colour (e.g. #3B82F6 or "deep blue")'),
20
+ style: z.enum(['minimal', 'bold', 'corporate', 'startup'])
21
+ .optional()
22
+ .default('startup')
23
+ .describe('Visual design style'),
24
+ sections: z.array(z.string())
25
+ .optional()
26
+ .describe('Sections to include (e.g. ["hero", "features", "pricing", "cta"])'),
27
+ model: z.string().optional().describe('Gemini model to use (defaults to configured default)'),
28
+ outputPath: z.string()
29
+ .optional()
30
+ .describe('Optional file path to save the HTML (e.g. C:/dev/output/landing.html)'),
31
+ },
32
+ _meta: {
33
+ ui: { resourceUri: 'ui://gemini/landing-page-viewer.html' }
34
+ }
35
+ }, async ({ brief, companyName, primaryColour, style, sections, model, outputPath }) => {
36
+ try {
37
+ logger.info('Executing generate_landing_page tool', { style, model });
38
+ const html = await landingPageTool.execute({
39
+ brief,
40
+ companyName,
41
+ primaryColour,
42
+ style,
43
+ sections,
44
+ model,
45
+ });
46
+ const absolutePath = outputPath
47
+ ? resolve(outputPath)
48
+ : resolve(ctx.outputDir, `gemini-landing-${Date.now()}.html`);
49
+ await mkdir(dirname(absolutePath), { recursive: true });
50
+ await writeFile(absolutePath, html, 'utf-8');
51
+ logger.info('Landing page saved successfully', { savedPath: absolutePath });
52
+ return {
53
+ structuredContent: {
54
+ html,
55
+ savedPath: absolutePath,
56
+ brief,
57
+ companyName
58
+ },
59
+ content: [
60
+ {
61
+ type: 'text',
62
+ text: `${savedFileMessage('Landing page saved', absolutePath)}\n\nOpen this file in your browser to view the landing page.`
63
+ }
64
+ ]
65
+ };
66
+ }
67
+ catch (error) {
68
+ logger.error('generate_landing_page tool failed', { error });
69
+ const msg = error instanceof McpError
70
+ ? error.message
71
+ : `Failed to generate landing page: ${error.message}`;
72
+ return {
73
+ content: createToolResult(false, msg, error),
74
+ structuredContent: { content: msg, success: false },
75
+ };
76
+ }
77
+ });
78
+ }
79
+ //# sourceMappingURL=register-landing-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-landing-page.js","sourceRoot":"","sources":["../../src/tools/register-landing-page.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-list-models.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-list-models.d.ts","sourceRoot":"","sources":["../../src/tools/register-list-models.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,wBAAgB,QAAQ,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CAmC/C"}
@@ -0,0 +1,33 @@
1
+ import * as z from 'zod';
2
+ import logger from '../utils/logger.js';
3
+ import { createToolResult } from '../utils/error-handler.js';
4
+ import { toolError } from '../utils/tool-wrapper.js';
5
+ export function register(ctx) {
6
+ ctx.server.registerTool('gemini_list_models', {
7
+ title: 'List Gemini Models',
8
+ description: 'List available Gemini models and their descriptions',
9
+ inputSchema: {},
10
+ outputSchema: {
11
+ content: z.string(),
12
+ success: z.boolean()
13
+ }
14
+ }, async () => {
15
+ try {
16
+ logger.info('Executing gemini_list_models tool');
17
+ const response = await ctx.geminiService.listModels();
18
+ let modelsInfo = 'Available Gemini Models:\n\n';
19
+ for (const model of response.models) {
20
+ modelsInfo += `• **${model.name}**: ${model.description}\n`;
21
+ }
22
+ modelsInfo += `\nLast updated: ${response.timestamp}`;
23
+ return {
24
+ content: createToolResult(true, modelsInfo),
25
+ structuredContent: { content: modelsInfo, success: true }
26
+ };
27
+ }
28
+ catch (error) {
29
+ return toolError('gemini_list_models', error);
30
+ }
31
+ });
32
+ }
33
+ //# sourceMappingURL=register-list-models.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-list-models.js","sourceRoot":"","sources":["../../src/tools/register-list-models.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAGrD,MAAM,UAAU,QAAQ,CAAC,GAAgB;IACvC,GAAG,CAAC,MAAM,CAAC,YAAY,CACrB,oBAAoB,EACpB;QACE,KAAK,EAAE,oBAAoB;QAC3B,WAAW,EAAE,qDAAqD;QAClE,WAAW,EAAE,EAAE;QACf,YAAY,EAAE;YACZ,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;YACnB,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;SACrB;KACF,EACD,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;YAEjD,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,aAAa,CAAC,UAAU,EAAE,CAAC;YAEtD,IAAI,UAAU,GAAG,8BAA8B,CAAC;YAEhD,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;gBACpC,UAAU,IAAI,OAAO,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,WAAW,IAAI,CAAC;YAC9D,CAAC;YAED,UAAU,IAAI,mBAAmB,QAAQ,CAAC,SAAS,EAAE,CAAC;YAEtD,OAAO;gBACL,OAAO,EAAE,gBAAgB,CAAC,IAAI,EAAE,UAAU,CAAC;gBAC3C,iBAAiB,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE;aAC1D,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,SAAS,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;QAChD,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ToolContext } from './types.js';
2
+ export declare function register(ctx: ToolContext): void;
3
+ //# sourceMappingURL=register-load-image.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-load-image.d.ts","sourceRoot":"","sources":["../../src/tools/register-load-image.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAI9C,wBAAgB,QAAQ,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CA8D/C"}
@@ -0,0 +1,66 @@
1
+ import * as z from 'zod';
2
+ import { stat } from 'fs/promises';
3
+ import { resolve } from 'path';
4
+ import logger from '../utils/logger.js';
5
+ import { createToolResult } from '../utils/error-handler.js';
6
+ import { toolError } from '../utils/tool-wrapper.js';
7
+ const SUPPORTED_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.bmp'];
8
+ export function register(ctx) {
9
+ ctx.server.registerTool('load_image_from_path', {
10
+ title: 'Load Image from File Path',
11
+ description: 'Read a local image file and return it as base64-encoded data ready to pass to ' +
12
+ 'generate_image, edit_image, describe_image, or analyze_image tools. ' +
13
+ 'Supports JPEG, PNG, GIF, WebP, BMP.',
14
+ inputSchema: {
15
+ filePath: z.string().describe('Absolute or relative path to the image file'),
16
+ },
17
+ outputSchema: {
18
+ content: z.string(),
19
+ success: z.boolean(),
20
+ },
21
+ }, async ({ filePath }) => {
22
+ try {
23
+ logger.info('Executing load_image_from_path tool', { filePath });
24
+ const absolutePath = resolve(filePath);
25
+ const ext = absolutePath.toLowerCase().match(/\.[a-z]+$/)?.[0];
26
+ if (!ext || !SUPPORTED_EXTENSIONS.includes(ext)) {
27
+ throw new Error(`Unsupported image format: ${ext || 'unknown'}. ` +
28
+ `Supported: ${SUPPORTED_EXTENSIONS.join(', ')}`);
29
+ }
30
+ const stats = await stat(absolutePath);
31
+ const sizeBytes = stats.size;
32
+ // Get media server URL for preview display (bypasses MCP transport)
33
+ const imageUrl = ctx.mediaServer.getFileUrl(absolutePath);
34
+ const summary = JSON.stringify({
35
+ filePath: absolutePath,
36
+ mimeType: MIME_MAP[ext] || 'application/octet-stream',
37
+ sizeBytes,
38
+ sizeKB: Math.round(sizeBytes / 1024),
39
+ imageUrl,
40
+ note: 'Pass filePath to edit_image, describe_image, or analyze_image. ' +
41
+ 'Images are loaded server-side, bypassing MCP transport limits.',
42
+ });
43
+ logger.info('Image loaded via media server', {
44
+ filePath: absolutePath,
45
+ sizeKB: Math.round(sizeBytes / 1024),
46
+ hasUrl: !!imageUrl,
47
+ });
48
+ return {
49
+ content: createToolResult(true, summary),
50
+ structuredContent: { content: summary, success: true },
51
+ };
52
+ }
53
+ catch (error) {
54
+ return toolError('load_image_from_path', error);
55
+ }
56
+ });
57
+ }
58
+ const MIME_MAP = {
59
+ '.jpg': 'image/jpeg',
60
+ '.jpeg': 'image/jpeg',
61
+ '.png': 'image/png',
62
+ '.gif': 'image/gif',
63
+ '.webp': 'image/webp',
64
+ '.bmp': 'image/bmp',
65
+ };
66
+ //# sourceMappingURL=register-load-image.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-load-image.js","sourceRoot":"","sources":["../../src/tools/register-load-image.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-svg.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-svg.d.ts","sourceRoot":"","sources":["../../src/tools/register-svg.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,wBAAgB,QAAQ,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CAqF/C"}