Summary
When calling the MCP tool ask_codebase with an explicit languageModel parameter, the request is rejected with 400 Language model '<provider>/<model>' is not configured. — even when list_language_models clearly shows that exact model configured.
Version
- Sourcebot
v4.16.11 (Helm chart 0.1.76)
- MCP client
@sourcebot/mcp@1.0.18 (via npx -y @sourcebot/mcp@latest)
Reproduction
Config in sourcebot.json / helm values sourcebot.config:
models:
- provider: anthropic
model: claude-sonnet-4-6
displayName: Claude Sonnet 4.6
token:
env: ANTHROPIC_API_KEY
- provider: anthropic
model: claude-opus-4-7
displayName: Claude Opus 4.7 (slow, highest quality)
token:
env: ANTHROPIC_API_KEY
- Call
list_language_models via MCP — returns both models as expected:
[
{"provider":"anthropic","model":"claude-sonnet-4-6","displayName":"Claude Sonnet 4.6"},
{"provider":"anthropic","model":"claude-opus-4-7","displayName":"Claude Opus 4.7 (slow, highest quality)"}
]
- Call
ask_codebase with an explicit language model of the exact shape the tool's JSON schema requires ({provider, model}):
{
"query": "...",
"languageModel": {"provider": "anthropic", "model": "claude-opus-4-7"}
}
Result:
{"statusCode":400,"errorCode":"INVALID_REQUEST_BODY","message":"Language model 'anthropic/claude-opus-4-7' is not configured."}
Same happens for claude-sonnet-4-6 — every explicit model is rejected, regardless of which one.
ask_codebase without languageModel works fine — the implicit default (first model in config) is used correctly. So the failure is specifically in the explicit-selection path.
Root cause
getLanguageModelKey in packages/web/src/features/chat/utils.ts builds the match key from provider + model + displayName:
export const getLanguageModelKey = (model: LanguageModelInfo) => {
return `${model.provider}-${model.model}-${model.displayName}`;
}
askCodebase uses this function to match the requested model against configured models in packages/web/src/features/mcp/askCodebase.ts:
const matchingModel = configuredModels.find(
(m) => getLanguageModelKey(m) === getLanguageModelKey(requestedLanguageModel)
);
The MCP JSON schema for ask_codebase.languageModel only requires {provider, model} — displayName is not part of the schema and clients cannot provide it:
languageModel: {
provider: (required),
model: (required)
}
So at match time:
- Configured entry key:
anthropic-claude-opus-4-7-Claude Opus 4.7 (slow, highest quality)
- Requested entry key:
anthropic-claude-opus-4-7-undefined
Keys never match → 400 for any explicit selection.
Suggested fix
Either:
- Match on provider+model only in
askCodebase.ts (simplest — displayName is a cosmetic label, not an identity key):
const matchingModel = configuredModels.find(
(m) => m.provider === requestedLanguageModel.provider &&
m.model === requestedLanguageModel.model
);
- Or drop
displayName from getLanguageModelKey so the match is consistent with the externally-visible identity.
Option 1 is the minimal change that keeps getLanguageModelKey untouched if it is used elsewhere where displayName matters.
Impact
- MCP clients cannot route a specific question to a non-default model — the dropdown selection in the Web UI works because the UI presumably submits the full
LanguageModelInfo (including displayName), but the MCP tool schema intentionally does not expose displayName, so there is no workaround.
- Defaulting to the first model in config still works, so this is not a total outage, but it removes a documented MCP capability.
Happy to open a PR if helpful.
Summary
When calling the MCP tool
ask_codebasewith an explicitlanguageModelparameter, the request is rejected with400 Language model '<provider>/<model>' is not configured.— even whenlist_language_modelsclearly shows that exact model configured.Version
v4.16.11(Helm chart0.1.76)@sourcebot/mcp@1.0.18(vianpx -y @sourcebot/mcp@latest)Reproduction
Config in
sourcebot.json/ helm valuessourcebot.config:list_language_modelsvia MCP — returns both models as expected:[ {"provider":"anthropic","model":"claude-sonnet-4-6","displayName":"Claude Sonnet 4.6"}, {"provider":"anthropic","model":"claude-opus-4-7","displayName":"Claude Opus 4.7 (slow, highest quality)"} ]ask_codebasewith an explicit language model of the exact shape the tool's JSON schema requires ({provider, model}):{ "query": "...", "languageModel": {"provider": "anthropic", "model": "claude-opus-4-7"} }Result:
{"statusCode":400,"errorCode":"INVALID_REQUEST_BODY","message":"Language model 'anthropic/claude-opus-4-7' is not configured."}Same happens for
claude-sonnet-4-6— every explicit model is rejected, regardless of which one.ask_codebasewithoutlanguageModelworks fine — the implicit default (first model in config) is used correctly. So the failure is specifically in the explicit-selection path.Root cause
getLanguageModelKeyinpackages/web/src/features/chat/utils.tsbuilds the match key from provider + model + displayName:askCodebaseuses this function to match the requested model against configured models inpackages/web/src/features/mcp/askCodebase.ts:The MCP JSON schema for
ask_codebase.languageModelonly requires{provider, model}—displayNameis not part of the schema and clients cannot provide it:So at match time:
anthropic-claude-opus-4-7-Claude Opus 4.7 (slow, highest quality)anthropic-claude-opus-4-7-undefinedKeys never match → 400 for any explicit selection.
Suggested fix
Either:
askCodebase.ts(simplest —displayNameis a cosmetic label, not an identity key):displayNamefromgetLanguageModelKeyso the match is consistent with the externally-visible identity.Option 1 is the minimal change that keeps
getLanguageModelKeyuntouched if it is used elsewhere wheredisplayNamematters.Impact
LanguageModelInfo(includingdisplayName), but the MCP tool schema intentionally does not exposedisplayName, so there is no workaround.Happy to open a PR if helpful.