Skip to content

Commit 48fb8b1

Browse files
feat(mcp): hide ask_codebase tool when no LLM providers configured (#1018)
* feat(mcp): hide ask_codebase tool when no LLM providers configured - Modified web MCP server to check configured language models before registering the ask_codebase tool - Made createMcpServer() async to support awaiting the config check - Updated standalone MCP package to check /api/models before registering ask_codebase tool - Tool is now only visible when at least one language model is configured Co-authored-by: Michael Sukkarieh <msukkari@users.noreply.github.com> * docs: add changelog entry for ask_codebase visibility change Co-authored-by: Michael Sukkarieh <msukkari@users.noreply.github.com> * revert: remove changes to deprecated packages/mcp The packages/mcp package is deprecated and should not be modified. Reverted the conditional ask_codebase registration changes from this package. Co-authored-by: Michael Sukkarieh <msukkari@users.noreply.github.com> * docs: add note about deprecated packages/mcp to AGENTS.md Co-authored-by: Michael Sukkarieh <msukkari@users.noreply.github.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Michael Sukkarieh <msukkari@users.noreply.github.com>
1 parent 6b52d37 commit 48fb8b1

File tree

4 files changed

+47
-37
lines changed

4 files changed

+47
-37
lines changed

AGENTS.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ Standard dev commands are documented in `CONTRIBUTING.md` and `package.json`. Ke
3333
- **Build deps only:** `yarn build:deps` (builds shared packages: schemas, db, shared, query-language)
3434
- **DB migrations:** `yarn dev:prisma:migrate:dev`
3535

36+
### Deprecated Packages
37+
38+
- **`packages/mcp`** - This standalone MCP package is deprecated. Do NOT modify it. MCP functionality is now handled by the web package at `packages/web/src/features/mcp/`.
39+
3640
### Non-obvious Caveats
3741

3842
- **Docker must be running** before `yarn dev`. Start it with `docker compose -f docker-compose-dev.yml up -d`. The backend will fail to connect to Redis/PostgreSQL otherwise.

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1414

1515
### Changed
1616
- Increased `SOURCEBOT_CHAT_MAX_STEP_COUNT` default from 20 to 100 to allow agents to perform more autonomous steps. [#1017](https://github.com/sourcebot-dev/sourcebot/pull/1017)
17+
- The `ask_codebase` MCP tool is now hidden when no language model providers are configured. [#1018](https://github.com/sourcebot-dev/sourcebot/pull/1018)
1718

1819
## [4.15.9] - 2026-03-17
1920

packages/web/src/app/api/(server)/mcp/route.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ export const POST = apiHandler(async (request: NextRequest) => {
7979
},
8080
});
8181

82-
const mcpServer = createMcpServer();
82+
const mcpServer = await createMcpServer();
8383
await mcpServer.connect(transport);
8484

8585
return transport.handleRequest(request);

packages/web/src/features/mcp/server.ts

Lines changed: 41 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { listRepos } from '@/app/api/(server)/repos/listReposApi';
2-
import { getConfiguredLanguageModelsInfo } from "../chat/utils.server";
2+
import { getConfiguredLanguageModels, getConfiguredLanguageModelsInfo } from "../chat/utils.server";
33
import { askCodebase } from '@/features/mcp/askCodebase';
44
import {
55
languageModelInfoSchema,
@@ -66,12 +66,15 @@ const TOOL_DESCRIPTIONS = {
6666
`,
6767
};
6868

69-
export function createMcpServer(): McpServer {
69+
export async function createMcpServer(): Promise<McpServer> {
7070
const server = new McpServer({
7171
name: 'sourcebot-mcp-server',
7272
version: SOURCEBOT_VERSION,
7373
});
7474

75+
const configuredModels = await getConfiguredLanguageModels();
76+
const hasLanguageModels = configuredModels.length > 0;
77+
7578
server.registerTool(
7679
"search_code",
7780
{
@@ -493,43 +496,45 @@ export function createMcpServer(): McpServer {
493496
}
494497
);
495498

496-
server.registerTool(
497-
"ask_codebase",
498-
{
499-
description: TOOL_DESCRIPTIONS.ask_codebase,
500-
annotations: { readOnlyHint: true },
501-
inputSchema: z.object({
502-
query: z.string().describe("The query to ask about the codebase."),
503-
repos: z.array(z.string()).optional().describe("The repositories accessible to the agent. If not provided, all repositories are accessible."),
504-
languageModel: languageModelInfoSchema.optional().describe("The language model to use. If not provided, defaults to the first model in the config."),
505-
visibility: z.enum(['PRIVATE', 'PUBLIC']).optional().describe("The visibility of the chat session. Defaults to PRIVATE for authenticated users."),
506-
}),
507-
},
508-
async (request) => {
509-
const result = await askCodebase({
510-
query: request.query,
511-
repos: request.repos,
512-
languageModel: request.languageModel,
513-
visibility: request.visibility as ChatVisibility | undefined,
514-
source: 'mcp',
515-
});
499+
if (hasLanguageModels) {
500+
server.registerTool(
501+
"ask_codebase",
502+
{
503+
description: TOOL_DESCRIPTIONS.ask_codebase,
504+
annotations: { readOnlyHint: true },
505+
inputSchema: z.object({
506+
query: z.string().describe("The query to ask about the codebase."),
507+
repos: z.array(z.string()).optional().describe("The repositories accessible to the agent. If not provided, all repositories are accessible."),
508+
languageModel: languageModelInfoSchema.optional().describe("The language model to use. If not provided, defaults to the first model in the config."),
509+
visibility: z.enum(['PRIVATE', 'PUBLIC']).optional().describe("The visibility of the chat session. Defaults to PRIVATE for authenticated users."),
510+
}),
511+
},
512+
async (request) => {
513+
const result = await askCodebase({
514+
query: request.query,
515+
repos: request.repos,
516+
languageModel: request.languageModel,
517+
visibility: request.visibility as ChatVisibility | undefined,
518+
source: 'mcp',
519+
});
516520

517-
if (isServiceError(result)) {
518-
return {
519-
content: [{ type: "text", text: `Failed to ask codebase: ${result.message}` }],
520-
};
521-
}
521+
if (isServiceError(result)) {
522+
return {
523+
content: [{ type: "text", text: `Failed to ask codebase: ${result.message}` }],
524+
};
525+
}
522526

523-
const formattedResponse = dedent`
524-
${result.answer}
527+
const formattedResponse = dedent`
528+
${result.answer}
525529
526-
---
527-
**View full research session:** ${result.chatUrl}
528-
**Model used:** ${result.languageModel.model}
529-
`;
530-
return { content: [{ type: "text", text: formattedResponse }] };
531-
}
532-
);
530+
---
531+
**View full research session:** ${result.chatUrl}
532+
**Model used:** ${result.languageModel.model}
533+
`;
534+
return { content: [{ type: "text", text: formattedResponse }] };
535+
}
536+
);
537+
}
533538

534539
return server;
535540
}

0 commit comments

Comments
 (0)