Skip to content

Commit dbf1aaf

Browse files
clydinalan-agius4
authored andcommitted
fix(@angular/cli): add snippet support to example search MCP tool
This commit enhances the `find_examples` tool by adding support for contextual snippets in the search results. Key changes: - The SQL query now uses the FTS5 `snippet()` function to generate a snippet of the matched content, with search terms highlighted. - The tool's output schema is updated with a new optional `snippet` field. - The description for the new `snippet` field is highly prescriptive, teaching the AI how to use snippets to enable more sophisticated and efficient agentic workflows, such as summarizing results for the user or performing internal evaluation before selecting the best result.
1 parent 31d4dfc commit dbf1aaf

File tree

1 file changed

+23
-2
lines changed

1 file changed

+23
-2
lines changed

packages/angular/cli/src/commands/mcp/tools/examples.ts

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,18 @@ const findExampleOutputSchema = z.object({
116116
'A complete, self-contained Angular code example in Markdown format. This should be ' +
117117
'presented to the user inside a markdown code block.',
118118
),
119+
snippet: z
120+
.string()
121+
.optional()
122+
.describe(
123+
'A contextual snippet from the content showing the matched search term. This field is ' +
124+
'critical for efficiently evaluating a result`s relevance. It enables two primary ' +
125+
'workflows:\n\n' +
126+
'1. For direct questions: You can internally review snippets to select the single best ' +
127+
'result before generating a comprehensive answer from its full `content`.\n' +
128+
'2. For ambiguous or exploratory questions: You can present a summary of titles and ' +
129+
'snippets to the user, allowing them to guide the next step.',
130+
),
119131
}),
120132
),
121133
});
@@ -196,7 +208,11 @@ async function createFindExampleHandler({ exampleDatabasePath }: McpToolContext)
196208
// Build the query dynamically
197209
const params: SQLInputValue[] = [];
198210
let sql =
199-
'SELECT title, summary, keywords, required_packages, related_concepts, related_tools, content FROM examples_fts';
211+
'SELECT title, summary, keywords, required_packages, related_concepts, related_tools, content, ' +
212+
// The `snippet` function generates a contextual snippet of the matched text.
213+
// Column 6 is the `content` column. We highlight matches with asterisks and limit the snippet size.
214+
"snippet(examples_fts, 6, '**', '**', '...', 15) AS snippet " +
215+
'FROM examples_fts';
200216
const whereClauses = [];
201217

202218
// FTS query
@@ -248,11 +264,16 @@ async function createFindExampleHandler({ exampleDatabasePath }: McpToolContext)
248264
related_concepts: JSON.parse(record['related_concepts'] || '[]') as string[],
249265
related_tools: JSON.parse(record['related_tools'] || '[]') as string[],
250266
content: record['content'],
267+
snippet: record['snippet'],
251268
};
252269
examples.push(example);
253270

254271
// Also create a more structured text output
255-
const text = `## Example: ${example.title}\n**Summary:** ${example.summary}\n\n---\n\n${example.content}`;
272+
let text = `## Example: ${example.title}\n**Summary:** ${example.summary}`;
273+
if (example.snippet) {
274+
text += `\n**Snippet:** ${example.snippet}`;
275+
}
276+
text += `\n\n---\n\n${example.content}`;
256277
textContent.push({ type: 'text' as const, text });
257278
}
258279

0 commit comments

Comments
 (0)