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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions