MCP endpoint matches the Authorization scheme case-sensitively and logs the same reason for "absent" and "wrong scheme" (ChatGPT connector gets missing_bearer_token)#23710

opened13d agobyFfanaru

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/server

Steps to reproduce

Control (dummy, non-secret value, through the public managed host)

  • Authorization: Bearer <dummy> -> 401, reason unknown_or_expired_token (the header passes the tunnel and reaches verification)
  • Authorization: bearer <dummy> -> 401, reason missing_bearer_token

Expected behavior

  1. Match the scheme case-insensitively.
  2. Log distinct reasons (for example missing_authorization_header vs unsupported_scheme), without logging the credential.

Actual behavior

Summary The MCP HTTP middleware only accepts an Authorization value that starts with exactly "Bearer " (case-sensitive). RFC 9110 section 11.1 says the auth-scheme is case-insensitive. A lowercase "bearer <token>" is rejected with 401 and the warning reason "missing_bearer_token", which is also the reason logged when no header is sent at all, so the two cases cannot be told apart in the logs.

Why I noticed ChatGPT custom MCP app (OAuth/DCR, orchestration:read only). OAuth completes: register 201, approval, /oauth/mcp/token 200 with token_type "Bearer". But every /mcp POST from the ChatGPT connector (UA Python/aiohttp), 8 of 8 across two separate authorizations, including one 0.8 s after token issuance and several after "Update tools", is rejected with missing_bearer_token, and the token-verification step never runs. From T3's logs I cannot tell whether ChatGPT sends no Authorization header or a scheme/case T3 does not accept. This may well be OpenAI-side; if so, this issue is only about the two T3 points under Expected behavior.

No credentials, environment IDs or hostnames are included.

Impact

Minor bug or occasional failure

Version or commit

T3 Code Desktop (stable) 0.1.1

Environment

macOS arm64, T3 Code Desktop 0.1.1, main server on 3773, reached through the managed tunnel host

Logs or stack traces

shell
1

Screenshots, recordings, or supporting files

No response

Workaround

No response

I'm taking this one: case-insensitive Bearer scheme matching on the MCP endpoint (both the middleware in McpHttpServer.ts and EnvironmentAuth.parseBearerToken behind the OAuth client authenticator), plus distinct rejection reasons (missing_authorization_header / unsupported_authorization_scheme vs missing_bearer_token) without logging the credential.

Synced from GitHub

I'm seeing a similar problem on macOS with T3 Code nightly 0.1.6-nightly.20261029.3892. Codex has successfully listed my T3 projects, but my main ChatGPT dot conversation still doesn't get the T3 tools, so it can't orchestrate work into T3 Code. I selected Auto access, not read-only.

One wrinkle: a separate ChatGPT cloud session has now successfully called t3_project_list, while the main dot conversation still has no callable T3 tools. A delegated local task also returned “Auth required” during MCP initialization. So the behavior differs between sessions.

I haven't captured the Authorization header, so I can't confirm lowercase bearer versus a missing header, or that this issue explains every symptom. Posting here because the Codex/ChatGPT difference looks related. It would be helpful to know which nightly includes the fix so I can retest.