@stabgan/openrouter-mcp-multimodal 1.2.0 → 1.2.1
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/dist/index.js +7 -8
- package/dist/index.js.map +1 -1
- package/dist/tool-handlers/analyze-image.d.ts +16 -2
- package/dist/tool-handlers/analyze-image.js +105 -51
- package/dist/tool-handlers/analyze-image.js.map +1 -1
- package/dist/tool-handlers/multi-image-analysis.d.ts +23 -0
- package/dist/tool-handlers/multi-image-analysis.js +218 -52
- package/dist/tool-handlers/multi-image-analysis.js.map +1 -1
- package/dist/tool-handlers.js +35 -5
- package/dist/tool-handlers.js.map +1 -1
- package/package.json +5 -4
package/dist/index.js
CHANGED
|
@@ -3,13 +3,15 @@
|
|
|
3
3
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
4
4
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
5
5
|
import { ToolHandlers } from './tool-handlers.js';
|
|
6
|
+
// Define the default model to use when none is specified
|
|
7
|
+
const DEFAULT_MODEL = 'qwen/qwen2.5-vl-32b-instruct:free';
|
|
6
8
|
class OpenRouterMultimodalServer {
|
|
7
9
|
server;
|
|
8
10
|
toolHandlers; // Using definite assignment assertion
|
|
9
11
|
constructor() {
|
|
10
|
-
//
|
|
12
|
+
// Retrieve API key and default model from environment variables
|
|
11
13
|
const apiKey = process.env.OPENROUTER_API_KEY;
|
|
12
|
-
const defaultModel = process.env.
|
|
14
|
+
const defaultModel = process.env.DEFAULT_MODEL || DEFAULT_MODEL;
|
|
13
15
|
// Check if API key is provided
|
|
14
16
|
if (!apiKey) {
|
|
15
17
|
throw new Error('OPENROUTER_API_KEY environment variable is required');
|
|
@@ -39,12 +41,9 @@ class OpenRouterMultimodalServer {
|
|
|
39
41
|
console.error('Using API key from environment variable');
|
|
40
42
|
console.error('Note: To use OpenRouter Multimodal, add the API key to your environment variables:');
|
|
41
43
|
console.error(' OPENROUTER_API_KEY=your-api-key');
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
else {
|
|
46
|
-
console.error(' No default model set. You will need to specify a model in each request.');
|
|
47
|
-
}
|
|
44
|
+
const modelDisplay = process.env.OPENROUTER_DEFAULT_MODEL || DEFAULT_MODEL;
|
|
45
|
+
console.error(` Using default model: ${modelDisplay}`);
|
|
46
|
+
console.error('Server is ready to process tool calls. Waiting for input...');
|
|
48
47
|
}
|
|
49
48
|
}
|
|
50
49
|
const server = new OpenRouterMultimodalServer();
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,mCAAmC;AACnC,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,MAAM,0BAA0B;IACtB,MAAM,CAAS;IACf,YAAY,CAAgB,CAAC,sCAAsC;IAE3E;QACE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,mCAAmC;AACnC,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,yDAAyD;AACzD,MAAM,aAAa,GAAG,mCAAmC,CAAC;AAE1D,MAAM,0BAA0B;IACtB,MAAM,CAAS;IACf,YAAY,CAAgB,CAAC,sCAAsC;IAE3E;QACE,gEAAgE;QAChE,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;QAC9C,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,aAAa,CAAC;QAEhE,+BAA+B;QAC/B,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;QACzE,CAAC;QAED,wBAAwB;QACxB,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CACtB;YACE,IAAI,EAAE,8BAA8B;YACpC,OAAO,EAAE,OAAO;SACjB,EACD;YACE,YAAY,EAAE;gBACZ,KAAK,EAAE,EAAE;aACV;SACF,CACF,CAAC;QAEF,wBAAwB;QACxB,IAAI,CAAC,MAAM,CAAC,OAAO,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;QAErE,2BAA2B;QAC3B,IAAI,CAAC,YAAY,GAAG,IAAI,YAAY,CAClC,IAAI,CAAC,MAAM,EACX,MAAM,EACN,YAAY,CACb,CAAC;QAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;YAC9B,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YAC1B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,GAAG;QACP,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC7C,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACrC,OAAO,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACnE,OAAO,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;QACzD,OAAO,CAAC,KAAK,CAAC,oFAAoF,CAAC,CAAC;QACpG,OAAO,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAEvD,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,IAAI,aAAa,CAAC;QAC3E,OAAO,CAAC,KAAK,CAAC,8BAA8B,YAAY,EAAE,CAAC,CAAC;QAC5D,OAAO,CAAC,KAAK,CAAC,6DAA6D,CAAC,CAAC;IAC/E,CAAC;CACF;AAED,MAAM,MAAM,GAAG,IAAI,0BAA0B,EAAE,CAAC;AAChD,MAAM,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import OpenAI from 'openai';
|
|
2
2
|
export interface AnalyzeImageToolRequest {
|
|
3
|
-
image_path
|
|
4
|
-
image_url?: string;
|
|
3
|
+
image_path: string;
|
|
5
4
|
question?: string;
|
|
6
5
|
model?: string;
|
|
7
6
|
}
|
|
7
|
+
/**
|
|
8
|
+
* Handler for analyzing a single image
|
|
9
|
+
*/
|
|
8
10
|
export declare function handleAnalyzeImage(request: {
|
|
9
11
|
params: {
|
|
10
12
|
arguments: AnalyzeImageToolRequest;
|
|
@@ -14,6 +16,12 @@ export declare function handleAnalyzeImage(request: {
|
|
|
14
16
|
type: string;
|
|
15
17
|
text: string;
|
|
16
18
|
}[];
|
|
19
|
+
metadata: {
|
|
20
|
+
model: string;
|
|
21
|
+
usage: OpenAI.Completions.CompletionUsage | undefined;
|
|
22
|
+
error_type?: undefined;
|
|
23
|
+
error_message?: undefined;
|
|
24
|
+
};
|
|
17
25
|
isError?: undefined;
|
|
18
26
|
} | {
|
|
19
27
|
content: {
|
|
@@ -21,4 +29,10 @@ export declare function handleAnalyzeImage(request: {
|
|
|
21
29
|
text: string;
|
|
22
30
|
}[];
|
|
23
31
|
isError: boolean;
|
|
32
|
+
metadata: {
|
|
33
|
+
error_type: string;
|
|
34
|
+
error_message: string;
|
|
35
|
+
model?: undefined;
|
|
36
|
+
usage?: undefined;
|
|
37
|
+
};
|
|
24
38
|
}>;
|
|
@@ -3,6 +3,9 @@ import { promises as fs } from 'fs';
|
|
|
3
3
|
import sharp from 'sharp';
|
|
4
4
|
import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js';
|
|
5
5
|
import fetch from 'node-fetch';
|
|
6
|
+
import { findSuitableFreeModel } from './multi-image-analysis.js';
|
|
7
|
+
// Default model for image analysis
|
|
8
|
+
const DEFAULT_FREE_MODEL = 'qwen/qwen2.5-vl-32b-instruct:free';
|
|
6
9
|
async function fetchImageAsBuffer(url) {
|
|
7
10
|
try {
|
|
8
11
|
// Handle data URLs
|
|
@@ -65,67 +68,110 @@ async function processImage(buffer) {
|
|
|
65
68
|
throw error;
|
|
66
69
|
}
|
|
67
70
|
}
|
|
68
|
-
|
|
69
|
-
|
|
71
|
+
/**
|
|
72
|
+
* Converts the image at the given path to a base64 string
|
|
73
|
+
*/
|
|
74
|
+
async function imageToBase64(imagePath) {
|
|
70
75
|
try {
|
|
71
|
-
//
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
if (!imagePath && !imageUrl) {
|
|
75
|
-
throw new McpError(ErrorCode.InvalidParams, 'Either image_path or image_url must be provided');
|
|
76
|
+
// Ensure the image path is absolute
|
|
77
|
+
if (!path.isAbsolute(imagePath)) {
|
|
78
|
+
throw new McpError(ErrorCode.InvalidParams, 'Image path must be absolute');
|
|
76
79
|
}
|
|
77
|
-
//
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
// Use the provided URL directly
|
|
81
|
-
imageSource = imageUrl;
|
|
80
|
+
// Check if the file exists
|
|
81
|
+
try {
|
|
82
|
+
await fs.access(imagePath);
|
|
82
83
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
84
|
+
catch (error) {
|
|
85
|
+
throw new McpError(ErrorCode.InvalidParams, `File not found: ${imagePath}`);
|
|
86
|
+
}
|
|
87
|
+
// Read the file as a buffer
|
|
88
|
+
const buffer = await fs.readFile(imagePath);
|
|
89
|
+
// Determine MIME type from file extension
|
|
90
|
+
const extension = path.extname(imagePath).toLowerCase();
|
|
91
|
+
let mimeType;
|
|
92
|
+
switch (extension) {
|
|
93
|
+
case '.png':
|
|
94
|
+
mimeType = 'image/png';
|
|
95
|
+
break;
|
|
96
|
+
case '.jpg':
|
|
97
|
+
case '.jpeg':
|
|
98
|
+
mimeType = 'image/jpeg';
|
|
99
|
+
break;
|
|
100
|
+
case '.webp':
|
|
101
|
+
mimeType = 'image/webp';
|
|
102
|
+
break;
|
|
103
|
+
case '.gif':
|
|
104
|
+
mimeType = 'image/gif';
|
|
105
|
+
break;
|
|
106
|
+
case '.bmp':
|
|
107
|
+
mimeType = 'image/bmp';
|
|
108
|
+
break;
|
|
109
|
+
default:
|
|
110
|
+
mimeType = 'application/octet-stream';
|
|
111
|
+
}
|
|
112
|
+
// Convert buffer to base64
|
|
113
|
+
const base64 = buffer.toString('base64');
|
|
114
|
+
return { base64, mimeType };
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
console.error('Error converting image to base64:', error);
|
|
118
|
+
throw error;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Handler for analyzing a single image
|
|
123
|
+
*/
|
|
124
|
+
export async function handleAnalyzeImage(request, openai, defaultModel) {
|
|
125
|
+
const args = request.params.arguments;
|
|
126
|
+
try {
|
|
127
|
+
// Validate inputs
|
|
128
|
+
if (!args.image_path) {
|
|
129
|
+
throw new McpError(ErrorCode.InvalidParams, 'An image path is required');
|
|
93
130
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
throw new McpError(ErrorCode.InvalidParams, 'No image source provided');
|
|
131
|
+
if (!args.question) {
|
|
132
|
+
throw new McpError(ErrorCode.InvalidParams, 'A question about the image is required');
|
|
97
133
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
//
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
134
|
+
console.error(`Processing image: ${args.image_path}`);
|
|
135
|
+
// Convert the image to base64
|
|
136
|
+
const { base64, mimeType } = await imageToBase64(args.image_path);
|
|
137
|
+
// Create the content array for the OpenAI API
|
|
138
|
+
const content = [
|
|
139
|
+
{
|
|
140
|
+
type: 'text',
|
|
141
|
+
text: args.question
|
|
142
|
+
},
|
|
107
143
|
{
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
{
|
|
111
|
-
|
|
112
|
-
text: args.question || "What's in this image?"
|
|
113
|
-
},
|
|
114
|
-
{
|
|
115
|
-
type: 'image_url',
|
|
116
|
-
image_url: {
|
|
117
|
-
url: `data:image/jpeg;base64,${base64Image}`
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
]
|
|
144
|
+
type: 'image_url',
|
|
145
|
+
image_url: {
|
|
146
|
+
url: `data:${mimeType};base64,${base64}`
|
|
147
|
+
}
|
|
121
148
|
}
|
|
122
149
|
];
|
|
123
|
-
|
|
124
|
-
//
|
|
150
|
+
// Select model with priority:
|
|
151
|
+
// 1. User-specified model
|
|
152
|
+
// 2. Default model from environment
|
|
153
|
+
// 3. Default free vision model (qwen/qwen2.5-vl-32b-instruct:free)
|
|
154
|
+
let model = args.model || defaultModel || DEFAULT_FREE_MODEL;
|
|
155
|
+
// If a model is specified but not our default free model, verify it exists
|
|
156
|
+
if (model !== DEFAULT_FREE_MODEL) {
|
|
157
|
+
try {
|
|
158
|
+
await openai.models.retrieve(model);
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
console.error(`Specified model ${model} not found, falling back to auto-selection`);
|
|
162
|
+
model = await findSuitableFreeModel(openai);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
console.error(`Making API call with model: ${model}`);
|
|
166
|
+
// Make the API call
|
|
125
167
|
const completion = await openai.chat.completions.create({
|
|
126
168
|
model,
|
|
127
|
-
messages:
|
|
169
|
+
messages: [{
|
|
170
|
+
role: 'user',
|
|
171
|
+
content
|
|
172
|
+
}]
|
|
128
173
|
});
|
|
174
|
+
// Return the analysis result
|
|
129
175
|
return {
|
|
130
176
|
content: [
|
|
131
177
|
{
|
|
@@ -133,10 +179,14 @@ export async function handleAnalyzeImage(request, openai, defaultModel) {
|
|
|
133
179
|
text: completion.choices[0].message.content || '',
|
|
134
180
|
},
|
|
135
181
|
],
|
|
182
|
+
metadata: {
|
|
183
|
+
model: completion.model,
|
|
184
|
+
usage: completion.usage
|
|
185
|
+
}
|
|
136
186
|
};
|
|
137
187
|
}
|
|
138
188
|
catch (error) {
|
|
139
|
-
console.error('Error
|
|
189
|
+
console.error('Error in image analysis:', error);
|
|
140
190
|
if (error instanceof McpError) {
|
|
141
191
|
throw error;
|
|
142
192
|
}
|
|
@@ -148,6 +198,10 @@ export async function handleAnalyzeImage(request, openai, defaultModel) {
|
|
|
148
198
|
},
|
|
149
199
|
],
|
|
150
200
|
isError: true,
|
|
201
|
+
metadata: {
|
|
202
|
+
error_type: error instanceof Error ? error.constructor.name : 'Unknown',
|
|
203
|
+
error_message: error instanceof Error ? error.message : String(error)
|
|
204
|
+
}
|
|
151
205
|
};
|
|
152
206
|
}
|
|
153
207
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analyze-image.js","sourceRoot":"","sources":["../../src/tool-handlers/analyze-image.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AAEzE,OAAO,KAAK,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"analyze-image.js","sourceRoot":"","sources":["../../src/tool-handlers/analyze-image.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,6 +8,13 @@ export interface MultiImageAnalysisToolRequest {
|
|
|
8
8
|
markdown_response?: boolean;
|
|
9
9
|
model?: string;
|
|
10
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* Find a suitable free model with vision capabilities, defaulting to Qwen
|
|
13
|
+
*/
|
|
14
|
+
export declare function findSuitableFreeModel(openai: OpenAI): Promise<string>;
|
|
15
|
+
/**
|
|
16
|
+
* Process and analyze multiple images using OpenRouter
|
|
17
|
+
*/
|
|
11
18
|
export declare function handleMultiImageAnalysis(request: {
|
|
12
19
|
params: {
|
|
13
20
|
arguments: MultiImageAnalysisToolRequest;
|
|
@@ -17,6 +24,14 @@ export declare function handleMultiImageAnalysis(request: {
|
|
|
17
24
|
type: string;
|
|
18
25
|
text: string;
|
|
19
26
|
}[];
|
|
27
|
+
metadata: {
|
|
28
|
+
model: string;
|
|
29
|
+
usage: OpenAI.Completions.CompletionUsage | undefined;
|
|
30
|
+
successful_images: number;
|
|
31
|
+
failed_images: number;
|
|
32
|
+
error_type?: undefined;
|
|
33
|
+
error_message?: undefined;
|
|
34
|
+
};
|
|
20
35
|
isError?: undefined;
|
|
21
36
|
} | {
|
|
22
37
|
content: {
|
|
@@ -24,4 +39,12 @@ export declare function handleMultiImageAnalysis(request: {
|
|
|
24
39
|
text: string;
|
|
25
40
|
}[];
|
|
26
41
|
isError: boolean;
|
|
42
|
+
metadata: {
|
|
43
|
+
error_type: string;
|
|
44
|
+
error_message: string;
|
|
45
|
+
model?: undefined;
|
|
46
|
+
usage?: undefined;
|
|
47
|
+
successful_images?: undefined;
|
|
48
|
+
failed_images?: undefined;
|
|
49
|
+
};
|
|
27
50
|
}>;
|
|
@@ -1,81 +1,203 @@
|
|
|
1
1
|
import fetch from 'node-fetch';
|
|
2
2
|
import sharp from 'sharp';
|
|
3
3
|
import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import { promises as fs } from 'fs';
|
|
6
|
+
import { tmpdir } from 'os';
|
|
7
|
+
// Remove uuid import as we'll use a simple random string generator instead
|
|
8
|
+
// import { v4 as uuidv4 } from 'uuid';
|
|
9
|
+
// Default model for image analysis
|
|
10
|
+
const DEFAULT_FREE_MODEL = 'qwen/qwen2.5-vl-32b-instruct:free';
|
|
11
|
+
// Image processing constants
|
|
12
|
+
const MAX_DIMENSION = 800;
|
|
13
|
+
const JPEG_QUALITY = 80;
|
|
14
|
+
const MAX_RETRY_ATTEMPTS = 3;
|
|
15
|
+
const RETRY_DELAY = 1000; // ms
|
|
16
|
+
// Simple random ID generator to replace uuid
|
|
17
|
+
function generateRandomId() {
|
|
18
|
+
return Math.random().toString(36).substring(2, 15) +
|
|
19
|
+
Math.random().toString(36).substring(2, 15);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Sleep function for retry mechanisms
|
|
23
|
+
*/
|
|
24
|
+
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
|
|
25
|
+
/**
|
|
26
|
+
* Get MIME type from file extension or data URL
|
|
27
|
+
*/
|
|
28
|
+
function getMimeType(url) {
|
|
29
|
+
if (url.startsWith('data:')) {
|
|
30
|
+
const match = url.match(/^data:([^;]+);/);
|
|
31
|
+
return match ? match[1] : 'application/octet-stream';
|
|
32
|
+
}
|
|
33
|
+
const extension = path.extname(url.split('?')[0]).toLowerCase();
|
|
34
|
+
switch (extension) {
|
|
35
|
+
case '.png': return 'image/png';
|
|
36
|
+
case '.jpg':
|
|
37
|
+
case '.jpeg': return 'image/jpeg';
|
|
38
|
+
case '.webp': return 'image/webp';
|
|
39
|
+
case '.gif': return 'image/gif';
|
|
40
|
+
case '.bmp': return 'image/bmp';
|
|
41
|
+
case '.svg': return 'image/svg+xml';
|
|
42
|
+
default: return 'application/octet-stream';
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Fetch image from various sources: data URLs, file paths, or remote URLs
|
|
47
|
+
*/
|
|
4
48
|
async function fetchImageAsBuffer(url) {
|
|
5
49
|
try {
|
|
6
50
|
// Handle data URLs
|
|
7
51
|
if (url.startsWith('data:')) {
|
|
8
52
|
const matches = url.match(/^data:([A-Za-z-+\/]+);base64,(.+)$/);
|
|
9
53
|
if (!matches || matches.length !== 3) {
|
|
10
|
-
throw new Error('Invalid data URL');
|
|
54
|
+
throw new Error('Invalid data URL format');
|
|
11
55
|
}
|
|
12
56
|
return Buffer.from(matches[2], 'base64');
|
|
13
57
|
}
|
|
14
|
-
// Handle file URLs
|
|
58
|
+
// Handle file URLs with file:// protocol
|
|
15
59
|
if (url.startsWith('file://')) {
|
|
16
60
|
const filePath = url.replace('file://', '');
|
|
17
|
-
|
|
18
|
-
|
|
61
|
+
try {
|
|
62
|
+
return await fs.readFile(filePath);
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
console.error(`Error reading file at ${filePath}:`, error);
|
|
66
|
+
throw new Error(`Failed to read file: ${filePath}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Handle absolute and relative file paths
|
|
70
|
+
if (url.startsWith('/') || url.startsWith('./') || url.startsWith('../') || /^[A-Za-z]:\\/.test(url)) {
|
|
71
|
+
try {
|
|
72
|
+
return await fs.readFile(url);
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
console.error(`Error reading file at ${url}:`, error);
|
|
76
|
+
throw new Error(`Failed to read file: ${url}`);
|
|
77
|
+
}
|
|
19
78
|
}
|
|
20
79
|
// Handle http/https URLs
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
80
|
+
if (url.startsWith('http://') || url.startsWith('https://')) {
|
|
81
|
+
for (let attempt = 0; attempt < MAX_RETRY_ATTEMPTS; attempt++) {
|
|
82
|
+
try {
|
|
83
|
+
// Use AbortController for timeout instead of timeout option
|
|
84
|
+
const controller = new AbortController();
|
|
85
|
+
const timeoutId = setTimeout(() => controller.abort(), 15000);
|
|
86
|
+
const response = await fetch(url, {
|
|
87
|
+
signal: controller.signal,
|
|
88
|
+
headers: {
|
|
89
|
+
'User-Agent': 'OpenRouter-MCP-Server/1.0'
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
// Clear the timeout to prevent memory leaks
|
|
93
|
+
clearTimeout(timeoutId);
|
|
94
|
+
if (!response.ok) {
|
|
95
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
96
|
+
}
|
|
97
|
+
return Buffer.from(await response.arrayBuffer());
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
console.error(`Error fetching URL (attempt ${attempt + 1}/${MAX_RETRY_ATTEMPTS}): ${url}`, error);
|
|
101
|
+
if (attempt < MAX_RETRY_ATTEMPTS - 1) {
|
|
102
|
+
// Exponential backoff with jitter
|
|
103
|
+
const delay = RETRY_DELAY * Math.pow(2, attempt) * (0.5 + Math.random() * 0.5);
|
|
104
|
+
await sleep(delay);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
throw error;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
24
111
|
}
|
|
25
|
-
|
|
112
|
+
// If we get here, the URL format is unsupported
|
|
113
|
+
throw new Error(`Unsupported URL format: ${url}`);
|
|
26
114
|
}
|
|
27
115
|
catch (error) {
|
|
28
116
|
console.error(`Error fetching image from ${url}:`, error);
|
|
29
117
|
throw error;
|
|
30
118
|
}
|
|
119
|
+
// TypeScript requires a return statement here, but this is unreachable
|
|
120
|
+
return Buffer.from([]);
|
|
31
121
|
}
|
|
32
|
-
|
|
122
|
+
/**
|
|
123
|
+
* Process and optimize image for API consumption
|
|
124
|
+
*/
|
|
125
|
+
async function processImage(buffer, mimeType) {
|
|
33
126
|
try {
|
|
34
|
-
//
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
127
|
+
// Create a temporary directory for processing if needed
|
|
128
|
+
const tempDir = path.join(tmpdir(), `openrouter-mcp-${generateRandomId()}`);
|
|
129
|
+
await fs.mkdir(tempDir, { recursive: true });
|
|
130
|
+
// Get image info
|
|
131
|
+
let sharpInstance = sharp(buffer);
|
|
132
|
+
const metadata = await sharpInstance.metadata();
|
|
133
|
+
// Skip processing for small images
|
|
134
|
+
if (metadata.width && metadata.height &&
|
|
135
|
+
metadata.width <= MAX_DIMENSION &&
|
|
136
|
+
metadata.height <= MAX_DIMENSION &&
|
|
137
|
+
(mimeType === 'image/jpeg' || mimeType === 'image/webp')) {
|
|
138
|
+
return buffer.toString('base64');
|
|
139
|
+
}
|
|
140
|
+
// Resize larger images
|
|
39
141
|
if (metadata.width && metadata.height) {
|
|
40
142
|
const largerDimension = Math.max(metadata.width, metadata.height);
|
|
41
143
|
if (largerDimension > MAX_DIMENSION) {
|
|
42
144
|
const resizeOptions = metadata.width > metadata.height
|
|
43
145
|
? { width: MAX_DIMENSION }
|
|
44
146
|
: { height: MAX_DIMENSION };
|
|
45
|
-
|
|
46
|
-
.resize(resizeOptions)
|
|
47
|
-
.jpeg({ quality: JPEG_QUALITY })
|
|
48
|
-
.toBuffer();
|
|
49
|
-
return resizedBuffer.toString('base64');
|
|
147
|
+
sharpInstance = sharpInstance.resize(resizeOptions);
|
|
50
148
|
}
|
|
51
149
|
}
|
|
52
|
-
//
|
|
53
|
-
const
|
|
150
|
+
// Convert to JPEG for consistency and small size
|
|
151
|
+
const processedBuffer = await sharpInstance
|
|
54
152
|
.jpeg({ quality: JPEG_QUALITY })
|
|
55
153
|
.toBuffer();
|
|
56
|
-
return
|
|
154
|
+
return processedBuffer.toString('base64');
|
|
57
155
|
}
|
|
58
156
|
catch (error) {
|
|
59
157
|
console.error('Error processing image:', error);
|
|
60
|
-
|
|
158
|
+
// If sharp processing fails, return the original buffer
|
|
159
|
+
// This is a fallback to ensure we don't completely fail on processing errors
|
|
160
|
+
console.error('Returning original image without processing');
|
|
161
|
+
return buffer.toString('base64');
|
|
61
162
|
}
|
|
62
163
|
}
|
|
63
|
-
|
|
64
|
-
|
|
164
|
+
/**
|
|
165
|
+
* Find a suitable free model with vision capabilities, defaulting to Qwen
|
|
166
|
+
*/
|
|
167
|
+
export async function findSuitableFreeModel(openai) {
|
|
65
168
|
try {
|
|
66
|
-
//
|
|
169
|
+
// First try with an exact match for our preferred model
|
|
170
|
+
const preferredModel = DEFAULT_FREE_MODEL;
|
|
171
|
+
try {
|
|
172
|
+
// Check if our preferred model is available
|
|
173
|
+
const modelInfo = await openai.models.retrieve(preferredModel);
|
|
174
|
+
if (modelInfo && modelInfo.id) {
|
|
175
|
+
console.error(`Using preferred model: ${preferredModel}`);
|
|
176
|
+
return preferredModel;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
console.error(`Preferred model ${preferredModel} not available, searching for alternatives...`);
|
|
181
|
+
}
|
|
182
|
+
// Query available models
|
|
67
183
|
const modelsResponse = await openai.models.list();
|
|
68
|
-
if (!modelsResponse
|
|
69
|
-
|
|
184
|
+
if (!modelsResponse?.data || modelsResponse.data.length === 0) {
|
|
185
|
+
console.error('No models found, using default fallback model');
|
|
186
|
+
return DEFAULT_FREE_MODEL;
|
|
70
187
|
}
|
|
71
|
-
//
|
|
72
|
-
const
|
|
73
|
-
.filter(model =>
|
|
188
|
+
// First, try to find free vision models
|
|
189
|
+
const freeVisionModels = modelsResponse.data
|
|
190
|
+
.filter(model => {
|
|
191
|
+
const modelId = model.id.toLowerCase();
|
|
192
|
+
return modelId.includes('free') &&
|
|
193
|
+
(modelId.includes('vl') || modelId.includes('vision') || modelId.includes('claude') ||
|
|
194
|
+
modelId.includes('gemini') || modelId.includes('gpt-4') || modelId.includes('qwen'));
|
|
195
|
+
})
|
|
74
196
|
.map(model => {
|
|
75
|
-
//
|
|
197
|
+
// Extract context length if available
|
|
76
198
|
let contextLength = 0;
|
|
77
199
|
try {
|
|
78
|
-
const modelAny = model;
|
|
200
|
+
const modelAny = model;
|
|
79
201
|
if (typeof modelAny.context_length === 'number') {
|
|
80
202
|
contextLength = modelAny.context_length;
|
|
81
203
|
}
|
|
@@ -91,19 +213,25 @@ async function findSuitableFreeModel(openai) {
|
|
|
91
213
|
contextLength: contextLength || 0
|
|
92
214
|
};
|
|
93
215
|
});
|
|
94
|
-
if (
|
|
95
|
-
|
|
216
|
+
if (freeVisionModels.length > 0) {
|
|
217
|
+
// Sort by context length and pick the one with the largest context window
|
|
218
|
+
freeVisionModels.sort((a, b) => b.contextLength - a.contextLength);
|
|
219
|
+
const selectedModel = freeVisionModels[0].id;
|
|
220
|
+
console.error(`Selected free vision model: ${selectedModel} with context length: ${freeVisionModels[0].contextLength}`);
|
|
221
|
+
return selectedModel;
|
|
96
222
|
}
|
|
97
|
-
//
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
return freeModels[0].id;
|
|
223
|
+
// If no free vision models found, fallback to our default
|
|
224
|
+
console.error('No free vision models found, using default fallback model');
|
|
225
|
+
return DEFAULT_FREE_MODEL;
|
|
101
226
|
}
|
|
102
227
|
catch (error) {
|
|
103
|
-
console.error('Error finding suitable
|
|
104
|
-
return
|
|
228
|
+
console.error('Error finding suitable model:', error);
|
|
229
|
+
return DEFAULT_FREE_MODEL;
|
|
105
230
|
}
|
|
106
231
|
}
|
|
232
|
+
/**
|
|
233
|
+
* Process and analyze multiple images using OpenRouter
|
|
234
|
+
*/
|
|
107
235
|
export async function handleMultiImageAnalysis(request, openai, defaultModel) {
|
|
108
236
|
const args = request.params.arguments;
|
|
109
237
|
try {
|
|
@@ -119,39 +247,57 @@ export async function handleMultiImageAnalysis(request, openai, defaultModel) {
|
|
|
119
247
|
type: 'text',
|
|
120
248
|
text: args.prompt
|
|
121
249
|
}];
|
|
250
|
+
// Track successful and failed images for reporting
|
|
251
|
+
const successfulImages = [];
|
|
252
|
+
const failedImages = [];
|
|
122
253
|
// Process each image
|
|
123
|
-
for (const image of args.images) {
|
|
254
|
+
for (const [index, image] of args.images.entries()) {
|
|
124
255
|
try {
|
|
256
|
+
console.error(`Processing image ${index + 1}/${args.images.length}: ${image.url.substring(0, 50)}...`);
|
|
257
|
+
// Get MIME type
|
|
258
|
+
const mimeType = getMimeType(image.url);
|
|
125
259
|
// Fetch and process the image
|
|
126
260
|
const imageBuffer = await fetchImageAsBuffer(image.url);
|
|
127
|
-
const base64Image = await processImage(imageBuffer);
|
|
261
|
+
const base64Image = await processImage(imageBuffer, mimeType);
|
|
262
|
+
// Use JPEG as the output format for consistency
|
|
263
|
+
const outputMimeType = 'image/jpeg';
|
|
128
264
|
// Add to content
|
|
129
265
|
content.push({
|
|
130
266
|
type: 'image_url',
|
|
131
267
|
image_url: {
|
|
132
|
-
url: `data
|
|
268
|
+
url: `data:${outputMimeType};base64,${base64Image}`
|
|
133
269
|
}
|
|
134
270
|
});
|
|
271
|
+
successfulImages.push(image.url);
|
|
135
272
|
}
|
|
136
273
|
catch (error) {
|
|
137
|
-
console.error(`Error processing image ${image.url}:`, error);
|
|
274
|
+
console.error(`Error processing image ${index + 1} (${image.url.substring(0, 30)}...):`, error);
|
|
275
|
+
failedImages.push({ url: image.url, error: error instanceof Error ? error.message : String(error) });
|
|
138
276
|
// Continue with other images if one fails
|
|
139
277
|
}
|
|
140
278
|
}
|
|
141
279
|
// If no images were successfully processed
|
|
142
280
|
if (content.length === 1) {
|
|
143
|
-
|
|
281
|
+
const errorDetails = failedImages.map(img => `${img.url.substring(0, 30)}...: ${img.error}`).join('; ');
|
|
282
|
+
throw new Error(`Failed to process any of the provided images. Errors: ${errorDetails}`);
|
|
144
283
|
}
|
|
145
284
|
// Select model with priority:
|
|
146
285
|
// 1. User-specified model
|
|
147
286
|
// 2. Default model from environment
|
|
148
|
-
// 3.
|
|
149
|
-
let model = args.model || defaultModel;
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
287
|
+
// 3. Default free vision model (qwen/qwen2.5-vl-32b-instruct:free)
|
|
288
|
+
let model = args.model || defaultModel || DEFAULT_FREE_MODEL;
|
|
289
|
+
// If a model is specified but not our default free model, verify it exists
|
|
290
|
+
if (model !== DEFAULT_FREE_MODEL) {
|
|
291
|
+
try {
|
|
292
|
+
await openai.models.retrieve(model);
|
|
293
|
+
}
|
|
294
|
+
catch (error) {
|
|
295
|
+
console.error(`Specified model ${model} not found, falling back to auto-selection`);
|
|
296
|
+
model = await findSuitableFreeModel(openai);
|
|
297
|
+
}
|
|
153
298
|
}
|
|
154
299
|
console.error(`Making API call with model: ${model}`);
|
|
300
|
+
console.error(`Successfully processed ${successfulImages.length} images, ${failedImages.length} failed`);
|
|
155
301
|
// Make the API call
|
|
156
302
|
const completion = await openai.chat.completions.create({
|
|
157
303
|
model,
|
|
@@ -160,13 +306,29 @@ export async function handleMultiImageAnalysis(request, openai, defaultModel) {
|
|
|
160
306
|
content
|
|
161
307
|
}]
|
|
162
308
|
});
|
|
309
|
+
// Format the response
|
|
310
|
+
let responseText = completion.choices[0].message.content || '';
|
|
311
|
+
// Add information about failed images if any
|
|
312
|
+
if (failedImages.length > 0) {
|
|
313
|
+
const formattedErrors = args.markdown_response !== false
|
|
314
|
+
? `\n\n---\n\n**Note:** ${failedImages.length} image(s) could not be processed:\n${failedImages.map((img, i) => `- Image ${i + 1}: ${img.error}`).join('\n')}`
|
|
315
|
+
: `\n\nNote: ${failedImages.length} image(s) could not be processed: ${failedImages.map((img, i) => `Image ${i + 1}: ${img.error}`).join('; ')}`;
|
|
316
|
+
responseText += formattedErrors;
|
|
317
|
+
}
|
|
318
|
+
// Return the analysis result
|
|
163
319
|
return {
|
|
164
320
|
content: [
|
|
165
321
|
{
|
|
166
322
|
type: 'text',
|
|
167
|
-
text:
|
|
323
|
+
text: responseText,
|
|
168
324
|
},
|
|
169
325
|
],
|
|
326
|
+
metadata: {
|
|
327
|
+
model: completion.model,
|
|
328
|
+
usage: completion.usage,
|
|
329
|
+
successful_images: successfulImages.length,
|
|
330
|
+
failed_images: failedImages.length
|
|
331
|
+
}
|
|
170
332
|
};
|
|
171
333
|
}
|
|
172
334
|
catch (error) {
|
|
@@ -182,6 +344,10 @@ export async function handleMultiImageAnalysis(request, openai, defaultModel) {
|
|
|
182
344
|
},
|
|
183
345
|
],
|
|
184
346
|
isError: true,
|
|
347
|
+
metadata: {
|
|
348
|
+
error_type: error instanceof Error ? error.constructor.name : 'Unknown',
|
|
349
|
+
error_message: error instanceof Error ? error.message : String(error)
|
|
350
|
+
}
|
|
185
351
|
};
|
|
186
352
|
}
|
|
187
353
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multi-image-analysis.js","sourceRoot":"","sources":["../../src/tool-handlers/multi-image-analysis.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"multi-image-analysis.js","sourceRoot":"","sources":["../../src/tool-handlers/multi-image-analysis.ts"],"names":[],"mappings":"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"}
|
package/dist/tool-handlers.js
CHANGED
|
@@ -8,6 +8,7 @@ import { handleSearchModels } from './tool-handlers/search-models.js';
|
|
|
8
8
|
import { handleGetModelInfo } from './tool-handlers/get-model-info.js';
|
|
9
9
|
import { handleValidateModel } from './tool-handlers/validate-model.js';
|
|
10
10
|
import { handleMultiImageAnalysis } from './tool-handlers/multi-image-analysis.js';
|
|
11
|
+
import { handleAnalyzeImage } from './tool-handlers/analyze-image.js';
|
|
11
12
|
export class ToolHandlers {
|
|
12
13
|
server;
|
|
13
14
|
openai;
|
|
@@ -34,7 +35,7 @@ export class ToolHandlers {
|
|
|
34
35
|
tools: [
|
|
35
36
|
// Chat Completion Tool
|
|
36
37
|
{
|
|
37
|
-
name: '
|
|
38
|
+
name: 'mcp_openrouter_chat_completion',
|
|
38
39
|
description: 'Send a message to OpenRouter.ai and get a response',
|
|
39
40
|
inputSchema: {
|
|
40
41
|
type: 'object',
|
|
@@ -109,10 +110,33 @@ export class ToolHandlers {
|
|
|
109
110
|
},
|
|
110
111
|
maxContextTokens: 200000
|
|
111
112
|
},
|
|
113
|
+
// Single Image Analysis Tool
|
|
114
|
+
{
|
|
115
|
+
name: 'mcp_openrouter_analyze_image',
|
|
116
|
+
description: 'Analyze an image using OpenRouter vision models',
|
|
117
|
+
inputSchema: {
|
|
118
|
+
type: 'object',
|
|
119
|
+
properties: {
|
|
120
|
+
image_path: {
|
|
121
|
+
type: 'string',
|
|
122
|
+
description: 'Path to the image file to analyze (must be an absolute path)',
|
|
123
|
+
},
|
|
124
|
+
question: {
|
|
125
|
+
type: 'string',
|
|
126
|
+
description: 'Question to ask about the image',
|
|
127
|
+
},
|
|
128
|
+
model: {
|
|
129
|
+
type: 'string',
|
|
130
|
+
description: 'OpenRouter model to use (e.g., "anthropic/claude-3.5-sonnet")',
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
required: ['image_path'],
|
|
134
|
+
},
|
|
135
|
+
},
|
|
112
136
|
// Multi-Image Analysis Tool
|
|
113
137
|
{
|
|
114
|
-
name: '
|
|
115
|
-
description: 'Analyze
|
|
138
|
+
name: 'mcp_openrouter_multi_image_analysis',
|
|
139
|
+
description: 'Analyze multiple images at once with a single prompt and receive detailed responses',
|
|
116
140
|
inputSchema: {
|
|
117
141
|
type: 'object',
|
|
118
142
|
properties: {
|
|
@@ -247,13 +271,19 @@ export class ToolHandlers {
|
|
|
247
271
|
}));
|
|
248
272
|
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
249
273
|
switch (request.params.name) {
|
|
250
|
-
case '
|
|
274
|
+
case 'mcp_openrouter_chat_completion':
|
|
251
275
|
return handleChatCompletion({
|
|
252
276
|
params: {
|
|
253
277
|
arguments: request.params.arguments
|
|
254
278
|
}
|
|
255
279
|
}, this.openai, this.defaultModel);
|
|
256
|
-
case '
|
|
280
|
+
case 'mcp_openrouter_analyze_image':
|
|
281
|
+
return handleAnalyzeImage({
|
|
282
|
+
params: {
|
|
283
|
+
arguments: request.params.arguments
|
|
284
|
+
}
|
|
285
|
+
}, this.openai, this.defaultModel);
|
|
286
|
+
case 'mcp_openrouter_multi_image_analysis':
|
|
257
287
|
return handleMultiImageAnalysis({
|
|
258
288
|
params: {
|
|
259
289
|
arguments: request.params.arguments
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-handlers.js","sourceRoot":"","sources":["../src/tool-handlers.ts"],"names":[],"mappings":"AACA,OAAO,EACL,qBAAqB,EACrB,SAAS,EACT,sBAAsB,EACtB,QAAQ,GACT,MAAM,oCAAoC,CAAC;AAC5C,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D,uBAAuB;AACvB,OAAO,EAAE,oBAAoB,EAA6B,MAAM,oCAAoC,CAAC;AACrG,OAAO,EAAE,kBAAkB,EAA2B,MAAM,kCAAkC,CAAC;AAC/F,OAAO,EAAE,kBAAkB,EAA2B,MAAM,mCAAmC,CAAC;AAChG,OAAO,EAAE,mBAAmB,EAA4B,MAAM,mCAAmC,CAAC;AAClG,OAAO,EAAE,wBAAwB,EAAiC,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"tool-handlers.js","sourceRoot":"","sources":["../src/tool-handlers.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stabgan/openrouter-mcp-multimodal",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "MCP server for OpenRouter providing text chat and image analysis tools",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -42,9 +42,10 @@
|
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@modelcontextprotocol/sdk": "^1.4.1",
|
|
45
|
-
"axios": "^1.
|
|
45
|
+
"axios": "^1.8.4",
|
|
46
|
+
"dotenv": "^16.4.7",
|
|
46
47
|
"node-fetch": "^3.3.2",
|
|
47
|
-
"openai": "^4.
|
|
48
|
+
"openai": "^4.89.1",
|
|
48
49
|
"sharp": "^0.33.3"
|
|
49
50
|
},
|
|
50
51
|
"devDependencies": {
|
|
@@ -57,4 +58,4 @@
|
|
|
57
58
|
"uri-js": "npm:uri-js-replace",
|
|
58
59
|
"whatwg-url": "^14.1.0"
|
|
59
60
|
}
|
|
60
|
-
}
|
|
61
|
+
}
|