@@ -61,6 +61,7 @@ import {
6161} from './patterns/semantics.js' ;
6262import { CONTEXT_RESOURCE_URI , isContextResourceUri } from './resources/uri.js' ;
6363import { assessSearchQuality } from './core/search-quality.js' ;
64+ import { findSymbolReferences } from './core/symbol-references.js' ;
6465
6566analyzerRegistry . register ( new AngularAnalyzer ( ) ) ;
6667analyzerRegistry . register ( new GenericAnalyzer ( ) ) ;
@@ -331,6 +332,27 @@ const TOOLS: Tool[] = [
331332 }
332333 }
333334 } ,
335+ {
336+ name : 'get_symbol_references' ,
337+ description :
338+ 'Find concrete references to a symbol in indexed chunks. Returns total usageCount and top usage snippets.' ,
339+ inputSchema : {
340+ type : 'object' ,
341+ properties : {
342+ symbol : {
343+ type : 'string' ,
344+ description :
345+ 'Symbol name to find references for (for example: parseConfig or UserService)'
346+ } ,
347+ limit : {
348+ type : 'number' ,
349+ description : 'Maximum number of usage snippets to return (default: 10)' ,
350+ default : 10
351+ }
352+ } ,
353+ required : [ 'symbol' ]
354+ }
355+ } ,
334356 {
335357 name : 'get_component_usage' ,
336358 description :
@@ -1661,6 +1683,71 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
16611683 }
16621684 }
16631685
1686+ case 'get_symbol_references ': {
1687+ const { symbol , limit } = args as { symbol ?: unknown ; limit ?: unknown } ;
1688+ const normalizedSymbol = typeof symbol === 'string' ? symbol . trim ( ) : '' ;
1689+ const normalizedLimit =
1690+ typeof limit === 'number' && Number . isFinite ( limit ) && limit > 0 ? Math . floor ( limit ) : 10 ;
1691+
1692+ if ( ! normalizedSymbol ) {
1693+ return {
1694+ content : [
1695+ {
1696+ type : 'text' ,
1697+ text : JSON . stringify (
1698+ {
1699+ status : 'error' ,
1700+ message : "Invalid params: 'symbol' is required and must be a non-empty string."
1701+ } ,
1702+ null ,
1703+ 2
1704+ )
1705+ }
1706+ ] ,
1707+ isError : true
1708+ } ;
1709+ }
1710+
1711+ const result = await findSymbolReferences ( ROOT_PATH , normalizedSymbol , normalizedLimit ) ;
1712+
1713+ if ( result . status === 'error' ) {
1714+ return {
1715+ content : [
1716+ {
1717+ type : 'text' ,
1718+ text : JSON . stringify (
1719+ {
1720+ status : 'error' ,
1721+ symbol : normalizedSymbol ,
1722+ message : result . message
1723+ } ,
1724+ null ,
1725+ 2
1726+ )
1727+ }
1728+ ]
1729+ } ;
1730+ }
1731+
1732+ return {
1733+ content : [
1734+ {
1735+ type : 'text' ,
1736+ text : JSON . stringify (
1737+ {
1738+ status : 'success' ,
1739+ symbol : result . symbol ,
1740+ usageCount : result . usageCount ,
1741+ usages : result . usages
1742+ } ,
1743+ null ,
1744+ 2
1745+ )
1746+ }
1747+ ]
1748+ } ;
1749+ }
1750+
16641751 case 'get_component_usage ': {
16651752 const { name : componentName } = args as { name : string } ;
16661753
0 commit comments