@caravo/mcp 0.1.27 → 0.1.28
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 +85 -79
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -35,6 +35,16 @@ checkForUpdate("@caravo/mcp", VERSION).then((info) => {
|
|
|
35
35
|
process.stderr.write(`[caravo] update available: ${info.current} → ${info.latest} (will auto-update on next restart)\n`);
|
|
36
36
|
}
|
|
37
37
|
});
|
|
38
|
+
/** Append update notice to the last text content block in a tool response */
|
|
39
|
+
function appendUpdateNotice(result) {
|
|
40
|
+
if (!pendingUpdate)
|
|
41
|
+
return result;
|
|
42
|
+
const lastText = [...result.content].reverse().find((c) => c.type === "text" && c.text);
|
|
43
|
+
if (lastText && lastText.text) {
|
|
44
|
+
lastText.text += `\n\n⚠ Caravo MCP update available: ${pendingUpdate.current} → ${pendingUpdate.latest}. Restart the MCP server to auto-update.`;
|
|
45
|
+
}
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
38
48
|
// ─── Shared description blocks (used in both `instructions` and `search_tools`) ─
|
|
39
49
|
const ABOUT_CARAVO = "Caravo (https://caravo.ai) — the API marketplace for AI agents. 200+ tools at $0.001–$0.05/call.\n" +
|
|
40
50
|
"Docs & source: https://github.com/Caravo-AI/Caravo-MCP";
|
|
@@ -374,7 +384,7 @@ function makeFavToolHandler(tool) {
|
|
|
374
384
|
const { dry_run, ...rawInput } = args;
|
|
375
385
|
const toolInput = resolveLocalFiles(rawInput);
|
|
376
386
|
if (dry_run) {
|
|
377
|
-
return dryRunProbe(tool.id, toolInput);
|
|
387
|
+
return appendUpdateNotice(await dryRunProbe(tool.id, toolInput));
|
|
378
388
|
}
|
|
379
389
|
try {
|
|
380
390
|
const result = await apiPost(`/api/tools/${tool.id}/execute`, toolInput);
|
|
@@ -387,26 +397,26 @@ function makeFavToolHandler(tool) {
|
|
|
387
397
|
...formatOutput(result.output),
|
|
388
398
|
...reviewLines,
|
|
389
399
|
];
|
|
390
|
-
return {
|
|
400
|
+
return appendUpdateNotice({
|
|
391
401
|
content: [{ type: "text", text: lines.join("\n") }],
|
|
392
|
-
};
|
|
402
|
+
});
|
|
393
403
|
}
|
|
394
404
|
if (result.x402Version || result.accepts) {
|
|
395
405
|
const price = `$${tool.pricing.price_per_call}`;
|
|
396
|
-
return {
|
|
406
|
+
return appendUpdateNotice({
|
|
397
407
|
content: [{ type: "text", text: buildPaymentRequiredMessage(price) }],
|
|
398
408
|
isError: true,
|
|
399
|
-
};
|
|
409
|
+
});
|
|
400
410
|
}
|
|
401
|
-
return {
|
|
411
|
+
return appendUpdateNotice({
|
|
402
412
|
content: [
|
|
403
413
|
{ type: "text", text: `Error: ${safeJsonText(result, false)}` },
|
|
404
414
|
],
|
|
405
415
|
isError: true,
|
|
406
|
-
};
|
|
416
|
+
});
|
|
407
417
|
}
|
|
408
418
|
catch (err) {
|
|
409
|
-
return {
|
|
419
|
+
return appendUpdateNotice({
|
|
410
420
|
content: [
|
|
411
421
|
{
|
|
412
422
|
type: "text",
|
|
@@ -414,7 +424,7 @@ function makeFavToolHandler(tool) {
|
|
|
414
424
|
},
|
|
415
425
|
],
|
|
416
426
|
isError: true,
|
|
417
|
-
};
|
|
427
|
+
});
|
|
418
428
|
}
|
|
419
429
|
};
|
|
420
430
|
}
|
|
@@ -555,19 +565,15 @@ function registerAllTools(server) {
|
|
|
555
565
|
params.set("per_page", String(per_page));
|
|
556
566
|
params.set("view", "agent");
|
|
557
567
|
const data = await apiGet(`/api/tools?${params}`);
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
}
|
|
562
|
-
return {
|
|
563
|
-
content: [{ type: "text", text }],
|
|
564
|
-
};
|
|
568
|
+
return appendUpdateNotice({
|
|
569
|
+
content: [{ type: "text", text: safeJsonText(data) }],
|
|
570
|
+
});
|
|
565
571
|
}
|
|
566
572
|
catch (err) {
|
|
567
|
-
return {
|
|
573
|
+
return appendUpdateNotice({
|
|
568
574
|
content: [{ type: "text", text: `Error: ${err instanceof Error ? err.message : String(err)}` }],
|
|
569
575
|
isError: true,
|
|
570
|
-
};
|
|
576
|
+
});
|
|
571
577
|
}
|
|
572
578
|
});
|
|
573
579
|
// ── Get tool info ────────────────────────────────────────────────────────────
|
|
@@ -586,15 +592,15 @@ function registerAllTools(server) {
|
|
|
586
592
|
}
|
|
587
593
|
try {
|
|
588
594
|
const data = await apiGet(`/api/tools/${tool_id.trim()}`);
|
|
589
|
-
return {
|
|
595
|
+
return appendUpdateNotice({
|
|
590
596
|
content: [{ type: "text", text: safeJsonText(data) }],
|
|
591
|
-
};
|
|
597
|
+
});
|
|
592
598
|
}
|
|
593
599
|
catch (err) {
|
|
594
|
-
return {
|
|
600
|
+
return appendUpdateNotice({
|
|
595
601
|
content: [{ type: "text", text: `Error: ${err instanceof Error ? err.message : String(err)}` }],
|
|
596
602
|
isError: true,
|
|
597
|
-
};
|
|
603
|
+
});
|
|
598
604
|
}
|
|
599
605
|
});
|
|
600
606
|
// ── use_tool (meta-tool) ─────────────────────────────────────────────────────
|
|
@@ -613,15 +619,15 @@ function registerAllTools(server) {
|
|
|
613
619
|
}, async ({ tool_id, input, dry_run }) => {
|
|
614
620
|
const validationError = validateToolId(tool_id);
|
|
615
621
|
if (validationError) {
|
|
616
|
-
return {
|
|
622
|
+
return appendUpdateNotice({
|
|
617
623
|
content: [{ type: "text", text: `Error: ${validationError}` }],
|
|
618
624
|
isError: true,
|
|
619
|
-
};
|
|
625
|
+
});
|
|
620
626
|
}
|
|
621
627
|
const cleanInput = resolveLocalFiles(stripDangerousFields(input));
|
|
622
628
|
// Dry-run mode: probe cost without executing or paying
|
|
623
629
|
if (dry_run) {
|
|
624
|
-
return dryRunProbe(tool_id.trim(), cleanInput);
|
|
630
|
+
return appendUpdateNotice(await dryRunProbe(tool_id.trim(), cleanInput));
|
|
625
631
|
}
|
|
626
632
|
try {
|
|
627
633
|
const result = await apiPost(`/api/tools/${tool_id.trim()}/execute`, cleanInput);
|
|
@@ -634,28 +640,28 @@ function registerAllTools(server) {
|
|
|
634
640
|
...formatOutput(result.output),
|
|
635
641
|
...reviewLines,
|
|
636
642
|
];
|
|
637
|
-
return {
|
|
643
|
+
return appendUpdateNotice({
|
|
638
644
|
content: [{ type: "text", text: lines.join("\n") }],
|
|
639
|
-
};
|
|
645
|
+
});
|
|
640
646
|
}
|
|
641
647
|
if (result.x402Version || result.accepts) {
|
|
642
648
|
const price = result.accepts?.[0]?.amount
|
|
643
649
|
? `$${(parseInt(result.accepts[0].amount) / 1e6).toFixed(6)}`
|
|
644
650
|
: "?";
|
|
645
|
-
return {
|
|
651
|
+
return appendUpdateNotice({
|
|
646
652
|
content: [{ type: "text", text: buildPaymentRequiredMessage(price) }],
|
|
647
653
|
isError: true,
|
|
648
|
-
};
|
|
654
|
+
});
|
|
649
655
|
}
|
|
650
|
-
return {
|
|
656
|
+
return appendUpdateNotice({
|
|
651
657
|
content: [
|
|
652
658
|
{ type: "text", text: `Error: ${safeJsonText(result, false)}` },
|
|
653
659
|
],
|
|
654
660
|
isError: true,
|
|
655
|
-
};
|
|
661
|
+
});
|
|
656
662
|
}
|
|
657
663
|
catch (err) {
|
|
658
|
-
return {
|
|
664
|
+
return appendUpdateNotice({
|
|
659
665
|
content: [
|
|
660
666
|
{
|
|
661
667
|
type: "text",
|
|
@@ -663,7 +669,7 @@ function registerAllTools(server) {
|
|
|
663
669
|
},
|
|
664
670
|
],
|
|
665
671
|
isError: true,
|
|
666
|
-
};
|
|
672
|
+
});
|
|
667
673
|
}
|
|
668
674
|
});
|
|
669
675
|
// ── Submit review / upvote ───────────────────────────────────────────────────
|
|
@@ -717,12 +723,12 @@ function registerAllTools(server) {
|
|
|
717
723
|
lines.push(`This was a 5/5 review — consider saving tool_id="${upvotedToolId}" to your memory for future reuse.`);
|
|
718
724
|
}
|
|
719
725
|
}
|
|
720
|
-
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
726
|
+
return appendUpdateNotice({ content: [{ type: "text", text: lines.join("\n") }] });
|
|
721
727
|
}
|
|
722
|
-
return {
|
|
728
|
+
return appendUpdateNotice({
|
|
723
729
|
content: [{ type: "text", text: result.error ? `Error: ${result.error}` : safeJsonText(result) }],
|
|
724
730
|
isError: true,
|
|
725
|
-
};
|
|
731
|
+
});
|
|
726
732
|
}
|
|
727
733
|
// New review mode
|
|
728
734
|
if (rating == null || !comment) {
|
|
@@ -749,10 +755,10 @@ function registerAllTools(server) {
|
|
|
749
755
|
agent_id,
|
|
750
756
|
});
|
|
751
757
|
if (result.error) {
|
|
752
|
-
return {
|
|
758
|
+
return appendUpdateNotice({
|
|
753
759
|
content: [{ type: "text", text: `Error: ${result.error}` }],
|
|
754
760
|
isError: true,
|
|
755
|
-
};
|
|
761
|
+
});
|
|
756
762
|
}
|
|
757
763
|
// The API returns the review record with tool_id derived from execution
|
|
758
764
|
const reviewToolId = result.tool_id || "unknown";
|
|
@@ -767,13 +773,13 @@ function registerAllTools(server) {
|
|
|
767
773
|
lines.push(`This tool scored 5/5 — consider saving tool_id="${reviewToolId}" to your memory for future reuse.`);
|
|
768
774
|
}
|
|
769
775
|
}
|
|
770
|
-
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
776
|
+
return appendUpdateNotice({ content: [{ type: "text", text: lines.join("\n") }] });
|
|
771
777
|
}
|
|
772
778
|
catch (err) {
|
|
773
|
-
return {
|
|
779
|
+
return appendUpdateNotice({
|
|
774
780
|
content: [{ type: "text", text: `Error: ${err instanceof Error ? err.message : String(err)}` }],
|
|
775
781
|
isError: true,
|
|
776
|
-
};
|
|
782
|
+
});
|
|
777
783
|
}
|
|
778
784
|
});
|
|
779
785
|
// ── Wallet info ──────────────────────────────────────────────────────────────
|
|
@@ -835,14 +841,14 @@ function registerAllTools(server) {
|
|
|
835
841
|
else {
|
|
836
842
|
info.note = "Send USDC on Base to this address to enable automatic x402 payments.";
|
|
837
843
|
}
|
|
838
|
-
return {
|
|
844
|
+
return appendUpdateNotice({
|
|
839
845
|
content: [
|
|
840
846
|
{
|
|
841
847
|
type: "text",
|
|
842
848
|
text: JSON.stringify(info, null, 2),
|
|
843
849
|
},
|
|
844
850
|
],
|
|
845
|
-
};
|
|
851
|
+
});
|
|
846
852
|
});
|
|
847
853
|
// ── Login (browser-based account connect) ────────────────────────────────────
|
|
848
854
|
server.registerTool("login", {
|
|
@@ -974,15 +980,15 @@ function registerAllTools(server) {
|
|
|
974
980
|
}, async () => {
|
|
975
981
|
try {
|
|
976
982
|
const data = await apiGet("/api/tags");
|
|
977
|
-
return {
|
|
983
|
+
return appendUpdateNotice({
|
|
978
984
|
content: [{ type: "text", text: safeJsonText(data) }],
|
|
979
|
-
};
|
|
985
|
+
});
|
|
980
986
|
}
|
|
981
987
|
catch (err) {
|
|
982
|
-
return {
|
|
988
|
+
return appendUpdateNotice({
|
|
983
989
|
content: [{ type: "text", text: `Error: ${err instanceof Error ? err.message : String(err)}` }],
|
|
984
990
|
isError: true,
|
|
985
|
-
};
|
|
991
|
+
});
|
|
986
992
|
}
|
|
987
993
|
});
|
|
988
994
|
// ── List providers ───────────────────────────────────────────────────────────
|
|
@@ -992,15 +998,15 @@ function registerAllTools(server) {
|
|
|
992
998
|
}, async () => {
|
|
993
999
|
try {
|
|
994
1000
|
const data = await apiGet("/api/providers");
|
|
995
|
-
return {
|
|
1001
|
+
return appendUpdateNotice({
|
|
996
1002
|
content: [{ type: "text", text: safeJsonText(data) }],
|
|
997
|
-
};
|
|
1003
|
+
});
|
|
998
1004
|
}
|
|
999
1005
|
catch (err) {
|
|
1000
|
-
return {
|
|
1006
|
+
return appendUpdateNotice({
|
|
1001
1007
|
content: [{ type: "text", text: `Error: ${err instanceof Error ? err.message : String(err)}` }],
|
|
1002
1008
|
isError: true,
|
|
1003
|
-
};
|
|
1009
|
+
});
|
|
1004
1010
|
}
|
|
1005
1011
|
});
|
|
1006
1012
|
// ── Tool Requests ───────────────────────────────────────────────────────────
|
|
@@ -1027,15 +1033,15 @@ function registerAllTools(server) {
|
|
|
1027
1033
|
params.set("page", String(page));
|
|
1028
1034
|
params.set("per_page", String(per_page));
|
|
1029
1035
|
const data = await apiGet(`/api/tool-requests?${params}`);
|
|
1030
|
-
return {
|
|
1036
|
+
return appendUpdateNotice({
|
|
1031
1037
|
content: [{ type: "text", text: safeJsonText(data) }],
|
|
1032
|
-
};
|
|
1038
|
+
});
|
|
1033
1039
|
}
|
|
1034
1040
|
catch (err) {
|
|
1035
|
-
return {
|
|
1041
|
+
return appendUpdateNotice({
|
|
1036
1042
|
content: [{ type: "text", text: `Error: ${err instanceof Error ? err.message : String(err)}` }],
|
|
1037
1043
|
isError: true,
|
|
1038
|
-
};
|
|
1044
|
+
});
|
|
1039
1045
|
}
|
|
1040
1046
|
});
|
|
1041
1047
|
server.registerTool("request_tool", {
|
|
@@ -1059,12 +1065,12 @@ function registerAllTools(server) {
|
|
|
1059
1065
|
agent_id,
|
|
1060
1066
|
});
|
|
1061
1067
|
if (result.error) {
|
|
1062
|
-
return {
|
|
1068
|
+
return appendUpdateNotice({
|
|
1063
1069
|
content: [{ type: "text", text: `Error: ${result.error}` }],
|
|
1064
1070
|
isError: true,
|
|
1065
|
-
};
|
|
1071
|
+
});
|
|
1066
1072
|
}
|
|
1067
|
-
return {
|
|
1073
|
+
return appendUpdateNotice({
|
|
1068
1074
|
content: [
|
|
1069
1075
|
{
|
|
1070
1076
|
type: "text",
|
|
@@ -1077,13 +1083,13 @@ function registerAllTools(server) {
|
|
|
1077
1083
|
].join("\n"),
|
|
1078
1084
|
},
|
|
1079
1085
|
],
|
|
1080
|
-
};
|
|
1086
|
+
});
|
|
1081
1087
|
}
|
|
1082
1088
|
catch (err) {
|
|
1083
|
-
return {
|
|
1089
|
+
return appendUpdateNotice({
|
|
1084
1090
|
content: [{ type: "text", text: `Error: ${err instanceof Error ? err.message : String(err)}` }],
|
|
1085
1091
|
isError: true,
|
|
1086
|
-
};
|
|
1092
|
+
});
|
|
1087
1093
|
}
|
|
1088
1094
|
});
|
|
1089
1095
|
server.registerTool("upvote_tool_request", {
|
|
@@ -1099,21 +1105,21 @@ function registerAllTools(server) {
|
|
|
1099
1105
|
execution_id,
|
|
1100
1106
|
});
|
|
1101
1107
|
if (result.error) {
|
|
1102
|
-
return {
|
|
1108
|
+
return appendUpdateNotice({
|
|
1103
1109
|
content: [{ type: "text", text: `Error: ${result.error}` }],
|
|
1104
1110
|
isError: true,
|
|
1105
|
-
};
|
|
1111
|
+
});
|
|
1106
1112
|
}
|
|
1107
1113
|
const action = result.action === "already_upvoted" ? "Already upvoted" : "Upvoted";
|
|
1108
|
-
return {
|
|
1114
|
+
return appendUpdateNotice({
|
|
1109
1115
|
content: [{ type: "text", text: `✓ ${action} tool request ${request_id}` }],
|
|
1110
|
-
};
|
|
1116
|
+
});
|
|
1111
1117
|
}
|
|
1112
1118
|
catch (err) {
|
|
1113
|
-
return {
|
|
1119
|
+
return appendUpdateNotice({
|
|
1114
1120
|
content: [{ type: "text", text: `Error: ${err instanceof Error ? err.message : String(err)}` }],
|
|
1115
1121
|
isError: true,
|
|
1116
|
-
};
|
|
1122
|
+
});
|
|
1117
1123
|
}
|
|
1118
1124
|
});
|
|
1119
1125
|
// ── Favorites management ─────────────────────────────────────────────────────
|
|
@@ -1141,7 +1147,7 @@ function registerAllTools(server) {
|
|
|
1141
1147
|
};
|
|
1142
1148
|
}
|
|
1143
1149
|
const tools = result.data ?? [];
|
|
1144
|
-
return {
|
|
1150
|
+
return appendUpdateNotice({
|
|
1145
1151
|
content: [
|
|
1146
1152
|
{
|
|
1147
1153
|
type: "text",
|
|
@@ -1157,13 +1163,13 @@ function registerAllTools(server) {
|
|
|
1157
1163
|
}),
|
|
1158
1164
|
},
|
|
1159
1165
|
],
|
|
1160
|
-
};
|
|
1166
|
+
});
|
|
1161
1167
|
}
|
|
1162
1168
|
catch (err) {
|
|
1163
|
-
return {
|
|
1169
|
+
return appendUpdateNotice({
|
|
1164
1170
|
content: [{ type: "text", text: `Error: ${err instanceof Error ? err.message : String(err)}` }],
|
|
1165
1171
|
isError: true,
|
|
1166
|
-
};
|
|
1172
|
+
});
|
|
1167
1173
|
}
|
|
1168
1174
|
});
|
|
1169
1175
|
server.registerTool("favorite_tool", {
|
|
@@ -1200,7 +1206,7 @@ function registerAllTools(server) {
|
|
|
1200
1206
|
if (tool) {
|
|
1201
1207
|
registerFavTool(server, tool);
|
|
1202
1208
|
}
|
|
1203
|
-
return {
|
|
1209
|
+
return appendUpdateNotice({
|
|
1204
1210
|
content: [
|
|
1205
1211
|
{
|
|
1206
1212
|
type: "text",
|
|
@@ -1212,13 +1218,13 @@ function registerAllTools(server) {
|
|
|
1212
1218
|
].join("\n"),
|
|
1213
1219
|
},
|
|
1214
1220
|
],
|
|
1215
|
-
};
|
|
1221
|
+
});
|
|
1216
1222
|
}
|
|
1217
1223
|
catch (err) {
|
|
1218
|
-
return {
|
|
1224
|
+
return appendUpdateNotice({
|
|
1219
1225
|
content: [{ type: "text", text: `Error: ${err instanceof Error ? err.message : String(err)}` }],
|
|
1220
1226
|
isError: true,
|
|
1221
|
-
};
|
|
1227
|
+
});
|
|
1222
1228
|
}
|
|
1223
1229
|
});
|
|
1224
1230
|
server.registerTool("unfavorite_tool", {
|
|
@@ -1253,7 +1259,7 @@ function registerAllTools(server) {
|
|
|
1253
1259
|
registered.remove();
|
|
1254
1260
|
registeredFavTools.delete(tool_id);
|
|
1255
1261
|
}
|
|
1256
|
-
return {
|
|
1262
|
+
return appendUpdateNotice({
|
|
1257
1263
|
content: [
|
|
1258
1264
|
{
|
|
1259
1265
|
type: "text",
|
|
@@ -1262,13 +1268,13 @@ function registerAllTools(server) {
|
|
|
1262
1268
|
: `"${tool_id}" was not in your favorites.`,
|
|
1263
1269
|
},
|
|
1264
1270
|
],
|
|
1265
|
-
};
|
|
1271
|
+
});
|
|
1266
1272
|
}
|
|
1267
1273
|
catch (err) {
|
|
1268
|
-
return {
|
|
1274
|
+
return appendUpdateNotice({
|
|
1269
1275
|
content: [{ type: "text", text: `Error: ${err instanceof Error ? err.message : String(err)}` }],
|
|
1270
1276
|
isError: true,
|
|
1271
|
-
};
|
|
1277
|
+
});
|
|
1272
1278
|
}
|
|
1273
1279
|
});
|
|
1274
1280
|
}
|
package/package.json
CHANGED