22// See LICENSE in the project root for license information.
33
44import * as path from 'path' ;
5- import { FileSystem , Import , JsonFile , JsonSchema } from '@rushstack/node-core-library' ;
5+ import { FileSystem , Import , JsonFile , type JsonObject , JsonSchema } from '@rushstack/node-core-library' ;
66import { Autoinstaller } from '@rushstack/rush-sdk/lib/logic/Autoinstaller' ;
77import { RushGlobalFolder } from '@rushstack/rush-sdk/lib/api/RushGlobalFolder' ;
88import { RushConfiguration } from '@rushstack/rush-sdk/lib/api/RushConfiguration' ;
9+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp' ;
910
1011import type { IRushMcpPlugin , RushMcpPluginFactory } from './IRushMcpPlugin' ;
1112import { RushMcpPluginSessionInternal } from './RushMcpPluginSession' ;
@@ -38,6 +39,11 @@ export interface IJsonRushMcpPlugin {
3839 * @rushstack /mcp-server will ensure this folder is installed before loading the plugin.
3940 */
4041 autoinstaller : string ;
42+
43+ /**
44+ * The name of the plugin. This is used to identify the plugin in the MCP server.
45+ */
46+ pluginName : string ;
4147}
4248
4349/**
@@ -72,9 +78,11 @@ export class RushMcpPluginLoader {
7278 JsonSchema . fromLoadedObject ( rushMcpPluginSchemaObject ) ;
7379
7480 private readonly _rushWorkspacePath : string ;
81+ private readonly _mcpServer : McpServer ;
7582
76- public constructor ( rushWorkspacePath : string ) {
83+ public constructor ( rushWorkspacePath : string , mcpServer : McpServer ) {
7784 this . _rushWorkspacePath = rushWorkspacePath ;
85+ this . _mcpServer = mcpServer ;
7886 }
7987
8088 public async loadAsync ( ) : Promise < void > {
@@ -84,7 +92,6 @@ export class RushMcpPluginLoader {
8492 ) ;
8593
8694 if ( ! ( await FileSystem . existsAsync ( rushMcpFilePath ) ) ) {
87- // Should we report an error here?
8895 return ;
8996 }
9097
@@ -135,7 +142,23 @@ export class RushMcpPluginLoader {
135142 RushMcpPluginLoader . _rushMcpPluginSchemaObject
136143 ) ;
137144
138- // TODO: Load and validate config file if defined by the manifest
145+ let rushMcpPluginOptions : JsonObject = { } ;
146+ if ( jsonManifest . configFileSchema ) {
147+ const mcpPluginSchemaFilePath : string = path . resolve (
148+ installedPluginPackageFolder ,
149+ jsonManifest . configFileSchema
150+ ) ;
151+ const mcpPluginSchema : JsonSchema = await JsonSchema . fromFile ( mcpPluginSchemaFilePath ) ;
152+ const rushMcpPluginOptionsFilePath : string = path . resolve (
153+ this . _rushWorkspacePath ,
154+ `common/config/rush-mcp/${ jsonMcpPlugin . pluginName } .json`
155+ ) ;
156+ // Example: /path/to/my-repo/common/config/rush-mcp/rush-mcp-example-plugin.json
157+ rushMcpPluginOptions = await JsonFile . loadAndValidateAsync (
158+ rushMcpPluginOptionsFilePath ,
159+ mcpPluginSchema
160+ ) ;
161+ }
139162
140163 const fullEntryPointPath : string = path . join ( installedPluginPackageFolder , jsonManifest . entryPoint ) ;
141164 let pluginFactory : RushMcpPluginFactory ;
@@ -149,12 +172,11 @@ export class RushMcpPluginLoader {
149172 throw new Error ( `Unable to load plugin entry point at ${ fullEntryPointPath } : ` + e . toString ( ) ) ;
150173 }
151174
152- const session : RushMcpPluginSessionInternal = new RushMcpPluginSessionInternal ( ) ;
175+ const session : RushMcpPluginSessionInternal = new RushMcpPluginSessionInternal ( this . _mcpServer ) ;
153176
154177 let plugin : IRushMcpPlugin ;
155178 try {
156- // TODO: Replace "{}" with the plugin's parsed config file JSON
157- plugin = pluginFactory ( session , { } ) ;
179+ plugin = pluginFactory ( session , rushMcpPluginOptions ) ;
158180 } catch ( e ) {
159181 throw new Error ( `Error invoking entry point for plugin ${ jsonManifest . pluginName } :` + e . toString ( ) ) ;
160182 }
0 commit comments