Repository navigation
MCP ask_codebase rejects explicit languageModel: getLanguageModelKey includes displayName which the MCP schema doesn't expose #1137
Description
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 chart0.1.76) - MCP client
@sourcebot/mcp@1.0.18(vianpx -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_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)"}
]- Call
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_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 —displayNameis a cosmetic label, not an identity key):const matchingModel = configuredModels.find( (m) => m.provider === requestedLanguageModel.provider && m.model === requestedLanguageModel.model );
- Or drop
displayNamefromgetLanguageModelKeyso 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(includingdisplayName), but the MCP tool schema intentionally does not exposedisplayName, 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.
Activity
brendan-kellam commentedon Apr 20, 2026
thanks for raising
The problem with either of these approaches is that the
displayNameis needed in the case when the provider & model are the same (e.g., in the case where you have twoopus-4-7models in your config with different reasoning efforts).The

languageModelparam does accept a optionaldisplayName:Was your agent not providing the
displayNamewhen calling this tool? Perhaps we need to be more explicit in our prompts.dmitrievav commentedon Apr 26, 2026
Dug into this further. The agent cannot provide
displayName— not because of prompt wording, but because@sourcebot/mcpexplicitly strips it from the request schema:So the tool definition presented to the LLM only has
{provider, model}. There is no amount of prompt engineering that can make an agent pass a field that isn't in the schema.That said — I also noticed that
@sourcebot/mcpwas deprecated and its source deleted in #1117 (April 15), in favor of the Streamable HTTP transport at/api/mcp. So we're migrating away from the npm package anyway.The server-side fix is still needed though: when clients connect via the HTTP transport and pass
{provider, model}withoutdisplayName(which is valid per the schema), the currentgetLanguageModelKeymatch fails the same way. PR #1153 fixes that.Harsh23Kashyap commentedon Jul 2, 2026
I'd like to work on this. The provider/model lookup issue still looks reproducible on current main, and I'll open a PR shortly.
Harsh23Kashyap commentedon Jul 2, 2026
PR opened: #1414 — matches on provider+model first, requires displayName only when multiple configs share the same pair.
fix(web): disambiguate MCP language model selection for ask_codebase (s…