Describe the bug
normalizeFilename in packages/mcp-server-supabase/src/edge-function.ts imports resolve from node:path, which is platform-dispatched, but strips a hardcoded POSIX prefix. On Windows resolve returns a backslash-separated path, so neither prefix strip can ever match and the full absolute path is returned instead of the file name.
For a developer running the MCP server locally on Windows, get_edge_function and list_edge_functions report entrypoint_path and files[].name as C:\tmp\user_fn_<deployment>\index.ts rather than index.ts.
This is confined to locally-run servers - the hosted server runs on Linux, where resolve is already POSIX, so hosted users are unaffected. It is also invisible to CI, which is Linux-only.
To Reproduce
Clone main on Windows and run the unit suite. No changes needed:
git clone https://github.com/supabase/mcp.git
cd mcp
pnpm install
pnpm run build
cd packages/mcp-server-supabase
set CI=true && pnpm vitest run --project unit
5 tests across 2 files fail on untouched main (30baa1f):
FAIL src/edge-function.test.ts > normalizeFilename > handles deno 1 paths
Expected: "index.ts"
Received: "C:\tmp\user_fn_xnzcmvwhvqonuunmwgdz_2b72daae-...-46f2df0463d1_2\source\index.ts"
FAIL src/edge-function.test.ts > normalizeFilename > handles deno 2 paths
FAIL src/edge-function.test.ts > normalizeFilename > doesn't interfere with nested directories
Expected: "/my/local/source/index.ts"
Received: "C:\my\local\source\index.ts"
FAIL src/server.test.ts > tools > list edge functions
FAIL src/server.test.ts > tools > get edge function
- "entrypoint_path": "index.ts",
+ "entrypoint_path": "C:\\tmp\\user_fn_wnibtrpkkvmuyxpollho_74bb898d-...-4f777d13e75a_1\\index.ts",
- "name": "index.ts",
+ "name": "C:\\tmp\\user_fn_fdkdaergfyvyekhgnrct_3a12780f-...-a6e57ae4a7f1_1\\index.ts",
Test Files 2 failed | 12 passed (14)
Tests 5 failed | 210 passed (215)
The last two are the tool output itself, so this is not only a test-harness artifact - it is what an MCP client on Windows actually receives.
Root cause
packages/mcp-server-supabase/src/edge-function.ts:
import { resolve } from 'node:path'; // platform-dispatched
export function getPathPrefix(deploymentId: string) {
return `/tmp/user_fn_${deploymentId}/`; // always POSIX
}
const filenameAbsolute = resolve(pathPrefix, filename);
let filenameWithoutPrefix = filenameAbsolute;
filenameWithoutPrefix = withoutPrefix(filenameWithoutPrefix, pathPrefix);
filenameWithoutPrefix = withoutPrefix(filenameWithoutPrefix, 'source/');
pathPrefix is always POSIX - it describes a path inside the Deno sandbox on the server, not on the developer's machine - but resolve follows the host OS. On Windows it returns C:\tmp\user_fn_...\source\index.ts, so startsWith(pathPrefix) is false for both /tmp/user_fn_.../ and source/, both strips are no-ops, and the whole absolute path falls through.
The intent is unambiguous elsewhere in the codebase: every caller in platform/api-platform.ts already forces POSIX semantics with fileURLToPath(..., { windows: false }) before calling in. That one platform-dependent import undoes it.
Expected behavior
normalizeFilename should return index.ts, and leave genuinely nested paths alone, regardless of host OS.
Suggested fix
One line - import the POSIX variant, since every path this function touches is POSIX by construction:
-import { resolve } from 'node:path';
+import { resolve } from 'node:path/posix';
Verified on Windows against main at 30baa1f:
|
result |
untouched main |
5 failed | 210 passed (215) |
| same tree, one-line change |
215 passed (215) |
All five failures clear, including the two in server.test.ts, and nothing else changes.
System information
- OS: Windows 11 (10.0.26200)
- Node.js 22 LTS, pnpm 10.34.5
supabase/mcp at main, commit 30baa1f
Additional context
This looks like a regression of a bug that was already fixed once. 8e9a447 ("fix: edge function path parsing on windows", May 2025) added { windows: false } to the fileURLToPath calls in api-platform.ts - those are still there, and are what I'm referring to above when I say the callers already force POSIX. normalizeFilename was added later in #138 ("consistent edge function filenames for deno 1 & 2", Sept 2025) and reintroduced the same class of bug at a new call site downstream of them.
That's really an argument for a regression test rather than just the one-line change: the current tests only pass POSIX strings, so they succeed on Linux whichever import is used, and nothing in a Linux-only CI can catch this class of bug before it lands a third time.
Happy to open a PR with the one-line change plus a platform-independent test if that's useful.
Describe the bug
normalizeFilenameinpackages/mcp-server-supabase/src/edge-function.tsimportsresolvefromnode:path, which is platform-dispatched, but strips a hardcoded POSIX prefix. On Windowsresolvereturns a backslash-separated path, so neither prefix strip can ever match and the full absolute path is returned instead of the file name.For a developer running the MCP server locally on Windows,
get_edge_functionandlist_edge_functionsreportentrypoint_pathandfiles[].nameasC:\tmp\user_fn_<deployment>\index.tsrather thanindex.ts.This is confined to locally-run servers - the hosted server runs on Linux, where
resolveis already POSIX, so hosted users are unaffected. It is also invisible to CI, which is Linux-only.To Reproduce
Clone
mainon Windows and run the unit suite. No changes needed:5 tests across 2 files fail on untouched
main(30baa1f):The last two are the tool output itself, so this is not only a test-harness artifact - it is what an MCP client on Windows actually receives.
Root cause
packages/mcp-server-supabase/src/edge-function.ts:pathPrefixis always POSIX - it describes a path inside the Deno sandbox on the server, not on the developer's machine - butresolvefollows the host OS. On Windows it returnsC:\tmp\user_fn_...\source\index.ts, sostartsWith(pathPrefix)is false for both/tmp/user_fn_.../andsource/, both strips are no-ops, and the whole absolute path falls through.The intent is unambiguous elsewhere in the codebase: every caller in
platform/api-platform.tsalready forces POSIX semantics withfileURLToPath(..., { windows: false })before calling in. That one platform-dependent import undoes it.Expected behavior
normalizeFilenameshould returnindex.ts, and leave genuinely nested paths alone, regardless of host OS.Suggested fix
One line - import the POSIX variant, since every path this function touches is POSIX by construction:
Verified on Windows against
mainat30baa1f:main5 failed | 210 passed (215)215 passed (215)All five failures clear, including the two in
server.test.ts, and nothing else changes.System information
supabase/mcpatmain, commit30baa1fAdditional context
This looks like a regression of a bug that was already fixed once.
8e9a447("fix: edge function path parsing on windows", May 2025) added{ windows: false }to thefileURLToPathcalls inapi-platform.ts- those are still there, and are what I'm referring to above when I say the callers already force POSIX.normalizeFilenamewas added later in #138 ("consistent edge function filenames for deno 1 & 2", Sept 2025) and reintroduced the same class of bug at a new call site downstream of them.That's really an argument for a regression test rather than just the one-line change: the current tests only pass POSIX strings, so they succeed on Linux whichever import is used, and nothing in a Linux-only CI can catch this class of bug before it lands a third time.
Happy to open a PR with the one-line change plus a platform-independent test if that's useful.