Support Perplexity custom connectors (MCP Streamable HTTP) — POST /api/mcp rejects valid API keys with 401 / clients see HTTP 419
What happened?
Attempting to add Pascal as a custom MCP connector in Perplexity fails with:
[API_CLIENTS_ERROR] MCP server returned HTTP 419
Investigation shows Pascal's /api/mcp endpoint accepts the API key on GET (returns the service descriptor with HTTP 200) but rejects the same key on the POST initialize handshake that Perplexity actually performs, returning:
HTTP 401 — {"error":"unauthorized","message":"Invalid or revoked API key."}
The 419 surfaced in Perplexity appears to be Pascal's middleware (Laravel-style "Page Expired" / CSRF) mapping the unauthenticated POST. Net effect: Perplexity cannot connect to Pascal at all, while Codex / Claude Code / Cursor / OpenClaw work fine with the same account.
Steps to reproduce
- In Pascal → Settings → API keys, create a new key (e.g. "Perplexity") and copy it via the Copy key button.
- In Perplexity → Settings → Connectors → Add custom connector, enter:
- MCP server URL:
https://editor.pascal.app/api/mcp - Authentication: API Key
- Key: the freshly copied
sk_live_… - Transport: Streamable HTTP
- MCP server URL:
- Click Add.
→ Perplexity returns:
[API_CLIENTS_ERROR] MCP server returned HTTP 419.
Reproduce server-side with curl using the same key:
GET works:
curl -i -H "Authorization: Bearer sk_live_…" https://editor.pascal.app/api/mcp
# → HTTP/2 200, service descriptor JSON, version 0.6.1POST initialize fails:
curl -i -X POST https://editor.pascal.app/api/mcp \
-H "Authorization: Bearer sk_live_…" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Mcp-Protocol-Version: 2025-06-18" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"test","version":"0.0.1"}}}'
# → HTTP/2 401
# → {"error":"unauthorized","message":"Invalid or revoked API key."}Expected behavior
POST /api/mcpwith a validAuthorization: Bearer sk_live_…header should accept the MCPinitializeJSON-RPC call and respond with HTTP 200 plus anMcp-Session-Idheader.- The same key that authenticates a
GET /api/mcprequest must authenticate aPOST /api/mcprequest. - Perplexity custom connectors should connect successfully, comparably to Codex / Claude Code / Cursor / OpenClaw.
- No 419 / CSRF-style rejection on stateless Bearer-authenticated MCP requests.
Browser & OS
- OS: macOS (Apple Silicon) - Browser: Perplexity Comet (latest) — also reproducible in Perplexity web on Chrome/Safari - Pascal MCP server version: 0.6.1 (from
GET /api/mcpservice descriptor) - Date observed: 2026-05-02
Screenshots or screen recordings
- Pascal Settings → API keys panel — shows a freshly created "Perplexity" key (
sk_live_…) created May 2, 2026, withCopy key/Copy setupbuttons. Key was copied via this button (not selected manually) to ensure full length.
- Perplexity → Add custom connector dialog — fields filled exactly as documented:
- MCP server URL:
https://editor.pascal.app/api/mcp - Authentication: API Key + the
sk_live_…value - Transport: Streamable HTTP
- Risk acknowledgement checkbox ticked
- Footer shows the failure:
[API_CLIENTS_ERROR] MCP server returned HTTP 419
- MCP server URL:
Additional context
- Pascal's own service descriptor advertises
transport: "streamable-http"andauth.methods: ["api-key"]withapiKeyHeader: "Authorization: Bearer sk_live_... or sk_test_..."— exactly what Perplexity sends, so the Perplexity-side configuration matches Pascal's documented expectations. - CORS allow-list on the endpoint includes
X-Agent-Client,Mcp-Protocol-Version,Mcp-Session-Id— suggesting session-based MCP. If Perplexity must sendX-Agent-Clientor some other header to be accepted, please document. - The descriptor notes: "For browser-visible co-editing, use an API key created in Settings by the same logged-in user… Agent self-registration creates a separate owner account." If Perplexity must use the
/api/auth/agent/registerflow instead of Settings keys, please clarify in docs. - HTTP 419 is non-standard; widely used by Laravel for "Page Expired" / CSRF token mismatch. Suggests the POST handler may be sitting behind web-session middleware that doesn't belong on a stateless MCP API.
- Tested clients that DO work with the same Pascal account: Codex CLI, Claude Code, Cursor. Only Perplexity fails — but the curl POST repro shows the failure is server-side, not Perplexity-specific.
- Happy to run additional curl variants (different protocol versions, with/without
X-Agent-Client, agent-registered keys, SSE transport) if it helps narrow it down. - Perplexity custom-connector support would be highly valuable for users combining research workflows with 3D scene authoring — a natural fit for Pascal.
Source: pascalorg/editor