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

Function isModelAllowed

src/utils/model/modelAllowlist.ts:100–170  ·  view source on GitHub ↗
(model: string)

Source from the content-addressed store, hash-verified

98 * 3. Full model IDs ("claude-opus-4-5-20251101") — exact match only
99 */
100export function isModelAllowed(model: string): boolean {
101 const settings = getSettings_DEPRECATED() || {}
102 const { availableModels } = settings
103 if (!availableModels) {
104 return true // No restrictions
105 }
106 if (availableModels.length === 0) {
107 return false // Empty allowlist blocks all user-specified models
108 }
109
110 const resolvedModel = resolveOverriddenModel(model)
111 const normalizedModel = resolvedModel.trim().toLowerCase()
112 const normalizedAllowlist = availableModels.map(m => m.trim().toLowerCase())
113
114 // Direct match (alias-to-alias or full-name-to-full-name)
115 // Skip family aliases that have been narrowed by specific entries —
116 // e.g., "opus" in ["opus", "opus-4-5"] should NOT directly match,
117 // because the admin intends to restrict to opus 4.5 only.
118 if (normalizedAllowlist.includes(normalizedModel)) {
119 if (
120 !isModelFamilyAlias(normalizedModel) ||
121 !familyHasSpecificEntries(normalizedModel, normalizedAllowlist)
122 ) {
123 return true
124 }
125 }
126
127 // Family-level aliases in the allowlist match any model in that family,
128 // but only if no more specific entries exist for that family.
129 // e.g., ["opus"] allows all opus, but ["opus", "opus-4-5"] only allows opus 4.5.
130 for (const entry of normalizedAllowlist) {
131 if (
132 isModelFamilyAlias(entry) &&
133 !familyHasSpecificEntries(entry, normalizedAllowlist) &&
134 modelBelongsToFamily(normalizedModel, entry)
135 ) {
136 return true
137 }
138 }
139
140 // For non-family entries, do bidirectional alias resolution
141 // If model is an alias, resolve it and check if the resolved name is in the list
142 if (isModelAlias(normalizedModel)) {
143 const resolved = parseUserSpecifiedModel(normalizedModel).toLowerCase()
144 if (normalizedAllowlist.includes(resolved)) {
145 return true
146 }
147 }
148
149 // If any non-family alias in the allowlist resolves to the input model
150 for (const entry of normalizedAllowlist) {
151 if (!isModelFamilyAlias(entry) && isModelAlias(entry)) {
152 const resolved = parseUserSpecifiedModel(entry).toLowerCase()
153 if (resolved === normalizedModel) {
154 return true
155 }
156 }
157 }

Callers 4

validateModelFunction · 0.85
handleModelChangeFunction · 0.85

Calls 7

resolveOverriddenModelFunction · 0.85
isModelFamilyAliasFunction · 0.85
familyHasSpecificEntriesFunction · 0.85
modelBelongsToFamilyFunction · 0.85
isModelAliasFunction · 0.85
parseUserSpecifiedModelFunction · 0.85

Tested by

no test coverage detected