@@ -53,8 +53,12 @@ private ConfigUtils() {}
5353 .serializeTypeInDocuments (false )
5454 .build ();
5555
56+ private static final String OS = System .getProperty ("os.name" ).toLowerCase ();
57+ private static final boolean WINDOWS = OS .contains ("windows" );
58+
5659 private static final Path CONFIG_DIR = resolveFromHomeDir (".config" , "smithy-mcp" );
5760 private static final Path BUNDLE_DIR = CONFIG_DIR .resolve ("bundles" );
61+ private static final Path SHIMS_DIR = CONFIG_DIR .resolve ("mcp-servers" );
5862 private static final Path CONFIG_PATH = CONFIG_DIR .resolve ("config.json" );
5963
6064 private static final DefaultConfigProvider DEFAULT_CONFIG_PROVIDER ;
@@ -63,6 +67,7 @@ private ConfigUtils() {}
6367 try {
6468 ensureDirectoryExists (CONFIG_DIR );
6569 ensureDirectoryExists (BUNDLE_DIR );
70+ ensureDirectoryExists (SHIMS_DIR );
6671 } catch (IOException e ) {
6772 throw new RuntimeException (e );
6873 }
@@ -169,6 +174,8 @@ public static void removeMcpBundle(Config currentConfig, String bundleName) thro
169174 updateConfig (newConfig );
170175 var bundleFile = getBundleFileLocation (bundleName );
171176 Files .deleteIfExists (bundleFile );
177+ // Remove wrapper script if it exists
178+ removeWrapperScript (bundleName );
172179 }
173180
174181 public static void addToClientConfigs (Config config , String name , Set <String > clients , McpServerConfig serverConfig )
@@ -333,4 +340,110 @@ private static String captureProcessOutput(Process process) throws IOException {
333340 return in .lines ().collect (Collectors .joining (System .lineSeparator ()));
334341 }
335342 }
343+
344+ public static void createWrapperScript (String bundleName ) throws IOException {
345+ Path scriptPath = SHIMS_DIR .resolve (bundleName );
346+ String scriptContent = createScriptContent (bundleName );
347+
348+ Files .writeString (scriptPath , scriptContent , StandardOpenOption .CREATE , StandardOpenOption .TRUNCATE_EXISTING );
349+ scriptPath .toFile ().setExecutable (true );
350+ }
351+
352+ private static String createScriptContent (String bundleName ) {
353+ if (WINDOWS ) {
354+ return "@echo off\n mcp-registry start-server " + bundleName + " %*\n " ;
355+ } else {
356+ return "#!/bin/bash\n exec mcp-registry start-server " + bundleName + " \" $@\" \n " ;
357+ }
358+ }
359+
360+ public static void removeWrapperScript (String bundleName ) throws IOException {
361+ Path scriptPath = SHIMS_DIR .resolve (bundleName );
362+ Files .deleteIfExists (scriptPath );
363+ }
364+
365+ public static boolean isMcpServersDirInPath () {
366+ String pathEnv = System .getenv ("PATH" );
367+ if (pathEnv == null ) {
368+ return false ;
369+ }
370+
371+ String shimsDirStr = SHIMS_DIR .toAbsolutePath ().toString ();
372+ return pathEnv .contains (shimsDirStr );
373+ }
374+
375+ public static void ensureMcpServersDirInPath () {
376+ if (isMcpServersDirInPath ()) {
377+ return ;
378+ }
379+
380+ String shimsDirStr = SHIMS_DIR .toAbsolutePath ().toString ();
381+
382+ if (WINDOWS ) {
383+ printWindowsPathInstructions (shimsDirStr );
384+ } else {
385+ if (!tryAddToShellConfigs (shimsDirStr )) {
386+ printUnixPathInstructions (shimsDirStr );
387+ }
388+ }
389+ }
390+
391+ private static boolean tryAddToShellConfigs (String shimsDirStr ) {
392+ var pathExport = "export PATH=\" " + shimsDirStr + ":$PATH\" " ;
393+ var comment = "# Added by smithy-mcp" ;
394+ var configFiles = List .of (".zshrc" , ".bashrc" , ".profile" , ".bash_profile" );
395+
396+ String addedTo = null ;
397+
398+ for (var configFile : configFiles ) {
399+ var configPath = resolveFromHomeDir (configFile );
400+
401+ if (Files .exists (configPath )) {
402+ try {
403+ // Check if already present
404+ var lines = Files .readAllLines (configPath , StandardCharsets .UTF_8 );
405+ boolean alreadyPresent = lines .stream ()
406+ .anyMatch (line -> line .contains (shimsDirStr ) && line .contains ("PATH" ));
407+
408+ if (!alreadyPresent ) {
409+ // Add the export statement
410+ lines .add ("" );
411+ lines .add (comment );
412+ lines .add (pathExport );
413+
414+ Files .write (configPath ,
415+ lines ,
416+ StandardCharsets .UTF_8 ,
417+ StandardOpenOption .WRITE ,
418+ StandardOpenOption .TRUNCATE_EXISTING );
419+
420+ System .out .println ("Added mcp-servers directory to PATH in " + configFile );
421+ addedTo = configFile ;
422+ }
423+ } catch (IOException e ) {
424+ // Continue to next config file if this one fails
425+ }
426+ }
427+ }
428+
429+ if (addedTo != null ) {
430+ System .out .println ("Please restart your shell or run 'source ~/" + configFiles + "' to reload your PATH" );
431+ return true ;
432+ }
433+ return false ;
434+ }
435+
436+ private static void printWindowsPathInstructions (String shimsDirStr ) {
437+ System .out .println ("\n To use the installed bundle as a command, add the mcp-servers directory to your PATH:" );
438+ System .out .println (" set PATH=" + shimsDirStr + ";%PATH%" );
439+ System .out .println ("Or permanently add it through System Properties > Environment Variables" );
440+ System .out .println ();
441+ }
442+
443+ private static void printUnixPathInstructions (String shimsDirStr ) {
444+ System .out .println ("\n To use the installed bundle as a command, add the mcp-servers directory to your PATH:" );
445+ System .out .println (" export PATH=\" " + shimsDirStr + ":$PATH\" " );
446+ System .out .println ("Add this line to your shell profile (~/.bashrc, ~/.zshrc, etc.) to make it permanent" );
447+ System .out .println ();
448+ }
336449}
0 commit comments