@@ -3032,6 +3032,117 @@ def system_caches_delete(
30323032 ce .delete_runtime_cache (language , version , image_name , dry_run )
30333033
30343034
3035+ @cli .group (
3036+ name = "mcp" ,
3037+ no_args_is_help = True ,
3038+ short_help = "Run rsconnect-python as an MCP (Model Context Protocol) server." ,
3039+ help = "Run rsconnect-python as an MCP (Model Context Protocol) server. "
3040+ "This allows AI assistants and other MCP clients to interact with "
3041+ "Posit Connect servers through standardized tool calls. "
3042+ "All rsconnect CLI commands are automatically exposed as MCP tools."
3043+ )
3044+ def mcp ():
3045+ pass
3046+
3047+
3048+ @mcp .command (
3049+ name = "server" ,
3050+ short_help = "Start the MCP server." ,
3051+ help = "Start the MCP server with the specified transport method."
3052+ )
3053+ @click .option (
3054+ "--stdio" ,
3055+ is_flag = True ,
3056+ default = True ,
3057+ help = "Use stdio transport for communication with MCP clients."
3058+ )
3059+ @click .option (
3060+ "--include" ,
3061+ help = "Comma-separated list of tool names to include in MCP exposure (if not specified, all tools are included)."
3062+ )
3063+ @click .option (
3064+ "--exclude" ,
3065+ help = "Comma-separated list of tool names to exclude from MCP exposure."
3066+ )
3067+ @click .option ("--verbose" , "-v" , count = True , help = "Enable verbose output. Use -vv for very verbose (debug) output." )
3068+ @cli_exception_handler
3069+ def mcp_server (stdio : bool , include : Optional [str ], exclude : Optional [str ], verbose : int ):
3070+ set_verbosity (verbose )
3071+
3072+ if not stdio :
3073+ raise click .UsageError ("Must specify --stdio transport method" )
3074+
3075+ try :
3076+ import asyncio
3077+
3078+ from .mcp import ClickToMCPConverter , RSConnectMCPServer
3079+
3080+ # Parse include/exclude lists
3081+ include_tools = []
3082+ exclude_tools = []
3083+
3084+ if include :
3085+ include_tools = [tool .strip () for tool in include .split ("," )]
3086+ if exclude :
3087+ exclude_tools = [tool .strip () for tool in exclude .split ("," )]
3088+
3089+ converter = ClickToMCPConverter (cli , include_tools = include_tools , exclude_tools = exclude_tools )
3090+
3091+ logger .info ("Starting MCP server with stdio transport..." )
3092+ logger .info ("Automatically discovering CLI commands as MCP tools..." )
3093+
3094+ server = RSConnectMCPServer (cli , converter )
3095+ logger .info (f"Discovered { len (server .converter .tools )} tools" )
3096+
3097+ if include_tools :
3098+ logger .info (f"Included tools: { ', ' .join (include_tools )} " )
3099+ if exclude_tools :
3100+ logger .info (f"Excluded tools: { ', ' .join (exclude_tools )} " )
3101+
3102+ asyncio .run (server .run ())
3103+
3104+ except ImportError :
3105+ click .secho (
3106+ "MCP dependencies not installed. Install with: pip install mcp" ,
3107+ fg = "red" ,
3108+ err = True
3109+ )
3110+ sys .exit (1 )
3111+ except KeyboardInterrupt :
3112+ logger .info ("MCP server stopped by user" )
3113+ except Exception as e :
3114+ logger .error (f"MCP server error: { e } \n { traceback .format_exc ()} " )
3115+ sys .exit (1 )
3116+
3117+
3118+ @mcp .command (
3119+ name = "list" ,
3120+ short_help = "List available MCP tools." ,
3121+ help = "List all CLI commands that would be exposed as MCP tools."
3122+ )
3123+ @click .option ("--verbose" , "-v" , count = True , help = "Enable verbose output. Use -vv for very verbose (debug) output." )
3124+ @cli_exception_handler
3125+ def mcp_list (verbose : int ):
3126+ set_verbosity (verbose )
3127+
3128+ try :
3129+ from .mcp import ClickToMCPConverter
3130+
3131+ converter = ClickToMCPConverter (cli )
3132+
3133+ click .echo (f"Discovered { len (converter .tools )} MCP tools:" )
3134+ for tool in converter .tools :
3135+ click .echo (f" - { tool .name } : { tool .description } " )
3136+
3137+ except ImportError :
3138+ click .secho (
3139+ "MCP dependencies not installed. Install with: pip install mcp" ,
3140+ fg = "red" ,
3141+ err = True
3142+ )
3143+ sys .exit (1 )
3144+
3145+
30353146if __name__ == "__main__" :
30363147 cli ()
30373148 click .echo ()
0 commit comments