Channels: no way to remotely stop/interrupt an in-progress turn
Summary
Claude Code Channels let a remote user message an agent and get replies, and there is a permission-relay bridge for approving tool calls mid-turn. But there is no way for a channel user to stop or interrupt an in-progress turn, and no hook fires on inbound channel messages, so this cannot be built in a plugin either. For an unattended or remotely-operated agent, "stop" is a baseline safety control, and today it cannot be made binding while the agent is mid-action.
Current behavior
- Inbound channel messages arrive as
notifications/claude/channeland are injected as<channel>context. Delivered to a busy session, a message is treated as steering text at the next tool-call boundary and does not interrupt the running turn; the binding effect only lands on the next turn. - No hook fires on an inbound channel message. The
Notificationhook's matchers cover permission/idle/auth/elicitation/agent-view events, not inbound channel notifications, and the docs state hooks fire on lifecycle events, "not on inbound MCP notifications specifically." So a hook or plugin cannot intercept a mid-turn "stop" out-of-band. - The only way to interrupt a running turn is the interactive Esc key. There is no programmatic or remote equivalent, and an MCP server cannot interrupt the client's turn.
Net: a remote "stop" depends on model cooperation mid-turn (steering) and only becomes binding at the next turn boundary. That is inadequate for halting a long, expensive, or clearly-wrong in-progress action.
Why this belongs in Claude Code
Only the harness can cancel a running turn. An MCP server (the channel plugin) can detect a stop keyword but has no primitive to enforce it. And the plumbing already exists: Claude Code already round-trips a permission request out to the channel mid-turn via notifications/claude/channel/permission, so the harness can already act on a channel-originated event during a turn. A remote stop is a sibling of that mechanism.
Requested
Any one of:
- Native stop keyword (zero plugin change): Claude Code recognizes a configurable stop keyword from an authorized channel sender in an inbound
notifications/claude/channeland interrupts the current turn. - A
claude/channel/stop(or/interrupt) capability that a channel plugin opts into, mirroringclaude/channel/permission, where the harness drives the interrupt. - An inbound-channel hook (a PreToolUse-equivalent that fires on inbound channel notifications, mid-turn) so tooling can gate or act on messages deterministically and out-of-band.
Option 1 is the most useful for end users; option 3 is the most general for tooling.
Environment
Observed with the official Discord channel plugin (gateway to notifications/claude/channel); the delivery and hook behavior is harness-level, not plugin-specific.