Skip to content

Support Perplexity custom connectors (MCP Streamable HTTP) — POST /api/mcp rejects valid API keys with 401 / clients see HTTP 419 #288

@fieldmanneasi

Description

@fieldmanneasi

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

  1. In Pascal → Settings → API keys, create a new key (e.g. "Perplexity") and copy it via the Copy key button.
  2. 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
  3. 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

Image
  1. 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.
Image
  1. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions