@@ -16,10 +16,22 @@ import { DOC_SEARCH_TOOL } from './tools/doc-search';
16
16
import { FIND_EXAMPLE_TOOL } from './tools/examples' ;
17
17
import { MODERNIZE_TOOL } from './tools/modernize' ;
18
18
import { LIST_PROJECTS_TOOL } from './tools/projects' ;
19
- import { McpToolDeclaration , registerTools } from './tools/tool-registry' ;
19
+ import { AnyMcpToolDeclaration , registerTools } from './tools/tool-registry' ;
20
+
21
+ /**
22
+ * The set of tools that are enabled by default for the MCP server.
23
+ * These tools are considered stable and suitable for general use.
24
+ */
25
+ const STABLE_TOOLS = [ BEST_PRACTICES_TOOL , DOC_SEARCH_TOOL , LIST_PROJECTS_TOOL ] as const ;
26
+
27
+ /**
28
+ * The set of tools that are available but not enabled by default.
29
+ * These tools are considered experimental and may have limitations.
30
+ */
31
+ const EXPERIMENTAL_TOOLS = [ FIND_EXAMPLE_TOOL , MODERNIZE_TOOL ] as const ;
20
32
21
33
export async function createMcpServer (
22
- context : {
34
+ options : {
23
35
workspace ?: AngularWorkspace ;
24
36
readOnly ?: boolean ;
25
37
localOnly ?: boolean ;
@@ -46,51 +58,61 @@ export async function createMcpServer(
46
58
47
59
registerInstructionsResource ( server ) ;
48
60
49
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
50
- let toolDeclarations : McpToolDeclaration < any , any > [ ] = [
51
- BEST_PRACTICES_TOOL ,
52
- DOC_SEARCH_TOOL ,
53
- LIST_PROJECTS_TOOL ,
54
- ] ;
55
- const experimentalToolDeclarations = [ FIND_EXAMPLE_TOOL , MODERNIZE_TOOL ] ;
61
+ const toolDeclarations = assembleToolDeclarations ( STABLE_TOOLS , EXPERIMENTAL_TOOLS , {
62
+ ...options ,
63
+ logger,
64
+ } ) ;
56
65
57
- if ( context . readOnly ) {
66
+ await registerTools (
67
+ server ,
68
+ {
69
+ workspace : options . workspace ,
70
+ logger,
71
+ exampleDatabasePath : path . join ( __dirname , '../../../lib/code-examples.db' ) ,
72
+ } ,
73
+ toolDeclarations ,
74
+ ) ;
75
+
76
+ return server ;
77
+ }
78
+
79
+ export function assembleToolDeclarations (
80
+ stableDeclarations : readonly AnyMcpToolDeclaration [ ] ,
81
+ experimentalDeclarations : readonly AnyMcpToolDeclaration [ ] ,
82
+ options : {
83
+ readOnly ?: boolean ;
84
+ localOnly ?: boolean ;
85
+ experimentalTools ?: string [ ] ;
86
+ logger : { warn ( text : string ) : void } ;
87
+ } ,
88
+ ) : AnyMcpToolDeclaration [ ] {
89
+ let toolDeclarations = [ ...stableDeclarations ] ;
90
+
91
+ if ( options . readOnly ) {
58
92
toolDeclarations = toolDeclarations . filter ( ( tool ) => tool . isReadOnly ) ;
59
93
}
60
94
61
- if ( context . localOnly ) {
95
+ if ( options . localOnly ) {
62
96
toolDeclarations = toolDeclarations . filter ( ( tool ) => tool . isLocalOnly ) ;
63
97
}
64
98
65
- const enabledExperimentalTools = new Set ( context . experimentalTools ) ;
99
+ const enabledExperimentalTools = new Set ( options . experimentalTools ) ;
66
100
if ( process . env [ 'NG_MCP_CODE_EXAMPLES' ] === '1' ) {
67
101
enabledExperimentalTools . add ( 'find_examples' ) ;
68
102
}
69
103
70
104
if ( enabledExperimentalTools . size > 0 ) {
71
- const experimentalToolsMap = new Map (
72
- experimentalToolDeclarations . map ( ( tool ) => [ tool . name , tool ] ) ,
73
- ) ;
105
+ const experimentalToolsMap = new Map ( experimentalDeclarations . map ( ( tool ) => [ tool . name , tool ] ) ) ;
74
106
75
107
for ( const toolName of enabledExperimentalTools ) {
76
108
const tool = experimentalToolsMap . get ( toolName ) ;
77
109
if ( tool ) {
78
110
toolDeclarations . push ( tool ) ;
79
111
} else {
80
- logger . warn ( `Unknown experimental tool: ${ toolName } ` ) ;
112
+ options . logger . warn ( `Unknown experimental tool: ${ toolName } ` ) ;
81
113
}
82
114
}
83
115
}
84
116
85
- await registerTools (
86
- server ,
87
- {
88
- workspace : context . workspace ,
89
- logger,
90
- exampleDatabasePath : path . join ( __dirname , '../../../lib/code-examples.db' ) ,
91
- } ,
92
- toolDeclarations ,
93
- ) ;
94
-
95
- return server ;
117
+ return toolDeclarations ;
96
118
}
0 commit comments