[FEATURE] Custom connectors: support static request headers (e.g. `Authorization: Bearer …`) — currently OAuth-only, forcing `mcp-remote` stdio shims

Status Open
Reported on v2.1.239
Maintainer reply None cached
Activity 1 comment · opened Aug 21, 2026

Summary

Settings → Connectors → Add custom connector can only reach a remote MCP server that is either fully public or speaks OAuth. There is no way to attach a static request header, so any HTTP MCP server that authenticates with a pre-issued bearer token or API key cannot be added as a connector at all.

The CLI already supports exactly this. claude mcp add --help:

  # Add HTTP server with headers:
  claude mcp add --transport http corridor https://app.corridor.dev/api/mcp --header "Authorization: Bearer ..."

  -H, --header <header...>     Set WebSocket headers (e.g. -H "X-Api-Key: abc123" -H "X-Custom: value")

The request is to bring that same capability to the custom-connector UI.

Environment

  • Claude Desktop 1.34493.1 (amd64), Linux beta
  • Ubuntu 24.04.4 LTS, x86_64
  • Claude Code CLI 2.1.239

To be clear, this is not a Linux-specific gap — remote MCP itself works fine on the Linux beta (verified: 7 cloud connectors resolving alongside 13 local stdio servers, replaceRemoteMcpServers: serverCount=7 in ~/.config/Claude/logs/main.log). The header limitation is platform-independent; the Linux environment is listed only because that is where it was hit.

Current behavior

Adding a token-authenticated HTTP MCP server as a custom connector is impossible. The dialog accepts a URL and negotiates OAuth; there is no field for headers, and no equivalent of the CLI's --header.

Workaround being used

Every such server has to be re-declared as a local stdio server in claude_desktop_config.json, wrapping the remote endpoint in an mcp-remote proxy purely to inject one header:

{
  "mcpServers": {
    "engineering": {
      "command": "/path/to/node",
      "args": [
        "/path/to/mcp-remote/dist/proxy.js",
        "https://mcp.example.internal/v1/mcp/<server-id>",
        "--transport", "http-only",
        "--header", "Authorization: Bearer <REDACTED>"
      ]
    }
  }
}

In our setup that is 13 stdio shims standing in for what should be 13 native remote connectors.

The workaround is bad in concrete ways:

  1. Secrets land in plaintext on disk. The bearer token sits in claude_desktop_config.json, and additionally in the process argv of every proxy — visible to any local process via /proc/*/cmdline. A connector-managed credential could be stored in the OS keychain instead.
  2. Loses everything remote connectors give you. Cloud-side execution, availability from claude.ai and the mobile apps, and org-level connector management all disappear — these servers exist only on the one machine whose config file lists them.
  3. N extra Node processes. One long-lived proxy per server, each a restart/failure surface that a native connector would not have.
  4. No sync. Every machine and every teammate must hand-maintain the same config file and the same secret.

Requested behavior

In Add custom connector, alongside the existing OAuth path, allow one or more static headers to be attached to the connector, with the values stored as secrets (write-only in the UI, masked on read, kept in the keychain / connector secret store rather than in a plaintext config file).

Header-authenticated servers are common — internal gateways, self-hosted MCP servers, and vendors that issue long-lived API keys rather than running an OAuth authorization server. Today all of them are second-class relative to OAuth servers, despite the CLI supporting them natively.

Related

  • #80298 — headersHelper 401-recovery falls back to OAuth DCR instead of re-invoking headersHelper (CLI-side header handling)
  • #68960 — closed request for an apiKeyHelper-equivalent for custom headers
  • #57349 — open request for an OAuth-compliant credential manager for connectors

None of these cover adding a static header from the custom-connector UI.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗