Channels: no way to remotely stop/interrupt an in-progress turn

Status Open
Maintainer reply None cached
Activity 0 comments · opened Jul 23, 2026

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/channel and 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 Notification hook'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:

  1. Native stop keyword (zero plugin change): Claude Code recognizes a configurable stop keyword from an authorized channel sender in an inbound notifications/claude/channel and interrupts the current turn.
  2. A claude/channel/stop (or /interrupt) capability that a channel plugin opts into, mirroring claude/channel/permission, where the harness drives the interrupt.
  3. 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.

View original on GitHub ↗