VS Code extension cannot use channels: it never passes --channels, and forcing the flag in still drops all inbound notifications (stream-json cannot show the registration dialog)
Summary
The VS Code extension has no way to run a session with channels. It never passes --channels or --dangerously-load-development-channels, and forcing the flag onto the CLI's command line does not help: the session then looks channel-enabled everywhere it can be inspected, but inbound notifications/claude/channel never surfaces. A terminal session launched with the identical flag, against the same repo and the same pending message, receives it immediately.
Related but not the same: #86800 asks for this in the desktop app. This is the VS Code extension.
Environment
- Claude Code 2.1.247, native installer
- VS Code extension 2.1.247-darwin-arm64
- macOS 15 (Darwin 25.3.0), arm64
- claude.ai OAuth, personal Max plan
- A local stdio MCP server declaring
capabilities.experimental['claude/channel'], registered in the project's.mcp.jsonas a bareserver:channel
1. The extension never passes the flag
$ grep -c 'dangerously-load-development-channels' \
~/.vscode/extensions/anthropic.claude-code-2.1.247-darwin-arm64/extension.js
0
--channels is likewise absent. The bundled SDK supports the option; nothing populates it.
2. Forcing the flag on is not sufficient
The extension exposes claudeCode.claudeProcessWrapper, which it uses as the executable itself, handing the real binary as argv[1]:
resolveClaudeBinary(){
let $=e4("claudeProcessWrapper"), Q=..., J=WZ1(this.context);
if($) return {pathToClaudeCodeExecutable:$, executableArgs:J?[J]:[], env:Q};
...
}
A wrapper that re-execs argv[1] with the flag prepended works exactly as intended — the flag reaches the real process:
$ ps -p 70539 -o args=
/Users/…/anthropic.claude-code-2.1.247-darwin-arm64/resources/native-binary/claude
--dangerously-load-development-channels server:multiverse-channel
--output-format stream-json --verbose --input-format stream-json
--max-thinking-tokens 31999 --permission-prompt-tool stdio
The channel MCP server starts as that process's child and connects normally. Its tools work.
Inbound notifications never arrive. A message written to the session's inbox before it started, and still unread, was never pushed.
3. Same message, same repo, terminal session — delivered immediately
With the extension window still open, a terminal session on the same repository reported that delivery belonged elsewhere and it would not receive. Closing the extension window:
← multiverse-channel: This session now receives channel messages for eastern-cruise-server
← multiverse-channel: handoff 2026-08-27 18:2x KST — …
The message, the server, and the inbox were fine the whole time. The only variable was which client held the session.
Likely cause
The extension runs the CLI with --output-format stream-json --input-format stream-json. The documented registration step is a full-screen confirmation dialog, which that mode has nowhere to draw — the same reason -p / print mode is already known not to register a channel (cf. #80822, where headless -p interacts badly with channel state).
So this is not "the extension forgot a flag". Passing the flag from the extension would not be enough on its own; the registration step needs a path that does not require a TUI.
What would fix it
Any one of:
- A non-interactive registration path — a settings key or a startup acknowledgement that stream-json clients can use in place of the dialog, so a channel can register without a TUI.
- The extension populates
--channelsand surfacesnotifications/claude/channelin its UI. (notifications/claude/channelappears 0 times inextension.jstoday; the CLI binary handles it, so the gap is on the extension side of the stream.) - A clear refusal. If channels are intentionally terminal-only for now, saying so at startup would be a large improvement over the current behaviour, which is silence.
Why the silence is the expensive part
Every signal available to a user says it is working. The flag is on the command line. The MCP server is connected and its tools respond. The inbox contains the message. Nothing anywhere reports a refusal — the session simply never mentions the message.
Worse, a coordination layer built on channels cannot tell the two states apart either. Ours infers "this session can receive" from the presence of the flag on the launching command line, which was reliable until a wrapper put that flag on a client that cannot receive. The result was an extension window quietly holding delivery for a repository and dropping everything sent to it. We have since taught our side to check the client's mode as well — but that is us working around the absence of a signal that only the CLI can give.
A refusal at startup, in the shape of the existing server <name> not in --channels list for this session message, would make this diagnosable in seconds instead of hours.