From 1fb60a5677db5340f77c03b140e9266545f0bbed Mon Sep 17 00:00:00 2001 From: Olivier Chafik Date: Wed, 8 Oct 2025 18:54:23 +0100 Subject: [PATCH 1/8] 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 5086364dd..bb7f5cd99 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) { From e1d2f40f95b54c666d21a81de1d41eef1472ab04 Mon Sep 17 00:00:00 2001 From: Olivier Chafik Date: Wed, 8 Oct 2025 19:03:25 +0100 Subject: [PATCH 2/8] Update everything.ts --- src/everything/everything.ts | 38 ++++++------------------------------ 1 file changed, 6 insertions(+), 32 deletions(-) diff --git a/src/everything/everything.ts b/src/everything/everything.ts index bb7f5cd99..a33c25acb 100644 --- a/src/everything/everything.ts +++ b/src/everything/everything.ts @@ -890,45 +890,19 @@ export const createServer = () => { } const blob = await zip.generateAsync({ type: "base64" }); + const mimeType = "application/zip"; if (outputType === 'inlinedResourceLink') { - return { - content: [ - { - type: "resource_link", - mimeType: "application/zip", - uri: `data:application/zip;base64,${blob}`, - }, - ], - }; + const uri = `data:${mimeType};base64,${blob}`; + return {content: [{type: "resource_link", mimeType, uri}]}; } else { const name = `out_${Date.now()}.zip`; const uri = `resource://${name}`; - const resource = { - uri, - name, - mimeType: "application/zip", - blob, - }; + const resource = {uri, name, mimeType, blob}; if (outputType === 'resource') { - return { - content: [ - { - type: "resource", - resource, - }, - ], - }; + return {content: [{ type: "resource", resource}]}; } else if (outputType === 'resourceLink') { transientResources.set(uri, resource); - return { - content: [ - { - type: "resource_link", - mimeType: "application/zip", - uri, - }, - ], - }; + return {content: [{ type: "resource_link", mimeType, uri }]}; } else { throw new Error(`Unknown outputType: ${outputType}`); } From 893ee9c5b7d34e8cd7d6197e5305ef80297e89a8 Mon Sep 17 00:00:00 2001 From: Olivier Chafik Date: Wed, 8 Oct 2025 19:05:28 +0100 Subject: [PATCH 3/8] Update everything.ts --- src/everything/everything.ts | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/everything/everything.ts b/src/everything/everything.ts index a33c25acb..90d16a67c 100644 --- a/src/everything/everything.ts +++ b/src/everything/everything.ts @@ -893,16 +893,33 @@ export const createServer = () => { const mimeType = "application/zip"; if (outputType === 'inlinedResourceLink') { const uri = `data:${mimeType};base64,${blob}`; - return {content: [{type: "resource_link", mimeType, uri}]}; + return { + content: [{ + type: "resource_link", + mimeType, + uri + }] + }; } else { const name = `out_${Date.now()}.zip`; const uri = `resource://${name}`; const resource = {uri, name, mimeType, blob}; if (outputType === 'resource') { - return {content: [{ type: "resource", resource}]}; + return { + content: [{ + type: "resource", + resource + }] + }; } else if (outputType === 'resourceLink') { transientResources.set(uri, resource); - return {content: [{ type: "resource_link", mimeType, uri }]}; + return { + content: [{ + type: "resource_link", + mimeType, + uri + }] + }; } else { throw new Error(`Unknown outputType: ${outputType}`); } From bd496fe7d850a8dfd07f8d268950a4a579d8918d Mon Sep 17 00:00:00 2001 From: Olivier Chafik Date: Thu, 9 Oct 2025 16:07:38 +0100 Subject: [PATCH 4/8] remove inlinedResourceLink --- src/everything/everything.ts | 40 +++++++++++++----------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/src/everything/everything.ts b/src/everything/everything.ts index 90d16a67c..143159ac3 100644 --- a/src/everything/everything.ts +++ b/src/everything/everything.ts @@ -134,9 +134,8 @@ 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."), + ]).default('resource').describe("How the resulting zip file should be returned. 'resourceLink' returns a linked to a resource that can be read later, 'resource' returns a full resource object."), }); enum ToolName { @@ -891,8 +890,18 @@ export const createServer = () => { const blob = await zip.generateAsync({ type: "base64" }); const mimeType = "application/zip"; - if (outputType === 'inlinedResourceLink') { - const uri = `data:${mimeType};base64,${blob}`; + const name = `out_${Date.now()}.zip`; + const uri = `resource://${name}`; + const resource = {uri, name, mimeType, blob}; + if (outputType === 'resource') { + return { + content: [{ + type: "resource", + resource + }] + }; + } else if (outputType === 'resourceLink') { + transientResources.set(uri, resource); return { content: [{ type: "resource_link", @@ -901,28 +910,7 @@ export const createServer = () => { }] }; } else { - const name = `out_${Date.now()}.zip`; - const uri = `resource://${name}`; - const resource = {uri, name, mimeType, blob}; - if (outputType === 'resource') { - return { - content: [{ - type: "resource", - resource - }] - }; - } else if (outputType === 'resourceLink') { - transientResources.set(uri, resource); - return { - content: [{ - type: "resource_link", - mimeType, - uri - }] - }; - } else { - throw new Error(`Unknown outputType: ${outputType}`); - } + throw new Error(`Unknown outputType: ${outputType}`); } } From ee5f8031350a2b17c23d0070b5fb542c0fae7930 Mon Sep 17 00:00:00 2001 From: Olivier Chafik Date: Thu, 9 Oct 2025 16:13:41 +0100 Subject: [PATCH 5/8] Update everything.ts --- src/everything/everything.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/everything/everything.ts b/src/everything/everything.ts index 143159ac3..c6a246472 100644 --- a/src/everything/everything.ts +++ b/src/everything/everything.ts @@ -872,7 +872,6 @@ export const createServer = () => { if (name === ToolName.ZIP_RESOURCES) { const { files, outputType } = ZipResourcesInputSchema.parse(args); - const zip = new JSZip(); for (const [fileName, fileUrl] of Object.entries(files)) { From 48d8afe4dac14cbe7fe13bb74b02eb277322d093 Mon Sep 17 00:00:00 2001 From: Olivier Chafik Date: Thu, 9 Oct 2025 16:14:55 +0100 Subject: [PATCH 6/8] Forcing an empty commit. From 12e313bf13d5082373a17fea17212561a420eccf Mon Sep 17 00:00:00 2001 From: Olivier Chafik Date: Thu, 9 Oct 2025 16:15:42 +0100 Subject: [PATCH 7/8] Forcing an empty commit. From f3c5e4f312dc16969e491a1877640212e8b87416 Mon Sep 17 00:00:00 2001 From: Cliff Hall Date: Fri, 10 Oct 2025 10:55:27 -0400 Subject: [PATCH 8/8] Apply suggestion from @cliffhall --- src/everything/everything.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/everything/everything.ts b/src/everything/everything.ts index c6a246472..ade7ef68d 100644 --- a/src/everything/everything.ts +++ b/src/everything/everything.ts @@ -135,7 +135,7 @@ const ZipResourcesInputSchema = z.object({ outputType: z.enum([ 'resourceLink', 'resource' - ]).default('resource').describe("How the resulting zip file should be returned. 'resourceLink' returns a linked to a resource that can be read later, 'resource' returns a full resource object."), + ]).default('resource').describe("How the resulting zip file should be returned. 'resourceLink' returns a link to a resource that can be read later, 'resource' returns a full resource object."), }); enum ToolName {