Description
After enabling mcp: true in the EmDash config, the MCP endpoint at /_emdash/api/mcp returns HTTP 500 with an empty response body on Cloudflare Workers. The route is registered (no longer 404), but every request crashes silently.
This also affects the REST API when using Bearer token authentication. All /_emdash/api/content/* requests with a valid ec_pat_ token return 500, while unauthenticated requests correctly return 401. The admin UI (session-based auth) works fine.
Steps to reproduce
- Deploy EmDash to Cloudflare Workers with
mcp: true in astro.config.mjs:
emdash({
database: d1({ binding: "DB", session: "auto" }),
storage: r2({ binding: "MEDIA" }),
mcp: true,
})
-
Generate a valid ec_pat_ token and insert it into the _emdash_api_tokens table (via wrangler d1 execute)
-
Send a request to the MCP endpoint:
curl -X POST https://your-site.workers.dev/_emdash/api/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Authorization: Bearer ec_pat_..." \
-d '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}},"id":1}'
- Response: HTTP 500, empty body
Also confirmed: the REST API at /_emdash/api/content/posts returns 500 with the same Bearer token, while returning 401 without auth. So the issue is in the auth middleware's token resolution path on Workers, not specific to MCP.
What I verified
- Token hash is correct (SHA-256 via
@oslojs/crypto/sha2, base64url-encoded, matches DB value)
- User exists in the
users table with admin role (50)
- Token row exists in
_emdash_api_tokens with correct token_hash, prefix, and user_id
- The
hashPrefixedToken function from @emdash-cms/auth produces the same hash locally
- Admin UI works (session auth path is fine)
nodejs_compat flag is set in wrangler.jsonc
Likely cause
The auth middleware at dist/astro/middleware/auth.mjs imports hashPrefixedToken from @emdash-cms/auth, which uses @oslojs/crypto/sha2 (synchronous SHA-256). This may behave differently in the Cloudflare Workers runtime vs Node.js, or the Kysely query on D1 may throw an unhandled error. The catch block in the MCP route returns a JSON error, but the 500 has an empty body, suggesting the crash happens before the MCP handler (i.e., in the auth middleware).
Environment
- EmDash: 0.1.0 (npm
emdash@0.0.3)
- Cloudflare Workers with D1 + R2
compatibility_date: 2026-02-24
compatibility_flags: ["nodejs_compat"]
- Node.js 24.11.1 (local)
Related
Description
After enabling
mcp: truein the EmDash config, the MCP endpoint at/_emdash/api/mcpreturns HTTP 500 with an empty response body on Cloudflare Workers. The route is registered (no longer 404), but every request crashes silently.This also affects the REST API when using Bearer token authentication. All
/_emdash/api/content/*requests with a validec_pat_token return 500, while unauthenticated requests correctly return 401. The admin UI (session-based auth) works fine.Steps to reproduce
mcp: trueinastro.config.mjs:Generate a valid
ec_pat_token and insert it into the_emdash_api_tokenstable (viawrangler d1 execute)Send a request to the MCP endpoint:
Also confirmed: the REST API at
/_emdash/api/content/postsreturns 500 with the same Bearer token, while returning 401 without auth. So the issue is in the auth middleware's token resolution path on Workers, not specific to MCP.What I verified
@oslojs/crypto/sha2, base64url-encoded, matches DB value)userstable with admin role (50)_emdash_api_tokenswith correcttoken_hash,prefix, anduser_idhashPrefixedTokenfunction from@emdash-cms/authproduces the same hash locallynodejs_compatflag is set inwrangler.jsoncLikely cause
The auth middleware at
dist/astro/middleware/auth.mjsimportshashPrefixedTokenfrom@emdash-cms/auth, which uses@oslojs/crypto/sha2(synchronous SHA-256). This may behave differently in the Cloudflare Workers runtime vs Node.js, or the Kysely query on D1 may throw an unhandled error. The catch block in the MCP route returns a JSON error, but the 500 has an empty body, suggesting the crash happens before the MCP handler (i.e., in the auth middleware).Environment
emdash@0.0.3)compatibility_date: 2026-02-24compatibility_flags: ["nodejs_compat"]Related