create-multicast 0.4.3 → 0.4.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-multicast",
3
- "version": "0.4.3",
3
+ "version": "0.4.4",
4
4
  "description": "Create a Multicast MCP gateway — one command to scaffold, configure, and deploy your parallel MCP server.",
5
5
  "type": "module",
6
6
  "bin": "./dist/cli.js",
@@ -919,66 +919,118 @@ Clears the cache and re-fetches tools/list from every registered server.`,
919
919
 
920
920
  this.server.tool(
921
921
  "fetch_result",
922
- `Retrieve the full output of a large result that was stored by reference.
923
- When multicast returns an output_ref instead of inline output, call this
924
- tool with the ref ID to get the complete data. Results expire after 1 hour.`,
922
+ `Retrieve the full output of large results stored by reference.
923
+ When multicast returns output_ref instead of inline output, call this tool
924
+ to get the complete data. Accepts a SINGLE ref or MULTIPLE refs at once.
925
+ Always pass ALL refs in one call — don't call this tool multiple times.
926
+ Results expire after 1 hour.
927
+
928
+ Example (single): { "ref": "ref_abc123" }
929
+ Example (batch): { "refs": ["ref_abc123", "ref_def456"] }`,
925
930
  {
926
931
  ref: z
927
932
  .string()
928
- .describe("The output_ref ID from a multicast result (e.g., ref_abc123def456)"),
933
+ .optional()
934
+ .describe("Single output_ref ID (use this OR refs, not both)"),
935
+ refs: z
936
+ .array(z.string())
937
+ .optional()
938
+ .describe("Multiple output_ref IDs to fetch at once (use this OR ref, not both)"),
929
939
  },
930
- async ({ ref }) => {
940
+ async ({ ref, refs }) => {
931
941
  const db = this.env.DB;
932
942
 
933
- const row = await db
934
- .prepare(
935
- "SELECT server_name, tool_name, output, created_at FROM result_cache WHERE ref_id = ?"
936
- )
937
- .bind(ref)
938
- .first<{
939
- server_name: string;
940
- tool_name: string;
941
- output: string;
942
- created_at: string;
943
- }>();
944
-
945
- if (!row) {
943
+ // Normalize: single ref or batch refs into one array
944
+ const refIds: string[] = [];
945
+ if (refs && refs.length > 0) {
946
+ refIds.push(...refs);
947
+ } else if (ref) {
948
+ refIds.push(ref);
949
+ } else {
946
950
  return {
947
- content: [
948
- {
949
- type: "text" as const,
950
- text: JSON.stringify({
951
- error: `Result not found for ref "${ref}". It may have expired (results are kept for 1 hour).`,
952
- }),
953
- },
954
- ],
951
+ content: [{
952
+ type: "text" as const,
953
+ text: JSON.stringify({ error: "Provide either 'ref' (single) or 'refs' (array)." }),
954
+ }],
955
955
  };
956
956
  }
957
957
 
958
- // Parse the stored output back
959
- let parsedOutput: unknown;
960
- try {
961
- parsedOutput = JSON.parse(row.output);
962
- } catch {
963
- parsedOutput = row.output;
958
+ // Fetch all refs in one D1 batch
959
+ const results: Array<{
960
+ ref_id: string;
961
+ server: string;
962
+ tool: string;
963
+ output: unknown;
964
+ cached_at: string;
965
+ error?: string;
966
+ }> = [];
967
+
968
+ for (const refId of refIds) {
969
+ const row = await db
970
+ .prepare(
971
+ "SELECT server_name, tool_name, output, created_at FROM result_cache WHERE ref_id = ?"
972
+ )
973
+ .bind(refId)
974
+ .first<{
975
+ server_name: string;
976
+ tool_name: string;
977
+ output: string;
978
+ created_at: string;
979
+ }>();
980
+
981
+ if (!row) {
982
+ results.push({
983
+ ref_id: refId,
984
+ server: "unknown",
985
+ tool: "unknown",
986
+ output: null,
987
+ cached_at: "",
988
+ error: `Not found — may have expired (1 hour TTL).`,
989
+ });
990
+ continue;
991
+ }
992
+
993
+ let parsedOutput: unknown;
994
+ try {
995
+ parsedOutput = JSON.parse(row.output);
996
+ } catch {
997
+ parsedOutput = row.output;
998
+ }
999
+
1000
+ results.push({
1001
+ ref_id: refId,
1002
+ server: row.server_name,
1003
+ tool: row.tool_name,
1004
+ output: parsedOutput,
1005
+ cached_at: row.created_at,
1006
+ });
1007
+ }
1008
+
1009
+ // Single ref: return flat (backwards compatible)
1010
+ if (refIds.length === 1 && results.length === 1 && !results[0].error) {
1011
+ return {
1012
+ content: [{
1013
+ type: "text" as const,
1014
+ text: JSON.stringify({
1015
+ server: results[0].server,
1016
+ tool: results[0].tool,
1017
+ output: results[0].output,
1018
+ cached_at: results[0].cached_at,
1019
+ }, null, 2),
1020
+ }],
1021
+ };
964
1022
  }
965
1023
 
1024
+ // Batch: return array of results
966
1025
  return {
967
- content: [
968
- {
969
- type: "text" as const,
970
- text: JSON.stringify(
971
- {
972
- server: row.server_name,
973
- tool: row.tool_name,
974
- output: parsedOutput,
975
- cached_at: row.created_at,
976
- },
977
- null,
978
- 2
979
- ),
980
- },
981
- ],
1026
+ content: [{
1027
+ type: "text" as const,
1028
+ text: JSON.stringify({
1029
+ results,
1030
+ fetched: results.filter((r) => !r.error).length,
1031
+ errors: results.filter((r) => r.error).length,
1032
+ }, null, 2),
1033
+ }],
982
1034
  };
983
1035
  }
984
1036
  );