mcp-hydrocoder-image 1.0.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.
- package/LICENSE +21 -0
- package/README.md +454 -0
- package/bin/install-skills.js +115 -0
- package/dist/api/geminiClient.d.ts +57 -0
- package/dist/api/geminiClient.d.ts.map +1 -0
- package/dist/api/geminiClient.js +341 -0
- package/dist/api/geminiClient.js.map +1 -0
- package/dist/api/geminiTextClient.d.ts +44 -0
- package/dist/api/geminiTextClient.d.ts.map +1 -0
- package/dist/api/geminiTextClient.js +202 -0
- package/dist/api/geminiTextClient.js.map +1 -0
- package/dist/business/fileManager.d.ts +20 -0
- package/dist/business/fileManager.d.ts.map +1 -0
- package/dist/business/fileManager.js +76 -0
- package/dist/business/fileManager.js.map +1 -0
- package/dist/business/inputValidator.d.ts +44 -0
- package/dist/business/inputValidator.d.ts.map +1 -0
- package/dist/business/inputValidator.js +213 -0
- package/dist/business/inputValidator.js.map +1 -0
- package/dist/business/responseBuilder.d.ts +21 -0
- package/dist/business/responseBuilder.d.ts.map +1 -0
- package/dist/business/responseBuilder.js +166 -0
- package/dist/business/responseBuilder.js.map +1 -0
- package/dist/business/structuredPromptGenerator.d.ts +56 -0
- package/dist/business/structuredPromptGenerator.d.ts.map +1 -0
- package/dist/business/structuredPromptGenerator.js +218 -0
- package/dist/business/structuredPromptGenerator.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -0
- package/dist/server/errorHandler.d.ts +29 -0
- package/dist/server/errorHandler.d.ts.map +1 -0
- package/dist/server/errorHandler.js +99 -0
- package/dist/server/errorHandler.js.map +1 -0
- package/dist/server/mcpServer.d.ts +159 -0
- package/dist/server/mcpServer.d.ts.map +1 -0
- package/dist/server/mcpServer.js +434 -0
- package/dist/server/mcpServer.js.map +1 -0
- package/dist/server-main.d.ts +5 -0
- package/dist/server-main.d.ts.map +1 -0
- package/dist/server-main.js +37 -0
- package/dist/server-main.js.map +1 -0
- package/dist/types/mcp.d.ts +121 -0
- package/dist/types/mcp.d.ts.map +1 -0
- package/dist/types/mcp.js +22 -0
- package/dist/types/mcp.js.map +1 -0
- package/dist/types/result.d.ts +27 -0
- package/dist/types/result.d.ts.map +1 -0
- package/dist/types/result.js +27 -0
- package/dist/types/result.js.map +1 -0
- package/dist/utils/config.d.ts +29 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +56 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/errors.d.ts +84 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +215 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/logger.d.ts +80 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +186 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/security.d.ts +50 -0
- package/dist/utils/security.d.ts.map +1 -0
- package/dist/utils/security.js +116 -0
- package/dist/utils/security.js.map +1 -0
- package/package.json +89 -0
- package/skills/image-generation/SKILL.md +131 -0
|
@@ -0,0 +1,434 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Server implementation
|
|
3
|
+
* Simplified architecture with direct Gemini integration
|
|
4
|
+
*/
|
|
5
|
+
import * as fs from 'node:fs/promises';
|
|
6
|
+
import * as path from 'node:path';
|
|
7
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
8
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
9
|
+
// API clients
|
|
10
|
+
import { createGeminiClient } from '../api/geminiClient.js';
|
|
11
|
+
import { createGeminiTextClient } from '../api/geminiTextClient.js';
|
|
12
|
+
// Business logic
|
|
13
|
+
import { createFileManager } from '../business/fileManager.js';
|
|
14
|
+
import { validateGenerateImageParams } from '../business/inputValidator.js';
|
|
15
|
+
import { createResponseBuilder } from '../business/responseBuilder.js';
|
|
16
|
+
import { createStructuredPromptGenerator, } from '../business/structuredPromptGenerator.js';
|
|
17
|
+
// Utilities
|
|
18
|
+
import { getConfig } from '../utils/config.js';
|
|
19
|
+
import { Logger } from '../utils/logger.js';
|
|
20
|
+
import { SecurityManager } from '../utils/security.js';
|
|
21
|
+
import { ErrorHandler } from './errorHandler.js';
|
|
22
|
+
/**
|
|
23
|
+
* Default MCP server configuration
|
|
24
|
+
*/
|
|
25
|
+
const DEFAULT_CONFIG = {
|
|
26
|
+
name: 'mcp-image-server',
|
|
27
|
+
version: '0.1.0',
|
|
28
|
+
defaultOutputDir: './output',
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Simplified MCP server
|
|
32
|
+
*/
|
|
33
|
+
export class MCPServerImpl {
|
|
34
|
+
constructor(config = {}) {
|
|
35
|
+
this.server = null;
|
|
36
|
+
this.structuredPromptGenerator = null;
|
|
37
|
+
this.geminiTextClient = null;
|
|
38
|
+
this.geminiClient = null;
|
|
39
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
40
|
+
this.logger = new Logger();
|
|
41
|
+
this.fileManager = createFileManager();
|
|
42
|
+
this.responseBuilder = createResponseBuilder();
|
|
43
|
+
this.securityManager = new SecurityManager();
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Get server info
|
|
47
|
+
*/
|
|
48
|
+
getServerInfo() {
|
|
49
|
+
return {
|
|
50
|
+
name: this.config.name,
|
|
51
|
+
version: this.config.version,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Get list of registered tools
|
|
56
|
+
*/
|
|
57
|
+
getToolsList() {
|
|
58
|
+
return {
|
|
59
|
+
tools: [
|
|
60
|
+
{
|
|
61
|
+
name: 'generate_image',
|
|
62
|
+
description: 'Generate, edit, blend, or merge images using AI. Supports text-to-image generation, single image editing, and multi-image composition/blending. Use inputImagePaths for merging multiple images from file paths, or inputImages for base64 encoded images.',
|
|
63
|
+
inputSchema: {
|
|
64
|
+
type: 'object',
|
|
65
|
+
properties: {
|
|
66
|
+
prompt: {
|
|
67
|
+
type: 'string',
|
|
68
|
+
description: 'The prompt for image generation (English recommended for optimal structured prompt enhancement)',
|
|
69
|
+
},
|
|
70
|
+
fileName: {
|
|
71
|
+
type: 'string',
|
|
72
|
+
description: 'Custom file name for the output image. Auto-generated if not specified.',
|
|
73
|
+
},
|
|
74
|
+
inputImagePath: {
|
|
75
|
+
type: 'string',
|
|
76
|
+
description: 'Optional absolute path to source image for image-to-image generation. Use when generating variations, style transfers, or similar images based on an existing image (must be an absolute path)',
|
|
77
|
+
},
|
|
78
|
+
inputImage: {
|
|
79
|
+
type: 'string',
|
|
80
|
+
description: 'Optional base64 encoded image data for image-to-image generation. Alternative to inputImagePath when image data is already in memory. Do not include data URI prefix (e.g., "data:image/png;base64,")',
|
|
81
|
+
},
|
|
82
|
+
inputImageMimeType: {
|
|
83
|
+
type: 'string',
|
|
84
|
+
description: 'MIME type of the input image provided via inputImage. Required when inputImage is provided for accurate processing',
|
|
85
|
+
enum: [
|
|
86
|
+
'image/jpeg',
|
|
87
|
+
'image/png',
|
|
88
|
+
'image/webp',
|
|
89
|
+
'image/gif',
|
|
90
|
+
'image/bmp',
|
|
91
|
+
],
|
|
92
|
+
},
|
|
93
|
+
inputImages: {
|
|
94
|
+
type: 'array',
|
|
95
|
+
description: 'Multiple input images for multi-image composition. Cannot be used together with inputImage or inputImagePath. Each item requires base64 data and MIME type.',
|
|
96
|
+
items: {
|
|
97
|
+
type: 'object',
|
|
98
|
+
properties: {
|
|
99
|
+
data: {
|
|
100
|
+
type: 'string',
|
|
101
|
+
description: 'Base64 encoded image data. Do not include data URI prefix.',
|
|
102
|
+
},
|
|
103
|
+
mimeType: {
|
|
104
|
+
type: 'string',
|
|
105
|
+
description: 'MIME type of the image',
|
|
106
|
+
enum: [
|
|
107
|
+
'image/jpeg',
|
|
108
|
+
'image/png',
|
|
109
|
+
'image/webp',
|
|
110
|
+
'image/gif',
|
|
111
|
+
'image/bmp',
|
|
112
|
+
],
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
required: ['data', 'mimeType'],
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
inputImagePaths: {
|
|
119
|
+
type: 'array',
|
|
120
|
+
description: 'Multiple input image file paths for multi-image composition. Cannot be used together with inputImage, inputImagePath, or inputImages. Each path must be absolute.',
|
|
121
|
+
items: {
|
|
122
|
+
type: 'string',
|
|
123
|
+
description: 'Absolute path to an image file',
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
returnBase64: {
|
|
127
|
+
type: 'boolean',
|
|
128
|
+
description: 'Return the generated image as base64 data in the response. The image is always saved to disk regardless of this setting. Default: false',
|
|
129
|
+
},
|
|
130
|
+
blendImages: {
|
|
131
|
+
type: 'boolean',
|
|
132
|
+
description: 'Enable multi-image blending for combining multiple visual elements naturally. Use when prompt mentions multiple subjects or composite scenes',
|
|
133
|
+
},
|
|
134
|
+
maintainCharacterConsistency: {
|
|
135
|
+
type: 'boolean',
|
|
136
|
+
description: 'Maintain character appearance consistency. Enable when generating same character in different poses/scenes',
|
|
137
|
+
},
|
|
138
|
+
useWorldKnowledge: {
|
|
139
|
+
type: 'boolean',
|
|
140
|
+
description: 'Use real-world knowledge for accurate context. Enable for historical figures, landmarks, or factual scenarios',
|
|
141
|
+
},
|
|
142
|
+
useGoogleSearch: {
|
|
143
|
+
type: 'boolean',
|
|
144
|
+
description: "Enable Google Search grounding to access real-time web information for factually accurate image generation. Use when prompt requires current or time-sensitive data that may have changed since the model's knowledge cutoff. Leave disabled for creative, fictional, historical, or timeless content.",
|
|
145
|
+
},
|
|
146
|
+
aspectRatio: {
|
|
147
|
+
type: 'string',
|
|
148
|
+
description: 'Aspect ratio for the generated image',
|
|
149
|
+
enum: [
|
|
150
|
+
'1:1',
|
|
151
|
+
'1:4',
|
|
152
|
+
'1:8',
|
|
153
|
+
'2:3',
|
|
154
|
+
'3:2',
|
|
155
|
+
'3:4',
|
|
156
|
+
'4:1',
|
|
157
|
+
'4:3',
|
|
158
|
+
'4:5',
|
|
159
|
+
'5:4',
|
|
160
|
+
'8:1',
|
|
161
|
+
'9:16',
|
|
162
|
+
'16:9',
|
|
163
|
+
'21:9',
|
|
164
|
+
],
|
|
165
|
+
},
|
|
166
|
+
imageSize: {
|
|
167
|
+
type: 'string',
|
|
168
|
+
description: 'Image resolution for high-quality output. Specify "1K", "2K", or "4K" when you need specific resolution. Leave unspecified for standard quality.',
|
|
169
|
+
enum: ['1K', '2K', '4K'],
|
|
170
|
+
},
|
|
171
|
+
purpose: {
|
|
172
|
+
type: 'string',
|
|
173
|
+
description: 'Intended use for the image (e.g., cookbook cover, social media post, presentation slide). Influences lighting, composition, and detail level to match the context.',
|
|
174
|
+
},
|
|
175
|
+
quality: {
|
|
176
|
+
type: 'string',
|
|
177
|
+
description: 'Quality preset controlling speed/fidelity tradeoff. Only specify when the user explicitly requests a specific quality level; omit to use the server\'s configured default. "fast": best for drafts and rapid iteration. "balanced": better detail and coherence, moderate latency. "quality": highest fidelity, use for final deliverables where quality matters most.',
|
|
178
|
+
enum: ['fast', 'balanced', 'quality'],
|
|
179
|
+
},
|
|
180
|
+
skipPromptEnhancement: {
|
|
181
|
+
type: 'boolean',
|
|
182
|
+
description: 'Skip prompt enhancement and use the prompt as-is. Enable when your prompt already contains exact instructions (e.g., multi-image blending) that should not be rewritten. Default: false',
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
required: ['prompt'],
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
],
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Tool execution
|
|
193
|
+
*/
|
|
194
|
+
async callTool(name, args) {
|
|
195
|
+
try {
|
|
196
|
+
if (name === 'generate_image') {
|
|
197
|
+
return await this.handleGenerateImage(args);
|
|
198
|
+
}
|
|
199
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
this.logger.error('mcp-server', 'Tool execution failed', error);
|
|
203
|
+
return ErrorHandler.handleError(error);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Initialize Gemini clients lazily
|
|
208
|
+
*/
|
|
209
|
+
async initializeClients() {
|
|
210
|
+
if (this.structuredPromptGenerator && this.geminiClient)
|
|
211
|
+
return;
|
|
212
|
+
const configResult = getConfig();
|
|
213
|
+
if (!configResult.success) {
|
|
214
|
+
throw configResult.error;
|
|
215
|
+
}
|
|
216
|
+
// Initialize Gemini Text Client for prompt generation
|
|
217
|
+
if (!this.geminiTextClient) {
|
|
218
|
+
const textClientResult = createGeminiTextClient(configResult.data);
|
|
219
|
+
if (!textClientResult.success) {
|
|
220
|
+
throw textClientResult.error;
|
|
221
|
+
}
|
|
222
|
+
this.geminiTextClient = textClientResult.data;
|
|
223
|
+
}
|
|
224
|
+
// Initialize Structured Prompt Generator
|
|
225
|
+
if (!this.structuredPromptGenerator) {
|
|
226
|
+
this.structuredPromptGenerator = createStructuredPromptGenerator(this.geminiTextClient);
|
|
227
|
+
}
|
|
228
|
+
// Initialize Gemini Client for image generation
|
|
229
|
+
if (!this.geminiClient) {
|
|
230
|
+
const clientResult = createGeminiClient(configResult.data);
|
|
231
|
+
if (!clientResult.success) {
|
|
232
|
+
throw clientResult.error;
|
|
233
|
+
}
|
|
234
|
+
this.geminiClient = clientResult.data;
|
|
235
|
+
}
|
|
236
|
+
this.logger.info('mcp-server', 'Gemini clients initialized');
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Simplified image generation handler
|
|
240
|
+
*/
|
|
241
|
+
async handleGenerateImage(params) {
|
|
242
|
+
const result = await ErrorHandler.wrapWithResultType(async () => {
|
|
243
|
+
// Validate input
|
|
244
|
+
const validationResult = validateGenerateImageParams(params);
|
|
245
|
+
if (!validationResult.success) {
|
|
246
|
+
throw validationResult.error;
|
|
247
|
+
}
|
|
248
|
+
// Get configuration
|
|
249
|
+
const configResult = getConfig();
|
|
250
|
+
if (!configResult.success) {
|
|
251
|
+
throw configResult.error;
|
|
252
|
+
}
|
|
253
|
+
// Initialize clients
|
|
254
|
+
await this.initializeClients();
|
|
255
|
+
// Handle input image if provided
|
|
256
|
+
let inputImageData;
|
|
257
|
+
let inputImageMimeType;
|
|
258
|
+
let inputImagesData;
|
|
259
|
+
if (params.inputImagePaths && params.inputImagePaths.length > 0) {
|
|
260
|
+
// Multi-image from file paths: read each file and derive mimeType from extension
|
|
261
|
+
const extToMime = {
|
|
262
|
+
'.jpg': 'image/jpeg',
|
|
263
|
+
'.jpeg': 'image/jpeg',
|
|
264
|
+
'.png': 'image/png',
|
|
265
|
+
'.webp': 'image/webp',
|
|
266
|
+
'.gif': 'image/gif',
|
|
267
|
+
'.bmp': 'image/bmp',
|
|
268
|
+
};
|
|
269
|
+
inputImagesData = await Promise.all(params.inputImagePaths.map(async (filePath) => {
|
|
270
|
+
const buffer = await fs.readFile(filePath);
|
|
271
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
272
|
+
return {
|
|
273
|
+
data: buffer.toString('base64'),
|
|
274
|
+
mimeType: extToMime[ext] || 'image/jpeg',
|
|
275
|
+
};
|
|
276
|
+
}));
|
|
277
|
+
inputImageData = inputImagesData[0]?.data;
|
|
278
|
+
inputImageMimeType = inputImagesData[0]?.mimeType;
|
|
279
|
+
}
|
|
280
|
+
else if (params.inputImages && params.inputImages.length > 0) {
|
|
281
|
+
// Multi-image: strip data URI prefix from each image
|
|
282
|
+
inputImagesData = params.inputImages.map((img) => ({
|
|
283
|
+
data: img.data.replace(/^data:image\/[a-z]+;base64,/, ''),
|
|
284
|
+
mimeType: img.mimeType,
|
|
285
|
+
}));
|
|
286
|
+
// Use first image for prompt enhancement context
|
|
287
|
+
inputImageData = inputImagesData[0]?.data;
|
|
288
|
+
inputImageMimeType = inputImagesData[0]?.mimeType;
|
|
289
|
+
}
|
|
290
|
+
else if (params.inputImagePath) {
|
|
291
|
+
const imageBuffer = await fs.readFile(params.inputImagePath);
|
|
292
|
+
inputImageData = imageBuffer.toString('base64');
|
|
293
|
+
}
|
|
294
|
+
else if (params.inputImage) {
|
|
295
|
+
// Use base64 input directly, stripping data URI prefix if present
|
|
296
|
+
inputImageData = params.inputImage.replace(/^data:image\/[a-z]+;base64,/, '');
|
|
297
|
+
inputImageMimeType = params.inputImageMimeType;
|
|
298
|
+
}
|
|
299
|
+
// Generate structured prompt (unless skipped)
|
|
300
|
+
let structuredPrompt = params.prompt;
|
|
301
|
+
const shouldSkipEnhancement = params.skipPromptEnhancement ?? configResult.data.skipPromptEnhancement;
|
|
302
|
+
if (!shouldSkipEnhancement && this.structuredPromptGenerator) {
|
|
303
|
+
const features = {};
|
|
304
|
+
if (params.maintainCharacterConsistency !== undefined) {
|
|
305
|
+
features.maintainCharacterConsistency = params.maintainCharacterConsistency;
|
|
306
|
+
}
|
|
307
|
+
if (params.blendImages !== undefined) {
|
|
308
|
+
features.blendImages = params.blendImages;
|
|
309
|
+
}
|
|
310
|
+
if (params.useWorldKnowledge !== undefined) {
|
|
311
|
+
features.useWorldKnowledge = params.useWorldKnowledge;
|
|
312
|
+
}
|
|
313
|
+
if (params.useGoogleSearch !== undefined) {
|
|
314
|
+
features.useGoogleSearch = params.useGoogleSearch;
|
|
315
|
+
}
|
|
316
|
+
const promptResult = await this.structuredPromptGenerator.generateStructuredPrompt(params.prompt, features, inputImageData, // Pass image data for context-aware prompt generation
|
|
317
|
+
params.purpose // Pass intended use for purpose-aware prompt generation
|
|
318
|
+
);
|
|
319
|
+
if (promptResult.success) {
|
|
320
|
+
structuredPrompt = promptResult.data.structuredPrompt;
|
|
321
|
+
this.logger.info('mcp-server', 'Structured prompt generated', {
|
|
322
|
+
originalLength: params.prompt.length,
|
|
323
|
+
structuredLength: structuredPrompt.length,
|
|
324
|
+
selectedPractices: promptResult.data.selectedPractices,
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
this.logger.warn('mcp-server', 'Using original prompt', {
|
|
329
|
+
error: promptResult.error.message,
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
else if (shouldSkipEnhancement) {
|
|
334
|
+
this.logger.info('mcp-server', 'Prompt enhancement skipped (SKIP_PROMPT_ENHANCEMENT=true)');
|
|
335
|
+
}
|
|
336
|
+
// Generate image using Gemini API
|
|
337
|
+
if (!this.geminiClient) {
|
|
338
|
+
throw new Error('Gemini client not initialized');
|
|
339
|
+
}
|
|
340
|
+
const generationResult = await this.geminiClient.generateImage({
|
|
341
|
+
prompt: structuredPrompt,
|
|
342
|
+
...(inputImagesData && { inputImages: inputImagesData }),
|
|
343
|
+
...(!inputImagesData && inputImageData && { inputImage: inputImageData }),
|
|
344
|
+
...(!inputImagesData && inputImageMimeType && { inputImageMimeType }),
|
|
345
|
+
...(params.aspectRatio && { aspectRatio: params.aspectRatio }),
|
|
346
|
+
...(params.imageSize && { imageSize: params.imageSize }),
|
|
347
|
+
...(params.useGoogleSearch !== undefined && { useGoogleSearch: params.useGoogleSearch }),
|
|
348
|
+
...(params.quality !== undefined && { quality: params.quality }),
|
|
349
|
+
});
|
|
350
|
+
if (!generationResult.success) {
|
|
351
|
+
throw generationResult.error;
|
|
352
|
+
}
|
|
353
|
+
// Save image file
|
|
354
|
+
let fileName = params.fileName || this.fileManager.generateFileName();
|
|
355
|
+
// Auto-append extension if user-provided fileName has no extension
|
|
356
|
+
if (params.fileName && !path.extname(fileName)) {
|
|
357
|
+
const mimeToExt = {
|
|
358
|
+
'image/png': '.png',
|
|
359
|
+
'image/jpeg': '.jpg',
|
|
360
|
+
'image/webp': '.webp',
|
|
361
|
+
'image/gif': '.gif',
|
|
362
|
+
'image/bmp': '.bmp',
|
|
363
|
+
};
|
|
364
|
+
fileName += mimeToExt[generationResult.data.metadata.mimeType] || '.png';
|
|
365
|
+
}
|
|
366
|
+
const outputPath = path.join(configResult.data.imageOutputDir, fileName);
|
|
367
|
+
const sanitizedPath = this.securityManager.sanitizeFilePath(outputPath);
|
|
368
|
+
if (!sanitizedPath.success) {
|
|
369
|
+
throw sanitizedPath.error;
|
|
370
|
+
}
|
|
371
|
+
const saveResult = await this.fileManager.saveImage(generationResult.data.imageData, sanitizedPath.data);
|
|
372
|
+
if (!saveResult.success) {
|
|
373
|
+
throw saveResult.error;
|
|
374
|
+
}
|
|
375
|
+
// Build response
|
|
376
|
+
if (params.returnBase64) {
|
|
377
|
+
const base64Data = generationResult.data.imageData.toString('base64');
|
|
378
|
+
return this.responseBuilder.buildBase64SuccessResponse(generationResult.data, saveResult.data, base64Data);
|
|
379
|
+
}
|
|
380
|
+
return this.responseBuilder.buildSuccessResponse(generationResult.data, saveResult.data);
|
|
381
|
+
}, 'image-generation');
|
|
382
|
+
if (result.ok) {
|
|
383
|
+
return result.value;
|
|
384
|
+
}
|
|
385
|
+
return this.responseBuilder.buildErrorResponse(result.error);
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Initialize MCP server with tool handlers
|
|
389
|
+
*/
|
|
390
|
+
initialize() {
|
|
391
|
+
this.server = new Server({
|
|
392
|
+
name: this.config.name,
|
|
393
|
+
version: this.config.version,
|
|
394
|
+
}, {
|
|
395
|
+
capabilities: {
|
|
396
|
+
tools: {},
|
|
397
|
+
},
|
|
398
|
+
});
|
|
399
|
+
// Setup tool handlers
|
|
400
|
+
this.setupHandlers();
|
|
401
|
+
return this.server;
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Setup MCP protocol handlers
|
|
405
|
+
*/
|
|
406
|
+
setupHandlers() {
|
|
407
|
+
if (!this.server) {
|
|
408
|
+
throw new Error('Server not initialized');
|
|
409
|
+
}
|
|
410
|
+
// Register tool list handler
|
|
411
|
+
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
412
|
+
return this.getToolsList();
|
|
413
|
+
});
|
|
414
|
+
// Register tool call handler
|
|
415
|
+
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
416
|
+
const { name, arguments: args } = request.params;
|
|
417
|
+
const result = await this.callTool(name, args);
|
|
418
|
+
const response = {
|
|
419
|
+
content: result.content,
|
|
420
|
+
};
|
|
421
|
+
if (result.structuredContent) {
|
|
422
|
+
response.structuredContent = result.structuredContent;
|
|
423
|
+
}
|
|
424
|
+
return response;
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* Factory function to create MCP server
|
|
430
|
+
*/
|
|
431
|
+
export function createMCPServer(config = {}) {
|
|
432
|
+
return new MCPServerImpl(config);
|
|
433
|
+
}
|
|
434
|
+
//# sourceMappingURL=mcpServer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcpServer.js","sourceRoot":"","sources":["../../src/server/mcpServer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-main.d.ts","sourceRoot":"","sources":["../src/server-main.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Image Generator - Server Entry Point
|
|
3
|
+
*/
|
|
4
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
5
|
+
import { MCPServerImpl } from './server/mcpServer.js';
|
|
6
|
+
import { Logger } from './utils/logger.js';
|
|
7
|
+
const logger = new Logger();
|
|
8
|
+
/**
|
|
9
|
+
* Application startup
|
|
10
|
+
*/
|
|
11
|
+
async function main() {
|
|
12
|
+
try {
|
|
13
|
+
logger.info('mcp-startup', 'Starting MCP Image Generator initialization', {
|
|
14
|
+
nodeVersion: process.version,
|
|
15
|
+
platform: process.platform,
|
|
16
|
+
env: process.env['NODE_ENV'] || 'development',
|
|
17
|
+
});
|
|
18
|
+
const mcpServerImpl = new MCPServerImpl();
|
|
19
|
+
const server = mcpServerImpl.initialize();
|
|
20
|
+
const transport = new StdioServerTransport();
|
|
21
|
+
await server.connect(transport);
|
|
22
|
+
logger.info('mcp-startup', 'Image Generator MCP Server started successfully');
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
logger.error('mcp-startup', 'Failed to start MCP server', error, {
|
|
26
|
+
errorType: error?.constructor?.name,
|
|
27
|
+
stack: error?.stack,
|
|
28
|
+
});
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// Run main function
|
|
33
|
+
main().catch((error) => {
|
|
34
|
+
logger.error('mcp-startup', 'Fatal error during startup', error);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
});
|
|
37
|
+
//# sourceMappingURL=server-main.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-main.js","sourceRoot":"","sources":["../src/server-main.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAA;AAChF,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAE1C,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAA;AAE3B;;GAEG;AACH,KAAK,UAAU,IAAI;IACjB,IAAI,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,6CAA6C,EAAE;YACxE,WAAW,EAAE,OAAO,CAAC,OAAO;YAC5B,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,aAAa;SAC9C,CAAC,CAAA;QAEF,MAAM,aAAa,GAAG,IAAI,aAAa,EAAE,CAAA;QAEzC,MAAM,MAAM,GAAG,aAAa,CAAC,UAAU,EAAE,CAAA;QAEzC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAA;QAE5C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;QAE/B,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,iDAAiD,CAAC,CAAA;IAC/E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,aAAa,EAAE,4BAA4B,EAAE,KAAc,EAAE;YACxE,SAAS,EAAG,KAAe,EAAE,WAAW,EAAE,IAAI;YAC9C,KAAK,EAAG,KAAe,EAAE,KAAK;SAC/B,CAAC,CAAA;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;AACH,CAAC;AAED,oBAAoB;AACpB,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,MAAM,CAAC,KAAK,CAAC,aAAa,EAAE,4BAA4B,EAAE,KAAc,CAAC,CAAA;IACzE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP-related type definitions
|
|
3
|
+
* Defines types related to @modelcontextprotocol/sdk and project-specific types
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Context method type for image generation metadata
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Supported aspect ratios for Gemini image generation
|
|
10
|
+
*/
|
|
11
|
+
export type AspectRatio = '1:1' | '1:4' | '1:8' | '2:3' | '3:2' | '3:4' | '4:1' | '4:3' | '4:5' | '5:4' | '8:1' | '9:16' | '16:9' | '21:9';
|
|
12
|
+
/**
|
|
13
|
+
* Supported image sizes for high-resolution output
|
|
14
|
+
*/
|
|
15
|
+
export type ImageSize = '1K' | '2K' | '4K';
|
|
16
|
+
/**
|
|
17
|
+
* Quality presets for image generation
|
|
18
|
+
* - 'fast': Nano Banana 2, fastest generation (default)
|
|
19
|
+
* - 'balanced': Nano Banana 2 with enhanced thinking, better quality
|
|
20
|
+
* - 'quality': Nano Banana Pro, highest quality output
|
|
21
|
+
*/
|
|
22
|
+
export type ImageQuality = 'fast' | 'balanced' | 'quality';
|
|
23
|
+
/**
|
|
24
|
+
* Supported quality preset values
|
|
25
|
+
*/
|
|
26
|
+
export declare const IMAGE_QUALITY_VALUES: readonly ImageQuality[];
|
|
27
|
+
/**
|
|
28
|
+
* Gemini image generation model identifiers
|
|
29
|
+
*/
|
|
30
|
+
export declare const GEMINI_MODELS: {
|
|
31
|
+
/** Nano Banana 2 - fast generation with Flash speed */
|
|
32
|
+
readonly FLASH: "gemini-3.1-flash-image-preview";
|
|
33
|
+
/** Nano Banana Pro - highest quality output */
|
|
34
|
+
readonly PRO: "gemini-3-pro-image-preview";
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Parameters for image generation using Gemini API
|
|
38
|
+
*/
|
|
39
|
+
export interface GenerateImageParams {
|
|
40
|
+
/** Prompt for image generation */
|
|
41
|
+
prompt: string;
|
|
42
|
+
/** Optional file name for the generated image (if not specified, generates an auto-named file in IMAGE_OUTPUT_DIR) */
|
|
43
|
+
fileName?: string;
|
|
44
|
+
/** Absolute path to input image for editing (optional) */
|
|
45
|
+
inputImagePath?: string;
|
|
46
|
+
/** Base64 encoded input image data (optional) */
|
|
47
|
+
inputImage?: string;
|
|
48
|
+
/** MIME type of the input image (optional, used with inputImage) */
|
|
49
|
+
inputImageMimeType?: string;
|
|
50
|
+
/** Multi-image blending functionality (default: false) */
|
|
51
|
+
blendImages?: boolean;
|
|
52
|
+
/** Maintain character consistency across generations (default: false) */
|
|
53
|
+
maintainCharacterConsistency?: boolean;
|
|
54
|
+
/** Use world knowledge integration for more accurate context (default: false) */
|
|
55
|
+
useWorldKnowledge?: boolean;
|
|
56
|
+
/** Enable Google Search grounding for real-time web information (default: false) */
|
|
57
|
+
useGoogleSearch?: boolean;
|
|
58
|
+
/** Aspect ratio for generated image (default: "1:1") */
|
|
59
|
+
aspectRatio?: AspectRatio;
|
|
60
|
+
/** Image resolution for high-quality output (e.g., "2K", "4K"). Leave unspecified for standard quality */
|
|
61
|
+
imageSize?: ImageSize;
|
|
62
|
+
/** Intended use for the image (e.g., cookbook cover, social media post). Helps tailor visual style and quality */
|
|
63
|
+
purpose?: string;
|
|
64
|
+
/** Quality preset for image generation (default: "fast"). Controls model selection and thinking configuration */
|
|
65
|
+
quality?: ImageQuality;
|
|
66
|
+
/** Return generated image as base64 data in the response (default: false). Image is always saved to disk regardless */
|
|
67
|
+
returnBase64?: boolean;
|
|
68
|
+
/** Multiple input images as base64 for multi-image composition (optional). Cannot be used with other image input params */
|
|
69
|
+
inputImages?: Array<{
|
|
70
|
+
data: string;
|
|
71
|
+
mimeType: string;
|
|
72
|
+
}>;
|
|
73
|
+
/** Multiple input image file paths for multi-image composition (optional). Cannot be used with other image input params */
|
|
74
|
+
inputImagePaths?: string[];
|
|
75
|
+
/** Skip prompt enhancement and use the prompt as-is (default: false). Useful for multi-image blending where enhancement may overwrite intent */
|
|
76
|
+
skipPromptEnhancement?: boolean;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* MCP server configuration
|
|
80
|
+
*/
|
|
81
|
+
export interface MCPServerConfig {
|
|
82
|
+
/** Server name */
|
|
83
|
+
name: string;
|
|
84
|
+
/** Version */
|
|
85
|
+
version: string;
|
|
86
|
+
/** Default image output directory */
|
|
87
|
+
defaultOutputDir: string;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Content types for MCP responses
|
|
91
|
+
*/
|
|
92
|
+
export type McpContent = {
|
|
93
|
+
type: 'text';
|
|
94
|
+
text: string;
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* MCP Tool Response format
|
|
98
|
+
*/
|
|
99
|
+
export interface McpToolResponse {
|
|
100
|
+
content: McpContent[];
|
|
101
|
+
isError?: boolean;
|
|
102
|
+
structuredContent?: unknown;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Structured content for successful responses
|
|
106
|
+
*/
|
|
107
|
+
export interface StructuredContent {
|
|
108
|
+
type: 'resource';
|
|
109
|
+
resource: {
|
|
110
|
+
uri: string;
|
|
111
|
+
name: string;
|
|
112
|
+
mimeType: string;
|
|
113
|
+
};
|
|
114
|
+
metadata: {
|
|
115
|
+
model: string;
|
|
116
|
+
processingTime: number;
|
|
117
|
+
contextMethod: string;
|
|
118
|
+
timestamp: string;
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=mcp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/types/mcp.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AAEH;;GAEG;AACH,MAAM,MAAM,WAAW,GACnB,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,MAAM,GACN,MAAM,GACN,MAAM,CAAA;AAEV;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;AAE1C;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS,CAAA;AAE1D;;GAEG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,YAAY,EAI9C,CAAA;AAEV;;GAEG;AACH,eAAO,MAAM,aAAa;IACxB,uDAAuD;;IAEvD,+CAA+C;;CAEvC,CAAA;AAEV;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,kCAAkC;IAClC,MAAM,EAAE,MAAM,CAAA;IACd,sHAAsH;IACtH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,0DAA0D;IAC1D,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,iDAAiD;IACjD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,oEAAoE;IACpE,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,0DAA0D;IAC1D,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,yEAAyE;IACzE,4BAA4B,CAAC,EAAE,OAAO,CAAA;IACtC,iFAAiF;IACjF,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,oFAAoF;IACpF,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,wDAAwD;IACxD,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,0GAA0G;IAC1G,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB,kHAAkH;IAClH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,iHAAiH;IACjH,OAAO,CAAC,EAAE,YAAY,CAAA;IACtB,uHAAuH;IACvH,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,2HAA2H;IAC3H,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACvD,2HAA2H;IAC3H,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;IAC1B,gJAAgJ;IAChJ,qBAAqB,CAAC,EAAE,OAAO,CAAA;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,kBAAkB;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,cAAc;IACd,OAAO,EAAE,MAAM,CAAA;IACf,qCAAqC;IACrC,gBAAgB,EAAE,MAAM,CAAA;CACzB;AAED;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,UAAU,EAAE,CAAA;IACrB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,UAAU,CAAA;IAChB,QAAQ,EAAE;QACR,GAAG,EAAE,MAAM,CAAA;QACX,IAAI,EAAE,MAAM,CAAA;QACZ,QAAQ,EAAE,MAAM,CAAA;KACjB,CAAA;IACD,QAAQ,EAAE;QACR,KAAK,EAAE,MAAM,CAAA;QACb,cAAc,EAAE,MAAM,CAAA;QACtB,aAAa,EAAE,MAAM,CAAA;QACrB,SAAS,EAAE,MAAM,CAAA;KAClB,CAAA;CACF"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP-related type definitions
|
|
3
|
+
* Defines types related to @modelcontextprotocol/sdk and project-specific types
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Supported quality preset values
|
|
7
|
+
*/
|
|
8
|
+
export const IMAGE_QUALITY_VALUES = [
|
|
9
|
+
'fast',
|
|
10
|
+
'balanced',
|
|
11
|
+
'quality',
|
|
12
|
+
];
|
|
13
|
+
/**
|
|
14
|
+
* Gemini image generation model identifiers
|
|
15
|
+
*/
|
|
16
|
+
export const GEMINI_MODELS = {
|
|
17
|
+
/** Nano Banana 2 - fast generation with Flash speed */
|
|
18
|
+
FLASH: 'gemini-3.1-flash-image-preview',
|
|
19
|
+
/** Nano Banana Pro - highest quality output */
|
|
20
|
+
PRO: 'gemini-3-pro-image-preview',
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=mcp.js.map
|