From cf921b73614db28527b4f2a3e23b1c6db4231fc7 Mon Sep 17 00:00:00 2001 From: Kevin van Zonneveld Date: Tue, 3 Feb 2026 20:28:00 +0100 Subject: [PATCH] Override Transloadit-Client header for MCP --- .changeset/mcp-client-header.md | 6 ++++++ packages/mcp-server/src/server.ts | 7 +++++++ packages/node/src/Transloadit.ts | 6 +++++- .../test/unit/test-transloadit-client.test.ts | 19 +++++++++++++++++++ 4 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 .changeset/mcp-client-header.md diff --git a/.changeset/mcp-client-header.md b/.changeset/mcp-client-header.md new file mode 100644 index 00000000..2d53e499 --- /dev/null +++ b/.changeset/mcp-client-header.md @@ -0,0 +1,6 @@ +--- +"@transloadit/node": patch +"@transloadit/mcp-server": patch +--- + +Allow overriding the Transloadit-Client header and set MCP server requests to its own client name. diff --git a/packages/mcp-server/src/server.ts b/packages/mcp-server/src/server.ts index c50bd8ad..1375ebd6 100644 --- a/packages/mcp-server/src/server.ts +++ b/packages/mcp-server/src/server.ts @@ -24,6 +24,7 @@ export type TransloaditMcpServerOptions = { endpoint?: string serverName?: string serverVersion?: string + clientName?: string } type LintIssueOutput = { @@ -278,11 +279,15 @@ const buildToolError = ( ], }) +const getClientName = (options: TransloaditMcpServerOptions): string => + options.clientName ?? `mcp-server:${packageJson.version}` + const createLintClient = (options: TransloaditMcpServerOptions): Transloadit => new Transloadit({ authKey: options.authKey ?? 'mcp', authSecret: options.authSecret ?? 'mcp', endpoint: options.endpoint, + clientName: getClientName(options), }) const getHeaderValue = (headers: HeaderMap | undefined, name: string): string | undefined => { @@ -315,6 +320,7 @@ const createLiveClient = ( authKey: options.authKey, authSecret: options.authSecret, endpoint: options.endpoint, + clientName: getClientName(options), }), } } @@ -333,6 +339,7 @@ const createLiveClient = ( authKey: options.authKey, authSecret: options.authSecret, endpoint: options.endpoint, + clientName: getClientName(options), }), } } diff --git a/packages/node/src/Transloadit.ts b/packages/node/src/Transloadit.ts index 60d8c385..14c5dbd0 100644 --- a/packages/node/src/Transloadit.ts +++ b/packages/node/src/Transloadit.ts @@ -322,6 +322,7 @@ type BaseOptions = { timeout?: number gotRetry?: Partial validateResponses?: boolean + clientName?: string } export type Options = BaseOptions & (AuthKeySecret | AuthToken) @@ -341,6 +342,8 @@ export class Transloadit { private _gotRetry: Partial + private _clientName: string + private _lastUsedAssemblyUrl = '' private _validateResponses = false @@ -369,6 +372,7 @@ export class Transloadit { this._endpoint = opts.endpoint || 'https://api2.transloadit.com' this._maxRetries = opts.maxRetries != null ? opts.maxRetries : 5 this._defaultTimeout = opts.timeout != null ? opts.timeout : 60000 + this._clientName = opts.clientName?.trim() || `node-sdk:${version}` // Passed on to got https://github.com/sindresorhus/got/blob/main/documentation/7-retry.md this._gotRetry = opts.gotRetry != null ? opts.gotRetry : { limit: 0 } @@ -1258,7 +1262,7 @@ export class Transloadit { body: form, timeout, headers: { - 'Transloadit-Client': `node-sdk:${version}`, + 'Transloadit-Client': this._clientName, 'User-Agent': undefined, // Remove got's user-agent ...(this._authToken ? { Authorization: `Bearer ${this._authToken}` } : {}), ...headers, diff --git a/packages/node/test/unit/test-transloadit-client.test.ts b/packages/node/test/unit/test-transloadit-client.test.ts index 1b5f83c2..2fc7066a 100644 --- a/packages/node/test/unit/test-transloadit-client.test.ts +++ b/packages/node/test/unit/test-transloadit-client.test.ts @@ -388,6 +388,25 @@ describe('Transloadit', () => { expect.objectContaining({ headers: { 'Transloadit-Client': `node-sdk:${version}` } }), ) }) + + it('should allow overriding the "Transloadit-Client" header', async () => { + const client = new Transloadit({ + authKey: 'foo_key', + authSecret: 'foo_secret', + clientName: 'mcp-server:1.2.3', + }) + + const get = mockGot('get') + + const url = '/some-url' + // @ts-expect-error This tests private internals + await client._remoteJson({ url, method: 'get', isTrustedUrl: true }) + + expect(get).toHaveBeenCalledWith( + expect.any(String), + expect.objectContaining({ headers: { 'Transloadit-Client': 'mcp-server:1.2.3' } }), + ) + }) }) describe('getSignedSmartCDNUrl', () => {