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

Function handleChannelEnable

src/cli/print.ts:4897–5003  ·  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

4895 * interactive either.)
4896 */
4897function handleChannelEnable(
4898 requestId: string,
4899 serverName: string,
4900 connectionPool: readonly MCPServerConnection[],
4901 output: Stream<StdoutMessage>,
4902): void {
4903 const respondError = (error: string) =>
4904 output.enqueue({
4905 type: 'control_response',
4906 response: { subtype: 'error', request_id: requestId, error },
4907 })
4908
4909 if (!(feature('KAIROS') || feature('KAIROS_CHANNELS'))) {
4910 return respondError('channels feature not available in this build')
4911 }
4912
4913 // Only a 'connected' client has .capabilities and .client to register the
4914 // handler on. The pool spread at the call site matches mcp_status.
4915 const connection = connectionPool.find(
4916 c => c.name === serverName && c.type === 'connected',
4917 )
4918 if (!connection || connection.type !== 'connected') {
4919 return respondError(`server ${serverName} is not connected`)
4920 }
4921
4922 const pluginSource = connection.config.pluginSource
4923 const parsed = pluginSource ? parsePluginIdentifier(pluginSource) : undefined
4924 if (!parsed?.marketplace) {
4925 // No pluginSource or @-less source — can never pass the {plugin,
4926 // marketplace}-keyed allowlist. Short-circuit with the same reason the
4927 // gate would produce.
4928 return respondError(
4929 `server ${serverName} is not plugin-sourced; channel_enable requires a marketplace plugin`,
4930 )
4931 }
4932
4933 const entry: ChannelEntry = {
4934 kind: 'plugin',
4935 name: parsed.name,
4936 marketplace: parsed.marketplace,
4937 }
4938 // Idempotency: don't double-append on repeat enable.
4939 const prior = getAllowedChannels()
4940 const already = prior.some(
4941 e =>
4942 e.kind === 'plugin' &&
4943 e.name === entry.name &&
4944 e.marketplace === entry.marketplace,
4945 )
4946 if (!already) setAllowedChannels([...prior, entry])
4947
4948 const gate = gateChannelServer(
4949 serverName,
4950 connection.capabilities,
4951 pluginSource,
4952 )
4953 if (gate.action === 'skip') {
4954 // Rollback — only remove the entry we appended.

Callers 1

runHeadlessStreamingFunction · 0.85

Calls 12

respondErrorFunction · 0.85
parsePluginIdentifierFunction · 0.85
getAllowedChannelsFunction · 0.85
setAllowedChannelsFunction · 0.85
gateChannelServerFunction · 0.85
logMCPDebugFunction · 0.85
logEventFunction · 0.85
wrapChannelMessageFunction · 0.85
keysMethod · 0.65
enqueueFunction · 0.50
enqueueMethod · 0.45

Tested by

no test coverage detected