[FEATURE] Channel notifications: `silent` mode to inject context without triggering a response
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
There is currently no way to deliver channel content as passive context. Every notification is treated as something Claude should react to.
This creates two problems:
1. Feedback loops in multi-session setups. When two CC sessions exchange messages via a channel plugin, each notification triggers a response that gets sent back to the other session — creating a loop. The main current defense is the instructions field, which is unreliable.
2. Wasted tokens on unwanted acknowledgments. Even with strong instructions to stay silent, Claude frequently produces output ("Noted", "Let me know if you need anything", etc.) — wasting tokens and cluttering the conversation.
Current workarounds:
instructionsfield: Tell Claude to produce no output. Unreliable — Claude breaks this frequently in our testing.- Hook-based suppression: Try to detect channel-triggered turns in hooks and suppress outgoing responses. Fragile — CC fires
UserPromptSubmitfor channel notifications too (not just human input), so there is no reliable way to distinguish them.
None of these are structural solutions.
Proposed Solution
Add a silent parameter to channel notifications:
await mcp.notification({
method: 'notifications/claude/channel',
params: {
content: 'alice: The deployment looks healthy.',
meta: { sender: 'alice', author_role: 'assistant' },
silent: true,
},
})
When silent: true:
- The notification content is added to Claude's context (the
<channel>tag appears in message history as today) - The
←indicator is displayed in the terminal (human sees it) - The notification is visible to the human and available in Claude's future context, but it does not itself solicit a response
- On the next human-initiated turn, Claude sees accumulated silent notifications and can reference them naturally
Default behavior (silent: false or omitted) remains unchanged — notifications trigger Claude to process them, which is correct for interactive channels (alerts, CI failures that need action).
Alternative Solutions
- A new hook event for channel messages (#39596): Would allow hooks to distinguish notification-triggered events from human input. Helps with the loop problem but not the unwanted-response problem.
- A
do_not_respondmeta field: Similar tosilentbut implemented via meta rather than a first-class parameter. Less discoverable but would also work.
Priority
High - Significant impact on productivity
Feature Category
MCP server integration
Use Case Example
A deployment pipeline channel that pushes status updates:
- Channel pushes "build started" (
silent: true) — human sees it, Claude doesn't respond - Channel pushes "tests passing: 42/42" (
silent: true) — background context, no response - Channel pushes "deploy failed — rollback needed" (
silent: false) — Claude responds, helps debug
Without silent, every status update in steps 1-2 triggers Claude to produce output ("Noted, build is in progress..."), wasting tokens and cluttering the conversation with acknowledgments of routine events.
Additional Context
- Channels already support one-way event feeds like CI, webhooks, and monitoring;
silentwould make those feeds usable as background context rather than forced prompts - Related: #39596 (hook event for channel messages)
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗