Skip to content

fix(professional-crm): two deploy-blocking bugs in the Edge Function reference#330

Open
UpLeafed wants to merge 2 commits into
NateBJones-Projects:mainfrom
UpLeafed:fix/professional-crm-deploy-blockers
Open

fix(professional-crm): two deploy-blocking bugs in the Edge Function reference#330
UpLeafed wants to merge 2 commits into
NateBJones-Projects:mainfrom
UpLeafed:fix/professional-crm-deploy-blockers

Conversation

@UpLeafed

@UpLeafed UpLeafed commented May 27, 2026

Copy link
Copy Markdown

Summary

Fixes two issues that prevent extensions/professional-crm/index.ts from being deployed as published — anyone who follows the README and runs supabase functions deploy professional-crm-mcp against a fresh project hits both immediately.

Discovered while deploying the extension against a real Supabase project + claude.ai connector. Each fix is isolated in its own commit so they can be reviewed (or split into separate PRs) independently.

Bug 1 — StreamableHTTPTransport constructor options crash on every POST

The transport is instantiated with { sessionIdGenerator: undefined, enableJsonResponse: true }. The pinned @hono/mcp@0.1.1 (deno.json) does not accept these options on its StreamableHTTPTransport constructor — passing them causes the handler to fail at runtime, returning HTTP 500 on every POST. GET probes return 200 (looks healthy), but MCP traffic 100% fails.

Symptom in Claude Desktop: "Couldn't reach the MCP server" on first connect, then — after retry — "Couldn't register with sign-in service. You can try again, or add an OAuth Client ID in the connector settings" (Claude infers an OAuth flow from the 500 response).

Fix: new StreamableHTTPTransport() with no args, matching the pattern in OB1's working core MCP example.

Bug 2 — Missing CORS preflight + response headers

Claude Desktop and claude.ai connectors send an OPTIONS preflight before opening the MCP stream. Without an app.options(...) handler, Hono returns 404 and the connector probe fails. Error responses (401, 500) also need CORS headers so the browser-based client can read the JSON body.

Fix: add corsHeaders, an app.options("*", ...) handler, and attach corsHeaders to existing 401/500/GET responses. The MCP success path through transport.handleRequest(c) is unchanged.

Verification

After applying both commits, deployed to a Supabase Edge Function (@hono/mcp@0.1.1, @modelcontextprotocol/sdk@1.24.3, hono@4.9.2 — all per the pinned deno.json) and confirmed:

  • OPTIONS /functions/v1/professional-crm-mcp → 200 with CORS headers
  • GET /functions/v1/professional-crm-mcp → 200 status JSON
  • POST … {"method":"initialize"} → 200 with proper MCP serverInfo
  • POST … {"method":"tools/list"} → 200 listing all 10 crm_* tools
  • POST … {"method":"tools/call","params":{"name":"crm_get_follow_ups",…}} → 200 with real data from professional_contacts
  • Claude Desktop connector reaches green-checkmark state and all 10 tools appear in chat

Test plan

  • Maintainer can reproduce the original 500 by deploying current main against a clean Supabase project with the four required secrets set
  • After applying these commits, the same deploy succeeds end-to-end with no client/connector retries needed
  • Manual MCP initialize returns the expected serverInfo JSON
  • No regression in the upstream README-documented flow

Closes #331

claude added 2 commits May 26, 2026 20:58
…d options

The pinned @hono/mcp@0.1.1 (deno.json) does not accept the
`sessionIdGenerator` or `enableJsonResponse` options on its
StreamableHTTPTransport constructor. Passing them causes the request
handler to fail at runtime, returning HTTP 500 on every POST to the
Edge Function. The function appears reachable (GET probes return 200)
but all MCP traffic fails, which manifests in Claude Desktop as
"Couldn't reach the MCP server" or — once the connector retries —
"Couldn't register with sign-in service" (Claude infers OAuth from the
500 response).

Calling the constructor with no arguments matches the working pattern
in other OB1 extensions and restores normal operation. Verified with
manual MCP initialize + tools/list against a deployed Supabase Edge
Function: HTTP 200, all 10 crm_* tools register and respond correctly.
…clients

Claude Desktop and claude.ai connectors send an OPTIONS preflight before
opening the MCP stream. Without an OPTIONS handler the function returns
404 on preflight and the connector reports either "Couldn't reach the
MCP server" or, after retry, "Couldn't register with sign-in service"
(Claude infers an OAuth flow from the missing preflight).

This mirrors the pattern already used in the core OpenBrain MCP server
example: an `app.options("*", ...)` handler that returns the CORS
headers, plus those same headers attached to the 401 / 500 error
responses and the GET status endpoint so the browser-based connector
can actually read the response body.

The success path through `transport.handleRequest(c)` is unchanged —
@hono/mcp emits its own response for the JSON-RPC body, which has been
empirically sufficient for browser-context MCP clients.
@github-actions github-actions Bot added the extension Contribution: curated learning path build label May 27, 2026
@github-actions

Copy link
Copy Markdown

Hey @UpLeafed — welcome to Open Brain Source! 👋

Thanks for submitting your first PR. The automated review will run shortly and check things like metadata, folder structure, and README completeness. If anything needs fixing, the review comment will tell you exactly what.

Once the automated checks pass, a human admin will review for quality and clarity. Expect a response within a few days.

If you have questions, check out CONTRIBUTING.md or open an issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

extension Contribution: curated learning path build

Projects

None yet

2 participants