feat: add --http local HTTP entry to mcp-server-supabase - #401
feat: add --http local HTTP entry to mcp-server-supabase#401barryroodt wants to merge 12 commits into
Conversation
Coverage Report for CI Build 33911539146Warning Build has drifted: This PR's base is out of sync with its target branch, so coverage data may include unrelated changes. Coverage decreased (-0.1%) to 96.401%Details
Uncovered Changes
Coverage RegressionsNo coverage regressions found. Coverage Stats
💛 - Coveralls |
3a37c5d to
ab4d6b7
Compare
ab4d6b7 to
841a505
Compare
commit: |
841a505 to
c70b3d0
Compare
7294022 to
b5d5fef
Compare
b5d5fef to
d397277
Compare
toNodeHandler replaces the hand-rolled node:http bridge. The 4 MiB body cap and the -32700 parse-error envelope stay entry-owned in readJsonBody, since the SDK collects bodies unbounded when no parsedBody is passed. The server callback wraps that read in try/catch so a client dropping mid-upload cannot kill the process on an unhandled rejection. Bridge tests: the 4 MiB cap test moved into local-http-entry.test.ts, the malformed-JSON test was rewritten as an entry test (400/-32700 plus 415 for a non-JSON content-type), a mid-upload drop test was added, and the round-trip and abort tests were dropped as SDK-owned.
|
@barryroodt I've pushed some changes to shrink the PR, mainly removing tests for stuff that One other QoL improvement I added is a top level Tested locally and with the preview build in latest Claude Code against staging: |


What kind of change does this PR introduce?
Feature: a local Streamable HTTP entry (
--http) for the MCP server.What is the current behavior?
The local server is stdio only. It needs a PAT in the client config, cannot show elicitation dialogs, and the hosted handler only runs inside platform. Matt asked for a local HTTP entry here.
What is the new behavior?
--httpon the primary bin serves the tools over Streamable HTTP onhttp://127.0.0.1:3111/mcp.Authorization; the server stores nothing and has no token flag or env var.legacy: 'stateless', so 2025-era clients keep working; one stderr line per request names the protocol era..mcp.jsonsnippet using${SUPABASE_ACCESS_TOKEN}.create_projectandcreate_branch; legacy clients keepget_cost/confirm_cost.CONTRIBUTING.mdrecommends--httpfor local development; stdio stays documented as the alternative.How to Review
CLI entry
packages/mcp-server-supabase/src/cli.ts--httpbranch: flag parsing, the--access-tokenrejection, and the hand-off to the entry.Per-request pipeline
packages/mcp-server-supabase/src/transports/local-http-entry.tscostConfirmationwiring.Body cap and node adapter
packages/mcp-server-supabase/src/transports/local-http-entry.tsreadJsonBodyowns the 4 MiB cap (413) and the -32700 parse-error envelope for malformed JSON;toNodeHandlerfrom@modelcontextprotocol/nodeadapts the fetch handler tonode:http.Shared handler option
packages/mcp-server-supabase/src/transports/http.tslegacyoption; the hosted handler must still default toreject.Tests
packages/mcp-server-supabase/src/transports/local-http-entry.test.tsDocs
CONTRIBUTING.md--httpsteps and the.mcp.jsonsnippet match what the banner prints.Review questions
--httpflag surface (flags, port, path) the minimal one we want to support long term?legacy: 'stateless'here leave the hosted handler'srejectposture untouched?WWW-Authenticatethe right call given the Claude Code discovery behaviour?Verification
Commands on
5b86dd4(CI on 5b86dd4 pending):packages/mcp-utils tsup --clean: okpnpm --filter @supabase/mcp-server-supabase test src/transports: 26/26 passpnpm --filter @supabase/mcp-server-supabase typecheck: cleanpnpm --filter @supabase/mcp-server-supabase build: oknode dist/cli.js --version: 0.11.0node dist/cli.js --http --port 0: banner printedpnpm test:packed-platform-consumer: 3/3 passpnpm exec biome ci .: cleanHow to test:
npx https://pkg.pr.new/@supabase/mcp-server-supabase@5b86dd4 --http(orpnpm build, thennode packages/mcp-server-supabase/dist/cli.js --http).--project-refis optional; without itcreate_projectis available too.export SUPABASE_ACCESS_TOKEN=<pat>and paste the printed snippet into.mcp.json.MCP_SDK_GENERATION=v2 MCP_PROTOCOL_NEGOTIATION=autoand ask for a preview branch: expect the cost dialog and amodernera line on stderr.get_cost/confirm_costguidance,legacyera line.Verified by Barry on 2026-09-03 on staging through the #404 stack at d397277 (hand-rolled bridge): OAuth login, project list, $0 project created directly, branch cost dialog shown in Claude Code 2.1.258 with a
modern 2026-07-28era line. The toNodeHandler head (5b86dd4) has not had a staging run yet.Additional context
toNodeHandlerfrom@modelcontextprotocol/node. The 4 MiB body cap is entry-owned because the SDK collects request bodies unbounded.honoarrives as a transitive of@hono/node-serverand is never loaded on this path.packages/mcp-server-supabase/src/transports/local-http-entry.ts.WWW-Authenticate: a challenge sends Claude Code into OAuth discovery against localhost.packages/mcp-server-supabase/src/transports/local-http-entry.ts.127.0.0.1), SDK Host guard,/mcponly; other paths get 404.packages/mcp-server-supabase/src/transports/local-http-entry.ts.--project-ref,--read-only,--features,--api-url), not query params;--access-tokenwith--httpexits 1.packages/mcp-server-supabase/src/cli.ts.requestStateprincipal is the SHA-256 of the bearer.packages/mcp-server-supabase/src/transports/local-http-entry.ts.--httpentrypoint shape from feat(mcp): add --http flag to serve the package over HTTP #402.checkjob is red from upstream management-API types drift; it fails onmaintoo.Closes AI-1166