99import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js' ;
1010import { readFile } from 'node:fs/promises' ;
1111import path from 'node:path' ;
12- import type { AngularWorkspace } from '../../utilities/config' ;
12+ import { z } from 'zod' ;
13+ import { AngularWorkspace } from '../../utilities/config' ;
1314import { VERSION } from '../../utilities/version' ;
1415
1516export async function createMcpServer ( context : {
@@ -28,9 +29,12 @@ export async function createMcpServer(context: {
2829 'instructions' ,
2930 'instructions://best-practices' ,
3031 {
31- title : 'Angular System Instructions ' ,
32+ title : 'Angular Best Practices and Code Generation Guide ' ,
3233 description :
33- 'A set of instructions to help LLMs generate correct code that follows Angular best practices.' ,
34+ "A comprehensive guide detailing Angular's best practices for code generation and development. " +
35+ 'This guide should be used as a reference by an LLM to ensure any generated code ' +
36+ 'adheres to modern Angular standards, including the use of standalone components, ' +
37+ 'typed forms, modern control flow syntax, and other current conventions.' ,
3438 mimeType : 'text/markdown' ,
3539 } ,
3640 async ( ) => {
@@ -46,18 +50,43 @@ export async function createMcpServer(context: {
4650 server . registerTool (
4751 'list_projects' ,
4852 {
49- title : 'List projects ' ,
53+ title : 'List Angular Projects ' ,
5054 description :
51- 'List projects within an Angular workspace.' +
52- ' This information is read from the `angular.json` file at the root path of the Angular workspace' ,
55+ 'Lists the names of all applications and libraries defined within an Angular workspace. ' +
56+ 'It reads the `angular.json` configuration file to identify the projects. ' +
57+ 'By default, it searches from the current working directory, but a different path can be specified.' ,
58+ inputSchema : {
59+ workingDirectory : z
60+ . string ( )
61+ . optional ( )
62+ . describe (
63+ 'Optionally use a filesystem directory as the initial location to search for an Angular Workspace root path.' +
64+ ' The root path is determined by the presence of an `angular.json` file.' ,
65+ ) ,
66+ } ,
67+ annotations : {
68+ readOnlyHint : true ,
69+ } ,
5370 } ,
54- ( ) => {
55- if ( ! context . workspace ) {
71+ async ( { workingDirectory } ) => {
72+ let workspace : AngularWorkspace | undefined ;
73+ if ( ! workingDirectory || workingDirectory === context . workspace ?. basePath ) {
74+ workspace = context . workspace ;
75+ } else {
76+ try {
77+ workspace = await AngularWorkspace . load ( path . join ( workingDirectory , 'angular.json' ) ) ;
78+ } catch { }
79+ }
80+
81+ if ( ! workspace ) {
5682 return {
5783 content : [
5884 {
59- type : 'text' ,
60- text : 'Not within an Angular project.' ,
85+ type : 'text' as const ,
86+ text :
87+ 'No Angular workspace found.' +
88+ ' An `angular.json` file, which marks the root of a workspace,' +
89+ ' could not be located in the current directory or any of its parent directories.' ,
6190 } ,
6291 ] ,
6392 } ;
@@ -66,10 +95,8 @@ export async function createMcpServer(context: {
6695 return {
6796 content : [
6897 {
69- type : 'text' ,
70- text :
71- 'Projects in the Angular workspace: ' +
72- [ ...context . workspace . projects . keys ( ) ] . join ( ',' ) ,
98+ type : 'text' as const ,
99+ text : 'Projects in the Angular workspace: ' + [ ...workspace . projects . keys ( ) ] . join ( ',' ) ,
73100 } ,
74101 ] ,
75102 } ;
0 commit comments