MCPcopy
hub / github.com/codeaashu/claude-code / handleChannelEnable

Function handleChannelEnable

src/cli/print.ts:4662–4768  ·  view source on GitHub ↗

* IDE-triggered channel enable. Derives the ChannelEntry from the connection's * pluginSource (IDE can't spoof kind/marketplace — we only take the server * name), appends it to session allowedChannels, and runs the full gate. On * gate failure, rolls back the append. On success, registers a notif

(
  requestId: string,
  serverName: string,
  connectionPool: readonly MCPServerConnection[],
  output: Stream<StdoutMessage>,
)

Source from the content-addressed store, hash-verified

4660 * interactive either.)
4661 */
4662function handleChannelEnable(
4663 requestId: string,
4664 serverName: string,
4665 connectionPool: readonly MCPServerConnection[],
4666 output: Stream<StdoutMessage>,
4667): void {
4668 const respondError = (error: string) =>
4669 output.enqueue({
4670 type: 'control_response',
4671 response: { subtype: 'error', request_id: requestId, error },
4672 })
4673
4674 if (!(feature('KAIROS') || feature('KAIROS_CHANNELS'))) {
4675 return respondError('channels feature not available in this build')
4676 }
4677
4678 // Only a 'connected' client has .capabilities and .client to register the
4679 // handler on. The pool spread at the call site matches mcp_status.
4680 const connection = connectionPool.find(
4681 c => c.name === serverName && c.type === 'connected',
4682 )
4683 if (!connection || connection.type !== 'connected') {
4684 return respondError(`server ${serverName} is not connected`)
4685 }
4686
4687 const pluginSource = connection.config.pluginSource
4688 const parsed = pluginSource ? parsePluginIdentifier(pluginSource) : undefined
4689 if (!parsed?.marketplace) {
4690 // No pluginSource or @-less source — can never pass the {plugin,
4691 // marketplace}-keyed allowlist. Short-circuit with the same reason the
4692 // gate would produce.
4693 return respondError(
4694 `server ${serverName} is not plugin-sourced; channel_enable requires a marketplace plugin`,
4695 )
4696 }
4697
4698 const entry: ChannelEntry = {
4699 kind: 'plugin',
4700 name: parsed.name,
4701 marketplace: parsed.marketplace,
4702 }
4703 // Idempotency: don't double-append on repeat enable.
4704 const prior = getAllowedChannels()
4705 const already = prior.some(
4706 e =>
4707 e.kind === 'plugin' &&
4708 e.name === entry.name &&
4709 e.marketplace === entry.marketplace,
4710 )
4711 if (!already) setAllowedChannels([...prior, entry])
4712
4713 const gate = gateChannelServer(
4714 serverName,
4715 connection.capabilities,
4716 pluginSource,
4717 )
4718 if (gate.action === 'skip') {
4719 // Rollback — only remove the entry we appended.

Callers 1

runHeadlessStreamingFunction · 0.85

Calls 12

featureFunction · 0.85
respondErrorFunction · 0.85
parsePluginIdentifierFunction · 0.85
getAllowedChannelsFunction · 0.85
setAllowedChannelsFunction · 0.85
gateChannelServerFunction · 0.85
logMCPDebugFunction · 0.85
logEventFunction · 0.85
enqueueFunction · 0.85
wrapChannelMessageFunction · 0.85
keysMethod · 0.80
enqueueMethod · 0.45

Tested by

no test coverage detected