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
- 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.1
POST 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/mcp with a valid Authorization: Bearer sk_live_… header should accept the MCP initialize JSON-RPC call and respond with HTTP 200 plus an Mcp-Session-Id header.
- The same key that authenticates a
GET /api/mcp request must authenticate a POST /api/mcp request.
- 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/mcp service 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, with Copy key / Copy setup buttons. 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
Additional context
- Pascal's own service descriptor advertises
transport: "streamable-http" and auth.methods: ["api-key"] with apiKeyHeader: "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 send X-Agent-Client or 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/register flow 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.
What happened?
Attempting to add Pascal as a custom MCP connector in Perplexity fails with:
Investigation shows Pascal's
/api/mcpendpoint accepts the API key onGET(returns the service descriptor with HTTP 200) but rejects the same key on thePOST initializehandshake that Perplexity actually performs, returning: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
https://editor.pascal.app/api/mcpsk_live_…→ Perplexity returns:
[API_CLIENTS_ERROR] MCP server returned HTTP 419.Reproduce server-side with curl using the same key:
GET works:
POST initialize fails:
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.GET /api/mcprequest must authenticate aPOST /api/mcprequest.Browser & OS
GET /api/mcpservice descriptor) - Date observed: 2026-05-02Screenshots or screen recordings
sk_live_…) created May 2, 2026, withCopy key/Copy setupbuttons. Key was copied via this button (not selected manually) to ensure full length.https://editor.pascal.app/api/mcpsk_live_…value[API_CLIENTS_ERROR] MCP server returned HTTP 419Additional context
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.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./api/auth/agent/registerflow instead of Settings keys, please clarify in docs.X-Agent-Client, agent-registered keys, SSE transport) if it helps narrow it down.