π File detail
services/mcp/channelAllowlist.ts
π― Use case
This file lives under βservices/β, which covers long-lived services (LSP, MCP, OAuth, tool execution, memory, compaction, voice, settings sync, β¦). On the API surface it exposes ChannelAllowlistEntry, getChannelAllowlist, isChannelsEnabled, and isChannelAllowlisted β mainly functions, hooks, or classes. Dependencies touch schema validation. It composes internal code from utils and analytics (relative imports). What the file header says: Approved channel plugins allowlist. --channels plugin:name@marketplace entries only register if {marketplace, plugin} is on this list. server: entries always fail (schema is plugin-only). The --dangerously-load-development-channels flag bypasses for both kinds. Lives in GrowthBoo.
Generated from folder role, exports, dependency roots, and inline comments β not hand-reviewed for every path.
π§ Inline summary
Approved channel plugins allowlist. --channels plugin:name@marketplace entries only register if {marketplace, plugin} is on this list. server: entries always fail (schema is plugin-only). The --dangerously-load-development-channels flag bypasses for both kinds. Lives in GrowthBook so it can be updated without a release. Plugin-level granularity: if a plugin is approved, all its channel servers are. Per-server gating was overengineering β a plugin that sprouts a malicious second server is already compromised, and per-server entries would break on harmless plugin refactors. The allowlist check is a pure {marketplace, plugin} comparison against the user's typed tag. The gate's separate 'marketplace' step verifies the tag matches what's actually installed before this check runs.
π€ Exports (heuristic)
ChannelAllowlistEntrygetChannelAllowlistisChannelsEnabledisChannelAllowlisted
π External import roots
Package roots from from "β¦" (relative paths omitted).
zod
π₯οΈ Source preview
/**
* Approved channel plugins allowlist. --channels plugin:name@marketplace
* entries only register if {marketplace, plugin} is on this list. server:
* entries always fail (schema is plugin-only). The
* --dangerously-load-development-channels flag bypasses for both kinds.
* Lives in GrowthBook so it can be updated without a release.
*
* Plugin-level granularity: if a plugin is approved, all its channel
* servers are. Per-server gating was overengineering β a plugin that
* sprouts a malicious second server is already compromised, and per-server
* entries would break on harmless plugin refactors.
*
* The allowlist check is a pure {marketplace, plugin} comparison against
* the user's typed tag. The gate's separate 'marketplace' step verifies
* the tag matches what's actually installed before this check runs.
*/
import { z } from 'zod/v4'
import { lazySchema } from '../../utils/lazySchema.js'
import { parsePluginIdentifier } from '../../utils/plugins/pluginIdentifier.js'
import { getFeatureValue_CACHED_MAY_BE_STALE } from '../analytics/growthbook.js'
export type ChannelAllowlistEntry = {
marketplace: string
plugin: string
}
const ChannelAllowlistSchema = lazySchema(() =>
z.array(
z.object({
marketplace: z.string(),
plugin: z.string(),
}),
),
)
export function getChannelAllowlist(): ChannelAllowlistEntry[] {
const raw = getFeatureValue_CACHED_MAY_BE_STALE<unknown>(
'tengu_harbor_ledger',
[],
)
const parsed = ChannelAllowlistSchema().safeParse(raw)
return parsed.success ? parsed.data : []
}
/**
* Overall channels on/off. Checked before any per-server gating β
* when false, --channels is a no-op and no handlers register.
* Default false; GrowthBook 5-min refresh.
*/
export function isChannelsEnabled(): boolean {
return getFeatureValue_CACHED_MAY_BE_STALE('tengu_harbor', false)
}
/**
* Pure allowlist check keyed off the connection's pluginSource β for UI
* pre-filtering so the IDE only shows "Enable channel?" for servers that will
* actually pass the gate. Not a security boundary: channel_enable still runs
* the full gate. Matches the allowlist comparison inside gateChannelServer()
* but standalone (no session/marketplace coupling β those are tautologies
* when the entry is derived from pluginSource).
*
* Returns false for undefined pluginSource (non-plugin server β can never
* match the {marketplace, plugin}-keyed ledger) and for @-less sources
* (builtin/inline β same reason).
*/
export function isChannelAllowlisted(
pluginSource: string | undefined,
): boolean {
if (!pluginSource) return false
const { name, marketplace } = parsePluginIdentifier(pluginSource)
if (!marketplace) return false
return getChannelAllowlist().some(
e => e.plugin === name && e.marketplace === marketplace,
)
}