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

Function gateChannelServer

src/services/mcp/channelNotification.ts:191–316  ·  view source on GitHub ↗
(
  serverName: string,
  capabilities: ServerCapabilities | undefined,
  pluginSource: string | undefined,
)

Source from the content-addressed store, hash-verified

189 * this gate only decides whether the notification handler registers.
190 */
191export function gateChannelServer(
192 serverName: string,
193 capabilities: ServerCapabilities | undefined,
194 pluginSource: string | undefined,
195): ChannelGateResult {
196 // Channel servers declare `experimental['claude/channel']: {}` (MCP's
197 // presence-signal idiom — same as `tools: {}`). Truthy covers `{}` and
198 // `true`; absent/undefined/explicit-`false` all fail. Key matches the
199 // notification method namespace (notifications/claude/channel).
200 if (!capabilities?.experimental?.['claude/channel']) {
201 return {
202 action: 'skip',
203 kind: 'capability',
204 reason: 'server did not declare claude/channel capability',
205 }
206 }
207
208 // Overall runtime gate. After capability so normal MCP servers never hit
209 // this path. Before auth/policy so the killswitch works regardless of
210 // session state.
211 if (!isChannelsEnabled()) {
212 return {
213 action: 'skip',
214 kind: 'disabled',
215 reason: 'channels feature is not currently available',
216 }
217 }
218
219 // OAuth-only. API key users (console) are blocked — there's no
220 // channelsEnabled admin surface in console yet, so the policy opt-in
221 // flow doesn't exist for them. Drop this when console parity lands.
222 if (!getClaudeAIOAuthTokens()?.accessToken) {
223 return {
224 action: 'skip',
225 kind: 'auth',
226 reason: 'channels requires claude.ai authentication (run /login)',
227 }
228 }
229
230 // Teams/Enterprise opt-in. Managed orgs must explicitly enable channels.
231 // Default OFF — absent or false blocks. Keyed off subscription tier, not
232 // "policy settings exist" — a team org with zero configured policy keys
233 // (remote endpoint returns 404) is still a managed org and must not fall
234 // through to the unmanaged path.
235 const sub = getSubscriptionType()
236 const managed = sub === 'team' || sub === 'enterprise'
237 const policy = managed ? getSettingsForSource('policySettings') : undefined
238 if (managed && policy?.channelsEnabled !== true) {
239 return {
240 action: 'skip',
241 kind: 'policy',
242 reason:
243 'channels not enabled by org policy (set channelsEnabled: true in managed settings)',
244 }
245 }
246
247 // User-level session opt-in. A server must be explicitly listed in
248 // --channels to push inbound this session — protects against a trusted

Callers 3

handleChannelEnableFunction · 0.85
useManageMCPConnectionsFunction · 0.85

Calls 7

isChannelsEnabledFunction · 0.85
getSubscriptionTypeFunction · 0.85
getSettingsForSourceFunction · 0.85
findChannelEntryFunction · 0.85
getAllowedChannelsFunction · 0.85
parsePluginIdentifierFunction · 0.85

Tested by

no test coverage detected