From 1fb60a5677db5340f77c03b140e9266545f0bbed Mon Sep 17 00:00:00 2001 From: Olivier Chafik Date: Wed, 8 Oct 2025 18:54:23 +0100 Subject: [PATCH] Add outputType to zip tool: (inlined /) resource link / resource --- src/everything/everything.ts | 70 +++++++++++++++++++++++++++++------- 1 file changed, 58 insertions(+), 12 deletions(-) diff --git a/src/everything/everything.ts b/src/everything/everything.ts index 5086364d..bb7f5cd9 100644 --- a/src/everything/everything.ts +++ b/src/everything/everything.ts @@ -132,6 +132,11 @@ const StructuredContentSchema = { const ZipResourcesInputSchema = z.object({ files: z.record(z.string().url().describe("URL of the file to include in the zip")).describe("Mapping of file names to URLs to include in the zip"), + outputType: z.enum([ + 'resourceLink', + 'inlinedResourceLink', + 'resource' + ]).default('inlinedResourceLink').describe("How the resulting zip file should be returned. 'resourceLink' returns a linked to a resource that can be read later, 'inlinedResourceLink' returns a resource_link with a data URI, and 'resource' returns a full resource object."), }); enum ToolName { @@ -334,9 +339,17 @@ export const createServer = () => { }; }); + const transientResources = new Map(); + server.setRequestHandler(ReadResourceRequestSchema, async (request) => { const uri = request.params.uri; + if (transientResources.has(uri)) { + return { + contents: [transientResources.get(uri)!], + }; + } + if (uri.startsWith("test://static/resource/")) { const index = parseInt(uri.split("/").pop() ?? "", 10) - 1; if (index >= 0 && index < ALL_RESOURCES.length) { @@ -859,7 +872,7 @@ export const createServer = () => { } if (name === ToolName.ZIP_RESOURCES) { - const { files } = ZipResourcesInputSchema.parse(args); + const { files, outputType } = ZipResourcesInputSchema.parse(args); const zip = new JSZip(); @@ -876,17 +889,50 @@ export const createServer = () => { } } - const uri = `data:application/zip;base64,${await zip.generateAsync({ type: "base64" })}`; - - return { - content: [ - { - type: "resource_link", - mimeType: "application/zip", - uri, - }, - ], - }; + const blob = await zip.generateAsync({ type: "base64" }); + if (outputType === 'inlinedResourceLink') { + return { + content: [ + { + type: "resource_link", + mimeType: "application/zip", + uri: `data:application/zip;base64,${blob}`, + }, + ], + }; + } else { + const name = `out_${Date.now()}.zip`; + const uri = `resource://${name}`; + const resource = { + uri, + name, + mimeType: "application/zip", + blob, + }; + if (outputType === 'resource') { + return { + content: [ + { + type: "resource", + resource, + }, + ], + }; + } else if (outputType === 'resourceLink') { + transientResources.set(uri, resource); + return { + content: [ + { + type: "resource_link", + mimeType: "application/zip", + uri, + }, + ], + }; + } else { + throw new Error(`Unknown outputType: ${outputType}`); + } + } } if (name === ToolName.LIST_ROOTS) {