diff --git a/.changeset/retire-serve-preview.md b/.changeset/retire-serve-preview.md new file mode 100644 index 00000000..fac4048b --- /dev/null +++ b/.changeset/retire-serve-preview.md @@ -0,0 +1,5 @@ +--- +'@transloadit/mcp-server': patch +--- + +Stop recommending the retired `builtin/serve-preview` Template for URL inputs. diff --git a/packages/mcp-server/src/server.ts b/packages/mcp-server/src/server.ts index 32140b70..bd29e5af 100644 --- a/packages/mcp-server/src/server.ts +++ b/packages/mcp-server/src/server.ts @@ -746,7 +746,7 @@ export const createTransloaditMcpServer = ( warnings.push({ code: 'mcp_url_inputs_ignored', message: 'URL inputs were ignored because the template does not require input files.', - hint: 'If you meant to process a URL, use a template that imports URLs (e.g. builtin/serve-preview@0.0.1), or call transloadit_list_templates with include_builtin: "exclusively-latest" to discover builtins.', + hint: 'If you meant to process a URL, add an /http/import step or choose a workspace template that contains one. Call transloadit_list_templates to discover available templates.', path: templatePathHint ?? 'instructions', }) } else if (analysis.hasHttpImport) { diff --git a/packages/mcp-server/test/e2e/template-inputs.test.ts b/packages/mcp-server/test/e2e/template-inputs.test.ts index 7d46f53a..924957c3 100644 --- a/packages/mcp-server/test/e2e/template-inputs.test.ts +++ b/packages/mcp-server/test/e2e/template-inputs.test.ts @@ -183,8 +183,9 @@ maybeDescribe('mcp-server template URL handling', { timeout: 60000 }, () => { const warnings = Array.isArray(payload.warnings) ? payload.warnings : [] const ignored = warnings.find((warning) => warning.code === 'mcp_url_inputs_ignored') expect(ignored).toBeDefined() - expect(typeof ignored?.hint).toBe('string') - expect(String(ignored?.hint)).toContain('transloadit_list_templates') + expect(ignored?.hint).toBe( + 'If you meant to process a URL, add an /http/import step or choose a workspace template that contains one. Call transloadit_list_templates to discover available templates.', + ) }) it('errors when required fields are missing', async () => { diff --git a/packages/node/test/e2e/cli/assemblies-create.test.ts b/packages/node/test/e2e/cli/assemblies-create.test.ts index 1251652b..9343bc85 100644 --- a/packages/node/test/e2e/cli/assemblies-create.test.ts +++ b/packages/node/test/e2e/cli/assemblies-create.test.ts @@ -313,33 +313,51 @@ describeLive('assemblies', { retry: 1 }, () => { ) it( - 'should allow output directory for no-input templates (downloads into directory)', + 'should allow output directory for no-input workspace templates', testCase(async (client) => { await fsp.mkdir('out') - const output = new OutputCtl() - await assembliesCreate(output, client, { - template: 'builtin/serve-preview@0.0.1', - fields: { - input: genericImg, - w: '256', - h: '256', - f: 'png', + const template = await client.createTemplate({ + name: `node-sdk-no-input-${crypto.randomUUID()}`, + template: { + steps: { + import: { + robot: '/http/import', + url: genericImg, + }, + resize: { + robot: '/image/resize', + use: 'import', + result: true, + width: 256, + height: 256, + format: 'png', + }, + }, }, - inputs: [], - output: 'out', }) - const files = await rreaddirAsync('out') - expect(files.length).to.be.greaterThan(0) - - // Ensure at least one output file is a valid image. - const first = files[0] - expect(first).to.be.a('string') - const buf = await fsp.readFile(first) - const dim = imageSize(new Uint8Array(buf)) - expect(dim.width).to.be.greaterThan(0) - expect(dim.height).to.be.greaterThan(0) + try { + const output = new OutputCtl() + await assembliesCreate(output, client, { + template: template.id, + inputs: [], + output: 'out', + }) + + const files = await rreaddirAsync('out') + expect(files.length).to.be.greaterThan(0) + + // Ensure at least one output file is a valid image. + const first = files[0] + expect(first).to.be.a('string') + const buf = await fsp.readFile(first) + const dim = imageSize(new Uint8Array(buf)) + expect(dim.width).to.be.greaterThan(0) + expect(dim.height).to.be.greaterThan(0) + } finally { + await client.deleteTemplate(template.id) + } }), 180_000, ) diff --git a/packages/node/test/unit/cli/templates-list.test.ts b/packages/node/test/unit/cli/templates-list.test.ts index d6aaca1b..8e934ed8 100644 --- a/packages/node/test/unit/cli/templates-list.test.ts +++ b/packages/node/test/unit/cli/templates-list.test.ts @@ -26,8 +26,8 @@ describe('cli templates list', () => { .mockResolvedValueOnce({ items: [ { - id: 'builtin/serve-preview@0.0.1', - name: 'Serve preview', + id: 'builtin/encode-hls-video@0.0.1', + name: 'Encode HLS video', // minimal shape for CLI printing content: {}, require_signature_auth: 0, @@ -57,8 +57,8 @@ describe('cli templates list', () => { .mockResolvedValueOnce({ items: [ { - id: 'builtin/serve-preview@0.0.1', - name: 'Serve preview', + id: 'builtin/encode-hls-video@0.0.1', + name: 'Encode HLS video', content: {}, require_signature_auth: 0, }, @@ -70,8 +70,8 @@ describe('cli templates list', () => { const getSpy = vi.spyOn(Transloadit.prototype, 'getTemplate').mockResolvedValue({ ok: 'ok', message: 'OK', - id: 'builtin/serve-preview@0.0.1', - name: 'Serve preview', + id: 'builtin/encode-hls-video@0.0.1', + name: 'Encode HLS video', require_signature_auth: 0, content: { steps: { @@ -86,7 +86,7 @@ describe('cli templates list', () => { await main(['templates', 'list', '--include-content', '--include-builtin', 'latest']) expect(process.exitCode).toBeUndefined() - expect(getSpy).toHaveBeenCalledWith('builtin/serve-preview@0.0.1') + expect(getSpy).toHaveBeenCalledWith('builtin/encode-hls-video@0.0.1') }) it('fails with an invalid --include-builtin value', async () => {