What happened
Since the nightly update on Oct 9, the t3-code MCP tools are missing in every Claude thread. The session reports that the server failed to connect with a 401. Restarting T3 Code several times and starting new threads didn't help. The same happens on my Linux server running the same nightly. T3 Code Alpha and the older nightly 20261008.2849 work fine.
Diagnosis
#17408 changed the Claude MCP header to Authorization: ${T3_CODE_MCP_AUTHORIZATION} and passes Bearer <token> through the child's environment. Claude Code expands that reference when it connects. But with CLAUDE_CODE_SUBPROCESS_ENV_SCRUB=1 set (a documented Claude Code security option, https://code.claude.com/docs/en/env-vars, which is set on both of my machines), Claude Code reads credential variables as empty when it expands a remote MCP server's headers. It sends an empty Authorization header, and McpHttpServer.authenticateRequest rejects it with missing_bearer_token.
| T3 build |
Scrub |
t3-code MCP |
| nightly 20261008.2849 (before #17408) |
on |
works |
| nightly 20261009.2873 / .2886 |
on |
401 missing_bearer_token (macOS and Linux) |
| nightly 20261009.2886 |
off |
works |
Renaming the variable won't fix it. The scrub matches the Bearer <token> value, not just the name: with the scrub on, a variable named MY_HEADER holding the same kind of value was also read as empty. One thing I noticed: a bare token without the Bearer prefix, referenced as Bearer ${VAR}, was not blanked (no warning in the debug log). But that relies on Claude Code's detection heuristics (names containing TOKEN are blanked, for example), so it seems fragile as a fix.
main still has the same code in ClaudeAdapterV2.ts.
Steps to reproduce
- Set
CLAUDE_CODE_SUBPROCESS_ENV_SCRUB=1, for example in the env block of ~/.claude/settings.json.
- Start T3 Code nightly (20261009.2873 or later) and open a new Claude thread.
- Ask the agent to call any t3-code tool, or check the session's MCP status: t3-code failed, HTTP 401.
The underlying behavior reproduces with the Claude CLI alone. The token has to look like T3's real one; a short dummy such as Bearer test doesn't trigger it. Nothing needs to listen on the port, because only the debug log matters:
TOKEN=$(openssl rand -base64 32 | tr '+/' '-_' | tr -d '=') # same shape as McpSessionRegistry's token
CLAUDE_CODE_SUBPROCESS_ENV_SCRUB=1 T3_CODE_MCP_AUTHORIZATION="Bearer $TOKEN" \
claude -p hi --strict-mcp-config --debug-file /tmp/cc-debug.log \
--mcp-config '{"mcpServers":{"t":{"type":"http","url":"http://127.0.0.1:47899/mcp","headers":{"Authorization":"${T3_CODE_MCP_AUTHORIZATION}"}}}}'
grep 'never expanded toward a remote server' /tmp/cc-debug.log
Version
0.0.46-nightly.20261009.2886 (also .2873). Last working: 0.0.46-nightly.20261008.2849.
Environment
macOS 27.0, T3 Code Nightly desktop app (Node v24.21.0), claude 2.1.295 (Homebrew); also a Linux server on the same nightly with claude 2.1.296
Evidence
# T3 server trace (server.trace.ndjson, condensed from the span JSON), every /mcp request from the Claude session:
span McpHttpServer.authenticateRequest, WARN event: "rejected MCP request with an unusable credential" { "reason": "missing_bearer_token" }
span http.server POST, http.route /mcp, status 401, user_agent claude-code/2.1.295 (sdk-ts, agent-sdk/0.3.276)
# Claude Code debug log (CLI repro above):
[WARN] MCP server config references credential variable(s) that are never expanded toward a remote server: T3_CODE_MCP_AUTHORIZATION (read as empty)
Related issues
Upstream: anthropics/claude-code#100930 (docs don't mention that the scrub blanks these header variables). Not a duplicate of #7870 or #14076: in those, a valid token expires or is lost. Here a valid token never reaches the header.
Fix applied or workaround
Removed CLAUDE_CODE_SUBPROCESS_ENV_SCRUB from ~/.claude/settings.json. After restarting T3, t3-code works on 2886. This weakens prompt-injection protection, so the other option is to stay on nightly 20261008.2849.
Filed by
Claude Code (claude-opus-5-5) via t3 triage
What happened
Since the nightly update on Oct 9, the t3-code MCP tools are missing in every Claude thread. The session reports that the server failed to connect with a 401. Restarting T3 Code several times and starting new threads didn't help. The same happens on my Linux server running the same nightly. T3 Code Alpha and the older nightly 20261008.2849 work fine.
Diagnosis
#17408 changed the Claude MCP header to
Authorization: ${T3_CODE_MCP_AUTHORIZATION}and passesBearer <token>through the child's environment. Claude Code expands that reference when it connects. But withCLAUDE_CODE_SUBPROCESS_ENV_SCRUB=1set (a documented Claude Code security option, https://code.claude.com/docs/en/env-vars, which is set on both of my machines), Claude Code reads credential variables as empty when it expands a remote MCP server'sheaders. It sends an empty Authorization header, andMcpHttpServer.authenticateRequestrejects it withmissing_bearer_token.missing_bearer_token(macOS and Linux)Renaming the variable won't fix it. The scrub matches the
Bearer <token>value, not just the name: with the scrub on, a variable namedMY_HEADERholding the same kind of value was also read as empty. One thing I noticed: a bare token without theBearerprefix, referenced asBearer ${VAR}, was not blanked (no warning in the debug log). But that relies on Claude Code's detection heuristics (names containingTOKENare blanked, for example), so it seems fragile as a fix.main still has the same code in
ClaudeAdapterV2.ts.Steps to reproduce
CLAUDE_CODE_SUBPROCESS_ENV_SCRUB=1, for example in theenvblock of~/.claude/settings.json.The underlying behavior reproduces with the Claude CLI alone. The token has to look like T3's real one; a short dummy such as
Bearer testdoesn't trigger it. Nothing needs to listen on the port, because only the debug log matters:Version
0.0.46-nightly.20261009.2886 (also .2873). Last working: 0.0.46-nightly.20261008.2849.
Environment
macOS 27.0, T3 Code Nightly desktop app (Node v24.21.0), claude 2.1.295 (Homebrew); also a Linux server on the same nightly with claude 2.1.296
Evidence
Related issues
Upstream: anthropics/claude-code#100930 (docs don't mention that the scrub blanks these header variables). Not a duplicate of #7870 or #14076: in those, a valid token expires or is lost. Here a valid token never reaches the header.
Fix applied or workaround
Removed
CLAUDE_CODE_SUBPROCESS_ENV_SCRUBfrom~/.claude/settings.json. After restarting T3, t3-code works on 2886. This weakens prompt-injection protection, so the other option is to stay on nightly 20261008.2849.Filed by
Claude Code (claude-opus-5-5) via t3 triage