@caravo/mcp 0.1.26 → 0.1.27
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 +41 -6
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -246,6 +246,35 @@ function stripDangerousFields(input) {
|
|
|
246
246
|
}
|
|
247
247
|
return cleaned;
|
|
248
248
|
}
|
|
249
|
+
/**
|
|
250
|
+
* Resolve local file paths in tool input to base64.
|
|
251
|
+
* Detects file:// URIs and absolute paths with image extensions.
|
|
252
|
+
* Runs locally so base64 never enters the LLM context.
|
|
253
|
+
*/
|
|
254
|
+
function resolveLocalFiles(input) {
|
|
255
|
+
const result = { ...input };
|
|
256
|
+
for (const [key, value] of Object.entries(result)) {
|
|
257
|
+
if (typeof value !== "string")
|
|
258
|
+
continue;
|
|
259
|
+
const filePath = toLocalPath(value);
|
|
260
|
+
if (!filePath)
|
|
261
|
+
continue;
|
|
262
|
+
if (!existsSync(filePath)) {
|
|
263
|
+
throw new Error(`Local file not found: ${filePath}`);
|
|
264
|
+
}
|
|
265
|
+
result[key] = readFileSync(filePath).toString("base64");
|
|
266
|
+
}
|
|
267
|
+
return result;
|
|
268
|
+
}
|
|
269
|
+
function toLocalPath(value) {
|
|
270
|
+
if (value.startsWith("file:///"))
|
|
271
|
+
return value.slice(7);
|
|
272
|
+
if (value.startsWith("file://"))
|
|
273
|
+
return value.slice(7);
|
|
274
|
+
if (/^\//.test(value) && /\.(png|jpe?g|gif|webp|bmp|svg|tiff?)$/i.test(value))
|
|
275
|
+
return value;
|
|
276
|
+
return null;
|
|
277
|
+
}
|
|
249
278
|
// ─── Favorites registration ────────────────────────────────────────────────────
|
|
250
279
|
// Track registered fav tool handles for dynamic add/remove
|
|
251
280
|
const registeredFavTools = new Map();
|
|
@@ -342,7 +371,8 @@ function buildPostExecPrompt(execId, toolId) {
|
|
|
342
371
|
function makeFavToolHandler(tool) {
|
|
343
372
|
return async (args) => {
|
|
344
373
|
// Extract dry_run before passing remaining args to the API
|
|
345
|
-
const { dry_run, ...
|
|
374
|
+
const { dry_run, ...rawInput } = args;
|
|
375
|
+
const toolInput = resolveLocalFiles(rawInput);
|
|
346
376
|
if (dry_run) {
|
|
347
377
|
return dryRunProbe(tool.id, toolInput);
|
|
348
378
|
}
|
|
@@ -571,6 +601,7 @@ function registerAllTools(server) {
|
|
|
571
601
|
server.registerTool("use_tool", {
|
|
572
602
|
description: "Execute any marketplace tool by ID. Use get_tool_info first to see the required input schema. " +
|
|
573
603
|
"Paid tools auto-pay via x402 (wallet) or API key balance. " +
|
|
604
|
+
"File upload tip: For tools that accept file input, you can pass a local file path (e.g., /path/to/photo.jpg) or file:// URI — it will be auto-converted to base64. Prefer passing a URL when available. " +
|
|
574
605
|
"After using a tool, check existing reviews first — upvote one if it matches your experience, or write a new review if none captures your feedback.",
|
|
575
606
|
inputSchema: {
|
|
576
607
|
tool_id: z.string().describe("The tool ID or slug to execute (e.g., 'black-forest-labs/flux.1-schnell' or 'alice/imagen-4')"),
|
|
@@ -587,7 +618,7 @@ function registerAllTools(server) {
|
|
|
587
618
|
isError: true,
|
|
588
619
|
};
|
|
589
620
|
}
|
|
590
|
-
const cleanInput = stripDangerousFields(input);
|
|
621
|
+
const cleanInput = resolveLocalFiles(stripDangerousFields(input));
|
|
591
622
|
// Dry-run mode: probe cost without executing or paying
|
|
592
623
|
if (dry_run) {
|
|
593
624
|
return dryRunProbe(tool_id.trim(), cleanInput);
|
|
@@ -893,7 +924,9 @@ function registerAllTools(server) {
|
|
|
893
924
|
"Removes the saved API key and unregisters all favorited tools from this session.",
|
|
894
925
|
inputSchema: {},
|
|
895
926
|
}, async () => {
|
|
896
|
-
|
|
927
|
+
// Check both in-memory key and config file (key may have been set by CLI login after MCP started)
|
|
928
|
+
const configKey = loadConfig().api_key;
|
|
929
|
+
if (!API_KEY && !configKey) {
|
|
897
930
|
return {
|
|
898
931
|
content: [{ type: "text", text: "Not logged in — already using x402 wallet payments." }],
|
|
899
932
|
};
|
|
@@ -902,9 +935,11 @@ function registerAllTools(server) {
|
|
|
902
935
|
API_KEY = undefined;
|
|
903
936
|
// 2. Remove key from config file
|
|
904
937
|
try {
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
938
|
+
if (configKey) {
|
|
939
|
+
const config = loadConfig();
|
|
940
|
+
delete config.api_key;
|
|
941
|
+
saveConfig(config);
|
|
942
|
+
}
|
|
908
943
|
}
|
|
909
944
|
catch {
|
|
910
945
|
// config file may not exist — that's fine
|
package/package.json
CHANGED