Skip to content

Commit 768864b

Browse files
plumb repo selection to grep tool
1 parent f46b563 commit 768864b

File tree

8 files changed

+47
-36
lines changed

8 files changed

+47
-36
lines changed

docs/docs/features/mcp-server.mdx

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -304,22 +304,19 @@ Pass the key as an `Authorization: Bearer <key>` header when connecting to the M
304304

305305
## Available Tools
306306

307-
### `search_code`
307+
### `grep`
308308

309-
Searches for code that matches the provided search query as a substring by default, or as a regular expression if `useRegex` is true.
309+
Searches for code matching a regular expression pattern across repositories, similar to `grep`/`ripgrep`. Always case-sensitive. Results are grouped by file and include line numbers.
310310

311311
Parameters:
312312
| Name | Required | Description |
313-
|:----------------------|:---------|:---------------------------------------------------------------------------------------------------------------------|
314-
| `query` | yes | The search pattern to match against code contents. Do not escape quotes in your query. |
315-
| `useRegex` | no | Whether to use regular expression matching. When false, substring matching is used (default: false). |
316-
| `filterByRepos` | no | Scope the search to specific repositories. |
317-
| `filterByLanguages` | no | Scope the search to specific languages. |
318-
| `filterByFilepaths` | no | Scope the search to specific filepaths. |
319-
| `caseSensitive` | no | Whether the search should be case sensitive (default: false). |
320-
| `includeCodeSnippets` | no | Whether to include code snippets in the response (default: false). |
313+
|:----------|:---------|:--------------------------------------------------------------------------------------------------------------|
314+
| `pattern` | yes | The regex pattern to search for in file contents. |
315+
| `path` | no | Directory path to scope the search to. Defaults to the repository root. |
316+
| `include` | no | File glob pattern to include in the search (e.g. `*.ts`, `*.{ts,tsx}`). |
317+
| `repo` | no | Repository name to search in. If not provided, searches all repositories. Use the full name including host (e.g. `github.com/org/repo`). |
321318
| `ref` | no | Commit SHA, branch or tag name to search on. If not provided, defaults to the default branch. |
322-
| `maxTokens` | no | The maximum number of tokens to return (default: 10000). |
319+
| `limit` | no | Maximum number of matching files to return (default: 100). |
323320

324321
### `list_repos`
325322

@@ -336,18 +333,20 @@ Parameters:
336333

337334
### `read_file`
338335

339-
Reads the source code for a given file.
336+
Reads the source code for a given file, with optional line range control for large files.
340337

341338
Parameters:
342339
| Name | Required | Description |
343-
|:-------|:---------|:-------------------------------------------------------------------------------------------------------|
340+
|:---------|:---------|:-------------------------------------------------------------------------------------------------------|
344341
| `repo` | yes | The repository name. |
345342
| `path` | yes | The path to the file. |
346343
| `ref` | no | Commit SHA, branch or tag name to fetch the source code for. If not provided, uses the default branch. |
344+
| `offset` | no | Line number to start reading from (1-indexed). Omit to start from the beginning. |
345+
| `limit` | no | Maximum number of lines to read (max: 500). Omit to read up to 500 lines. |
347346

348347
### `list_tree`
349348

350-
Lists files and directories from a repository path. Can be used as a directory listing tool (`depth: 1`) or a repo-tree tool (`depth > 1`).
349+
Lists files and directories from a repository path. Directories are shown before files at each level.
351350

352351
Parameters:
353352
| Name | Required | Description |

packages/web/src/features/chat/agent.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { readFileDefinition } from "@/features/tools/readFile";
2121
import { grepDefinition } from "@/features/tools/grep";
2222
import { Source } from "./types";
2323
import { addLineNumbers, fileReferenceToString } from "./utils";
24-
import { tools } from "./tools";
24+
import { createTools } from "./tools";
2525
import { listTreeDefinition } from "../tools";
2626

2727
const dedent = _dedent.withOptions({ alignValues: true });
@@ -203,7 +203,7 @@ const createAgentStream = async ({
203203
providerOptions,
204204
messages: inputMessages,
205205
system: systemPrompt,
206-
tools,
206+
tools: createTools({ source: 'sourcebot-ask-agent', selectedRepos }),
207207
temperature: env.SOURCEBOT_CHAT_MODEL_TEMPERATURE,
208208
stopWhen: [
209209
stepCountIsGTE(env.SOURCEBOT_CHAT_MAX_STEP_COUNT),

packages/web/src/features/chat/tools.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,19 @@ import {
88
findSymbolDefinitionsDefinition,
99
listTreeDefinition,
1010
} from "@/features/tools";
11+
import { ToolContext } from "@/features/tools/types";
1112
import { ToolUIPart } from "ai";
1213
import { SBChatMessageToolTypes } from "./types";
1314

14-
export const tools = {
15-
[readFileDefinition.name]: toVercelAITool(readFileDefinition),
16-
[listCommitsDefinition.name]: toVercelAITool(listCommitsDefinition),
17-
[listReposDefinition.name]: toVercelAITool(listReposDefinition),
18-
[grepDefinition.name]: toVercelAITool(grepDefinition),
19-
[findSymbolReferencesDefinition.name]: toVercelAITool(findSymbolReferencesDefinition),
20-
[findSymbolDefinitionsDefinition.name]: toVercelAITool(findSymbolDefinitionsDefinition),
21-
[listTreeDefinition.name]: toVercelAITool(listTreeDefinition),
22-
} as const;
15+
export const createTools = (context: ToolContext) => ({
16+
[readFileDefinition.name]: toVercelAITool(readFileDefinition, context),
17+
[listCommitsDefinition.name]: toVercelAITool(listCommitsDefinition, context),
18+
[listReposDefinition.name]: toVercelAITool(listReposDefinition, context),
19+
[grepDefinition.name]: toVercelAITool(grepDefinition, context),
20+
[findSymbolReferencesDefinition.name]: toVercelAITool(findSymbolReferencesDefinition, context),
21+
[findSymbolDefinitionsDefinition.name]: toVercelAITool(findSymbolDefinitionsDefinition, context),
22+
[listTreeDefinition.name]: toVercelAITool(listTreeDefinition, context),
23+
});
2324

2425
export type ReadFileToolUIPart = ToolUIPart<{ read_file: SBChatMessageToolTypes['read_file'] }>;
2526
export type ListCommitsToolUIPart = ToolUIPart<{ list_commits: SBChatMessageToolTypes['list_commits'] }>;

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

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
readFileDefinition,
1919
registerMcpTool,
2020
grepDefinition,
21+
ToolContext,
2122
} from '../tools';
2223

2324
const dedent = _dedent.withOptions({ alignValues: true });
@@ -28,13 +29,17 @@ export function createMcpServer(): McpServer {
2829
version: SOURCEBOT_VERSION,
2930
});
3031

31-
registerMcpTool(server, grepDefinition);
32-
registerMcpTool(server, listCommitsDefinition);
33-
registerMcpTool(server, listReposDefinition);
34-
registerMcpTool(server, readFileDefinition);
35-
registerMcpTool(server, listTreeDefinition);
36-
registerMcpTool(server, findSymbolDefinitionsDefinition);
37-
registerMcpTool(server, findSymbolReferencesDefinition);
32+
const toolContext: ToolContext = {
33+
source: 'sourcebot-mcp-server',
34+
}
35+
36+
registerMcpTool(server, grepDefinition, toolContext);
37+
registerMcpTool(server, listCommitsDefinition, toolContext);
38+
registerMcpTool(server, listReposDefinition, toolContext);
39+
registerMcpTool(server, readFileDefinition, toolContext);
40+
registerMcpTool(server, listTreeDefinition, toolContext);
41+
registerMcpTool(server, findSymbolDefinitionsDefinition, toolContext);
42+
registerMcpTool(server, findSymbolReferencesDefinition, toolContext);
3843

3944
server.registerTool(
4045
"list_language_models",

packages/web/src/features/tools/adapters.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
import { tool } from "ai";
22
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
33
import { z } from "zod";
4-
import { ToolDefinition } from "./types";
4+
import { ToolContext, ToolDefinition } from "./types";
55

66
export function toVercelAITool<TName extends string, TShape extends z.ZodRawShape, TMetadata>(
77
def: ToolDefinition<TName, TShape, TMetadata>,
8+
context: ToolContext,
89
) {
910
return tool({
1011
description: def.description,
1112
inputSchema: def.inputSchema,
12-
execute: (input) => def.execute(input, { source: 'sourcebot-ask-agent' }),
13+
execute: (input) => def.execute(input, context),
1314
toModelOutput: ({ output }) => ({
1415
type: "content",
1516
value: [{ type: "text", text: output.output }],
@@ -20,6 +21,7 @@ export function toVercelAITool<TName extends string, TShape extends z.ZodRawShap
2021
export function registerMcpTool<TName extends string, TShape extends z.ZodRawShape, TMetadata>(
2122
server: McpServer,
2223
def: ToolDefinition<TName, TShape, TMetadata>,
24+
context: ToolContext,
2325
) {
2426
// Widening .shape to z.ZodRawShape (its base constraint) gives TypeScript a
2527
// concrete InputArgs so it can fully resolve BaseToolCallback's conditional
@@ -37,7 +39,7 @@ export function registerMcpTool<TName extends string, TShape extends z.ZodRawSha
3739
async (input) => {
3840
try {
3941
const parsed = def.inputSchema.parse(input);
40-
const result = await def.execute(parsed, { source: 'mcp' });
42+
const result = await def.execute(parsed, context);
4143
return { content: [{ type: "text" as const, text: result.output }] };
4244
} catch (error) {
4345
const message = error instanceof Error ? error.message : String(error);

packages/web/src/features/tools/grep.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ export const grepDefinition: ToolDefinition<'grep', typeof grepShape, GrepMetada
8484

8585
if (repo) {
8686
query += ` repo:${escapeStringRegexp(repo)}`;
87+
} else if (context.selectedRepos && context.selectedRepos.length > 0) {
88+
query += ` reposet:${context.selectedRepos.join(',')}`;
8789
}
8890

8991
if (ref) {

packages/web/src/features/tools/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ export * from './grep';
55
export * from './findSymbolReferences';
66
export * from './findSymbolDefinitions';
77
export * from './listTree';
8-
export * from './adapters';
8+
export * from './adapters';
9+
export * from './types';

packages/web/src/features/tools/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { z } from "zod";
22

33
export interface ToolContext {
44
source?: string;
5+
selectedRepos?: string[];
56
}
67

78
export interface ToolDefinition<

0 commit comments

Comments
 (0)