From cf23bfe77a8c721eed2c003793c14d4ac4d4b345 Mon Sep 17 00:00:00 2001 From: Kevin van Zonneveld Date: Tue, 3 Feb 2026 19:28:27 +0100 Subject: [PATCH 1/5] Clean up MCP config after verification --- scripts/verify-mcp-clients.ts | 39 ++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/scripts/verify-mcp-clients.ts b/scripts/verify-mcp-clients.ts index 635beb42..e594ae3c 100644 --- a/scripts/verify-mcp-clients.ts +++ b/scripts/verify-mcp-clients.ts @@ -8,6 +8,7 @@ type CliCheck = { command: string add: () => void run: () => { ok: boolean; output: string } + cleanup?: () => void } const requiredEnv = ['TRANSLOADIT_KEY', 'TRANSLOADIT_SECRET'] @@ -105,6 +106,9 @@ const runClaude = (prompt: string, expectedTemplateId: string): CliCheck => ({ throw new Error(`claude mcp add failed: ${result.stderr || result.stdout}`) } }, + cleanup: () => { + runCommand('claude', ['mcp', 'remove', serverName]) + }, run: () => { const result = runCommand('claude', [ '-p', @@ -112,7 +116,7 @@ const runClaude = (prompt: string, expectedTemplateId: string): CliCheck => ({ '--output-format', 'json', '--allowedTools', - 'transloadit_list_templates', + `mcp__${serverName}`, '--permission-mode', 'acceptEdits', ]) @@ -144,6 +148,9 @@ const runCodex = (prompt: string, expectedTemplateId: string): CliCheck => ({ throw new Error(`codex mcp add failed: ${result.stderr || result.stdout}`) } }, + cleanup: () => { + runCommand('codex', ['mcp', 'remove', serverName]) + }, run: () => { const result = runCommand('codex', ['exec', '--full-auto', '--json', prompt]) const output = `${result.stdout}\n${result.stderr}` @@ -188,6 +195,30 @@ const ensureGeminiSettings = (): void => { writeFileSync(settingsPath, `${JSON.stringify(settings, null, 2)}\n`) } +const cleanupGeminiSettings = (): void => { + const cwd = process.cwd() + const settingsPath = join(homedir(), '.gemini', 'settings.json') + if (settingsPath.startsWith(`${cwd}/`)) { + return + } + if (!existsSync(settingsPath)) { + return + } + let settings: Record = {} + try { + settings = JSON.parse(readFileSync(settingsPath, 'utf8')) as Record + } catch { + return + } + const mcpServers = (settings.mcpServers as Record) ?? {} + if (!(serverName in mcpServers)) { + return + } + delete mcpServers[serverName] + settings.mcpServers = mcpServers + writeFileSync(settingsPath, `${JSON.stringify(settings, null, 2)}\n`) +} + const runGemini = (prompt: string, expectedTemplateId: string): CliCheck => ({ name: 'Gemini CLI', command: 'gemini', @@ -217,6 +248,10 @@ const runGemini = (prompt: string, expectedTemplateId: string): CliCheck => ({ return } }, + cleanup: () => { + runCommand('gemini', ['mcp', 'remove', serverName]) + cleanupGeminiSettings() + }, run: () => { const result = runCommand('gemini', [ '--prompt', @@ -261,6 +296,8 @@ const main = async (): Promise => { ok: false, output: error instanceof Error ? error.message : String(error), }) + } finally { + check.cleanup?.() } } From 13b411d2110937ee86112eb9ef61155ed8ee8022 Mon Sep 17 00:00:00 2001 From: Kevin van Zonneveld Date: Tue, 3 Feb 2026 19:41:23 +0100 Subject: [PATCH 2/5] Document MCP tool permissions for CLI clients --- packages/mcp-server/README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/mcp-server/README.md b/packages/mcp-server/README.md index b3829334..1379000a 100644 --- a/packages/mcp-server/README.md +++ b/packages/mcp-server/README.md @@ -32,6 +32,10 @@ claude mcp add --transport stdio transloadit \ -- npx -y @transloadit/mcp-server stdio ``` +For non-interactive runs (e.g. `claude -p`), Claude requires explicit permission for MCP tools. +Pass an allowlist like `--allowedTools mcp__transloadit__*` (or use a permissive +`--permission-mode`) to avoid a permission prompt. + Codex CLI: ```bash @@ -49,6 +53,9 @@ gemini mcp add --scope user transloadit npx -y @transloadit/mcp-server stdio \ --env TRANSLOADIT_SECRET=... ``` +Gemini CLI can auto-approve tool calls with `--approval-mode yolo`, so no +separate allowlist is required unless you want tighter restrictions. + Cursor (`~/.cursor/mcp.json`): ```json From cda44b897a010edc39aa30fc8c9c4d805c4eaa45 Mon Sep 17 00:00:00 2001 From: Kevin van Zonneveld Date: Tue, 3 Feb 2026 19:56:58 +0100 Subject: [PATCH 3/5] Document MCP allowlists for CLI clients --- packages/mcp-server/README.md | 38 +++++++++++++++++++++++++++----- scripts/verify-mcp-clients.ts | 41 +++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 5 deletions(-) diff --git a/packages/mcp-server/README.md b/packages/mcp-server/README.md index 1379000a..9b20278b 100644 --- a/packages/mcp-server/README.md +++ b/packages/mcp-server/README.md @@ -32,9 +32,13 @@ claude mcp add --transport stdio transloadit \ -- npx -y @transloadit/mcp-server stdio ``` -For non-interactive runs (e.g. `claude -p`), Claude requires explicit permission for MCP tools. -Pass an allowlist like `--allowedTools mcp__transloadit__*` (or use a permissive -`--permission-mode`) to avoid a permission prompt. +For non-interactive runs (e.g. `claude -p`), explicitly allow MCP tools: + +```bash +claude -p "List templates" \ + --allowedTools mcp__transloadit__* \ + --output-format json +``` Codex CLI: @@ -45,6 +49,15 @@ codex mcp add transloadit \ -- npx -y @transloadit/mcp-server stdio ``` +To allowlist tools, add `enabled_tools` for the server in `~/.codex/config.toml`: + +```toml +[mcp_servers.transloadit] +command = "npx" +args = ["-y", "@transloadit/mcp-server", "stdio"] +enabled_tools = ["transloadit_list_templates"] +``` + Gemini CLI: ```bash @@ -53,8 +66,23 @@ gemini mcp add --scope user transloadit npx -y @transloadit/mcp-server stdio \ --env TRANSLOADIT_SECRET=... ``` -Gemini CLI can auto-approve tool calls with `--approval-mode yolo`, so no -separate allowlist is required unless you want tighter restrictions. +To allowlist tools, set `includeTools` for the server in `~/.gemini/settings.json`: + +```json +{ + "mcpServers": { + "transloadit": { + "command": "npx", + "args": ["-y", "@transloadit/mcp-server", "stdio"], + "env": { + "TRANSLOADIT_KEY": "...", + "TRANSLOADIT_SECRET": "..." + }, + "includeTools": ["transloadit_list_templates"] + } + } +} +``` Cursor (`~/.cursor/mcp.json`): diff --git a/scripts/verify-mcp-clients.ts b/scripts/verify-mcp-clients.ts index e594ae3c..49fc9cdc 100644 --- a/scripts/verify-mcp-clients.ts +++ b/scripts/verify-mcp-clients.ts @@ -22,6 +22,7 @@ if (envMissing.length > 0) { const endpoint = process.env.TRANSLOADIT_ENDPOINT ?? 'https://api2.transloadit.com' const commandTimeoutMs = Number(process.env.MCP_VERIFY_TIMEOUT_MS ?? 60_000) const serverName = process.env.MCP_SERVER_NAME ?? 'transloadit' +const allowlistedTools = ['transloadit_list_templates'] const serverCommand = [ 'npm', 'exec', @@ -147,6 +148,7 @@ const runCodex = (prompt: string, expectedTemplateId: string): CliCheck => ({ if (result.status !== 0) { throw new Error(`codex mcp add failed: ${result.stderr || result.stdout}`) } + updateCodexEnabledTools() }, cleanup: () => { runCommand('codex', ['mcp', 'remove', serverName]) @@ -188,6 +190,7 @@ const ensureGeminiSettings = (): void => { TRANSLOADIT_SECRET: process.env.TRANSLOADIT_SECRET ?? '', TRANSLOADIT_ENDPOINT: endpoint, }, + includeTools: allowlistedTools, } settings.mcpServers = mcpServers @@ -219,6 +222,44 @@ const cleanupGeminiSettings = (): void => { writeFileSync(settingsPath, `${JSON.stringify(settings, null, 2)}\n`) } +const updateCodexEnabledTools = (): void => { + const configPath = join(homedir(), '.codex', 'config.toml') + if (!existsSync(configPath)) { + return + } + const content = readFileSync(configPath, 'utf8') + const header = `[mcp_servers.${serverName}]` + const lines = content.split('\n') + const headerIndex = lines.findIndex((line) => line.trim() === header) + if (headerIndex === -1) { + return + } + let endIndex = lines.length + for (let i = headerIndex + 1; i < lines.length; i += 1) { + if (lines[i].startsWith('[')) { + endIndex = i + break + } + } + + const enabledLine = `enabled_tools = [${allowlistedTools + .map((tool) => `"${tool}"`) + .join(', ')}]` + let replaced = false + for (let i = headerIndex + 1; i < endIndex; i += 1) { + if (lines[i].trim().startsWith('enabled_tools')) { + lines[i] = enabledLine + replaced = true + break + } + } + if (!replaced) { + lines.splice(headerIndex + 1, 0, enabledLine) + } + + writeFileSync(configPath, `${lines.join('\n')}\n`) +} + const runGemini = (prompt: string, expectedTemplateId: string): CliCheck => ({ name: 'Gemini CLI', command: 'gemini', From 22b5df5c5fbea09db76b647330997ed10b65231c Mon Sep 17 00:00:00 2001 From: Kevin van Zonneveld Date: Tue, 3 Feb 2026 20:07:51 +0100 Subject: [PATCH 4/5] Add changeset for MCP allowlist docs --- .changeset/mcp-allowlist-docs.md | 5 +++++ scripts/verify-mcp-clients.ts | 4 +--- 2 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 .changeset/mcp-allowlist-docs.md diff --git a/.changeset/mcp-allowlist-docs.md b/.changeset/mcp-allowlist-docs.md new file mode 100644 index 00000000..192df915 --- /dev/null +++ b/.changeset/mcp-allowlist-docs.md @@ -0,0 +1,5 @@ +--- +"@transloadit/mcp-server": patch +--- + +Document MCP client tool allowlists and keep verification tooling aligned. diff --git a/scripts/verify-mcp-clients.ts b/scripts/verify-mcp-clients.ts index 49fc9cdc..7f0c7ea1 100644 --- a/scripts/verify-mcp-clients.ts +++ b/scripts/verify-mcp-clients.ts @@ -242,9 +242,7 @@ const updateCodexEnabledTools = (): void => { } } - const enabledLine = `enabled_tools = [${allowlistedTools - .map((tool) => `"${tool}"`) - .join(', ')}]` + const enabledLine = `enabled_tools = [${allowlistedTools.map((tool) => `"${tool}"`).join(', ')}]` let replaced = false for (let i = headerIndex + 1; i < endIndex; i += 1) { if (lines[i].trim().startsWith('enabled_tools')) { From 0bc6f4edecd14df012ce1ccdb6180670d15b7f3b Mon Sep 17 00:00:00 2001 From: Kevin van Zonneveld Date: Tue, 3 Feb 2026 20:09:45 +0100 Subject: [PATCH 5/5] Clarify MCP tool allowlists in README --- packages/mcp-server/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/mcp-server/README.md b/packages/mcp-server/README.md index 9b20278b..5529154b 100644 --- a/packages/mcp-server/README.md +++ b/packages/mcp-server/README.md @@ -32,7 +32,9 @@ claude mcp add --transport stdio transloadit \ -- npx -y @transloadit/mcp-server stdio ``` -For non-interactive runs (e.g. `claude -p`), explicitly allow MCP tools: +For non-interactive runs (e.g. `claude -p`), explicitly allow MCP tools. Claude MCP +tools are named `mcp____`, so `mcp__transloadit__*` allows all tools +from this server. ```bash claude -p "List templates" \