66using System . Text ;
77using System . Text . Json ;
88using System . Text . Json . Schema ;
9+ using LangChain . Cli . Models ;
910using Microsoft . Extensions . AI ;
1011using ModelContextProtocol ;
1112using ModelContextProtocol . Client ;
1213using ModelContextProtocol . Protocol . Transport ;
1314using ModelContextProtocol . Protocol . Types ;
15+ using Tool = LangChain . Cli . Models . Tool ;
1416
1517namespace LangChain . Cli . Commands ;
1618
1719internal sealed class DoCommandHandler : ICommandHandler
1820{
1921 public Option < string > InputOption { get ; } = CommonOptions . Input ;
20- public Option < string > InputFileOption { get ; } = CommonOptions . InputFile ;
21- public Option < string > OutputFileOption { get ; } = CommonOptions . OutputFile ;
22+ public Option < FileInfo ? > InputFileOption { get ; } = CommonOptions . InputFile ;
23+ public Option < FileInfo ? > OutputFileOption { get ; } = CommonOptions . OutputFile ;
2224 public Option < bool > DebugOption { get ; } = CommonOptions . Debug ;
2325 public Option < string > ModelOption { get ; } = CommonOptions . Model ;
24- public Option < string > ProviderOption { get ; } = CommonOptions . Provider ;
25- public Option < string [ ] > ToolsOption { get ; } = new (
26+ public Option < Provider > ProviderOption { get ; } = CommonOptions . Provider ;
27+ public Option < Tool [ ] > ToolsOption { get ; } = new (
2628 aliases : [ "--tools" , "-t" ] ,
27- parseArgument : result => result . Tokens . SelectMany ( t => t . Value . Split ( ',' ) ) . ToArray ( ) ,
28- description : $ "Tools you want to use. Example: --tools={ string . Join ( "," , Formats . All ) } ") ;
29- public Option < string [ ] > DirectoriesOption { get ; } = new (
29+ description : $ "Tools you want to use - { string . Join ( ", " , Enum . GetNames < Tool > ( ) ) } .")
30+ {
31+ AllowMultipleArgumentsPerToken = true ,
32+ } ;
33+ public Option < DirectoryInfo [ ] > DirectoriesOption { get ; } = new (
3034 aliases : [ "--directories" , "-d" ] ,
31- getDefaultValue : ( ) => [ "." ] ,
35+ getDefaultValue : ( ) => [ new DirectoryInfo ( "." ) ] ,
3236 description : "Directories you want to use for filesystem." ) ;
33- public Option < string > FormatOption { get ; } = new (
37+ public Option < Format > FormatOption { get ; } = new (
3438 aliases : [ "--format" , "-f" ] ,
35- getDefaultValue : ( ) => Formats . Text ,
36- description : $ "Format of answer. Can be { string . Join ( " or " , Formats . All ) } .") ;
39+ getDefaultValue : ( ) => Format . Text ,
40+ description : "Format of answer." ) ;
3741
3842 public int Invoke ( InvocationContext context )
3943 {
@@ -43,7 +47,7 @@ public int Invoke(InvocationContext context)
4347 public async Task < int > InvokeAsync ( InvocationContext context )
4448 {
4549 var input = context . ParseResult . GetValueForOption ( InputOption ) ?? string . Empty ;
46- var inputPath = context . ParseResult . GetValueForOption ( InputFileOption ) ?? string . Empty ;
50+ var inputPath = context . ParseResult . GetValueForOption ( InputFileOption ) ;
4751 var outputPath = context . ParseResult . GetValueForOption ( OutputFileOption ) ;
4852 var debug = context . ParseResult . GetValueForOption ( DebugOption ) ;
4953 var model = context . ParseResult . GetValueForOption ( ModelOption ) ;
@@ -60,76 +64,76 @@ public async Task<int> InvokeAsync(InvocationContext context)
6064 return await McpClientFactory . CreateAsync (
6165 tool switch
6266 {
63- Tools . Filesystem => new McpServerConfig
67+ Tool . Filesystem => new McpServerConfig
6468 {
65- Id = Tools . Filesystem ,
66- Name = Tools . Filesystem ,
69+ Id = Tool . Filesystem . ToString ( ) ,
70+ Name = Tool . Filesystem . ToString ( ) ,
6771 TransportType = TransportTypes . StdIo ,
6872 TransportOptions = new Dictionary < string , string >
6973 {
7074 [ "command" ] = "npx" ,
71- [ "arguments" ] = $ "-y @modelcontextprotocol/server-filesystem { string . Join ( ' ' , directories ) } ",
75+ [ "arguments" ] = $ "-y @modelcontextprotocol/server-filesystem { string . Join ( ' ' , directories . Select ( x => x . FullName ) ) } ",
7276 } ,
7377 } ,
74- Tools . Fetch => new McpServerConfig
78+ Tool . Fetch => new McpServerConfig
7579 {
76- Id = Tools . Fetch ,
77- Name = Tools . Fetch ,
80+ Id = Tool . Fetch . ToString ( ) ,
81+ Name = Tool . Fetch . ToString ( ) ,
7882 TransportType = TransportTypes . StdIo ,
7983 TransportOptions = new Dictionary < string , string >
8084 {
8185 [ "command" ] = "docker" ,
8286 [ "arguments" ] = "run -i --rm mcp/fetch" ,
8387 } ,
8488 } ,
85- Tools . GitHub => new McpServerConfig
89+ Tool . GitHub => new McpServerConfig
8690 {
87- Id = Tools . GitHub ,
88- Name = Tools . GitHub ,
91+ Id = Tool . GitHub . ToString ( ) ,
92+ Name = Tool . GitHub . ToString ( ) ,
8993 TransportType = TransportTypes . StdIo ,
9094 TransportOptions = new Dictionary < string , string >
9195 {
9296 [ "command" ] = "docker" ,
9397 [ "arguments" ] = $ "run -i --rm -e GITHUB_PERSONAL_ACCESS_TOKEN={ Environment . GetEnvironmentVariable ( "GITHUB_TOKEN" ) } ghcr.io/github/github-mcp-server",
9498 } ,
9599 } ,
96- Tools . Git => new McpServerConfig
100+ Tool . Git => new McpServerConfig
97101 {
98- Id = Tools . Git ,
99- Name = Tools . Git ,
102+ Id = Tool . Git . ToString ( ) ,
103+ Name = Tool . Git . ToString ( ) ,
100104 TransportType = TransportTypes . StdIo ,
101105 TransportOptions = new Dictionary < string , string >
102106 {
103107 [ "command" ] = "docker" ,
104108 [ "arguments" ] = $ "run -i --rm { string . Join ( ' ' , directories . Select ( x => $ "--mount type=bind,src={ x } ,dst={ x } ") ) } mcp/git",
105109 } ,
106110 } ,
107- Tools . Puppeteer => new McpServerConfig
111+ Tool . Puppeteer => new McpServerConfig
108112 {
109- Id = Tools . Puppeteer ,
110- Name = Tools . Puppeteer ,
113+ Id = Tool . Puppeteer . ToString ( ) ,
114+ Name = Tool . Puppeteer . ToString ( ) ,
111115 TransportType = TransportTypes . StdIo ,
112116 TransportOptions = new Dictionary < string , string >
113117 {
114118 [ "command" ] = "docker" ,
115119 [ "arguments" ] = "run -i --rm --init -e DOCKER_CONTAINER=true mcp/puppeteer" ,
116120 } ,
117121 } ,
118- Tools . SequentialThinking => new McpServerConfig
122+ Tool . SequentialThinking => new McpServerConfig
119123 {
120- Id = Tools . SequentialThinking ,
121- Name = Tools . SequentialThinking ,
124+ Id = Tool . SequentialThinking . ToString ( ) ,
125+ Name = Tool . SequentialThinking . ToString ( ) ,
122126 TransportType = TransportTypes . StdIo ,
123127 TransportOptions = new Dictionary < string , string >
124128 {
125129 [ "command" ] = "docker" ,
126130 [ "arguments" ] = "run -i --rm mcp/sequentialthinking" ,
127131 } ,
128132 } ,
129- Tools . Slack => new McpServerConfig
133+ Tool . Slack => new McpServerConfig
130134 {
131- Id = Tools . Slack ,
132- Name = Tools . Slack ,
135+ Id = Tool . Slack . ToString ( ) ,
136+ Name = Tool . Slack . ToString ( ) ,
133137 TransportType = TransportTypes . StdIo ,
134138 TransportOptions = new Dictionary < string , string >
135139 {
@@ -167,7 +171,7 @@ public async Task<int> InvokeAsync(InvocationContext context)
167171 {
168172 Tools = [
169173 .. aiTools . SelectMany ( x => x ) . ToArray ( ) ,
170- .. tools . Contains ( "filesystem" )
174+ .. tools . Contains ( Tool . Filesystem )
171175 ? new [ ] { AIFunctionFactory . Create (
172176 FindFilePathsByContent ,
173177 name : "FindFilePathsByContent" ,
@@ -176,33 +180,33 @@ .. tools.Contains("filesystem")
176180 ] ,
177181 ResponseFormat = format switch
178182 {
179- Formats . Text => ChatResponseFormat . Text ,
180- Formats . Lines => ChatResponseFormatForType < StringArraySchema > ( ) ,
181- Formats . ConventionalCommit => ChatResponseFormatForType < ConventionalCommitSchema > (
183+ Format . Text => ChatResponseFormat . Text ,
184+ Format . Lines => ChatResponseFormatForType < StringArraySchema > ( ) ,
185+ Format . ConventionalCommit => ChatResponseFormatForType < ConventionalCommitSchema > (
182186 schemaName : "ConventionalCommitSchema" ,
183187 schemaDescription : "Conventional commit schema. Use this schema to generate conventional commits." ) ,
184- Formats . Markdown => ChatResponseFormatForType < MarkdownSchema > (
188+ Format . Markdown => ChatResponseFormatForType < MarkdownSchema > (
185189 schemaName : "MarkdownSchema" ,
186190 schemaDescription : "Markdown schema. Use this schema to generate markdown." ) ,
187- Formats . Json => ChatResponseFormat . Json ,
191+ Format . Json => ChatResponseFormat . Json ,
188192 _ => throw new ArgumentException ( $ "Unknown format: { format } ") ,
189193 } ,
190194 } ) . ConfigureAwait ( false ) ;
191195
192196 var output = response . Text ;
193- if ( format == Formats . Lines )
197+ if ( format == Format . Lines )
194198 {
195199 var value = JsonSerializer . Deserialize < StringArraySchema > ( response . Text ) ;
196200
197201 output = string . Join ( Environment . NewLine , value ? . Value ?? [ ] ) ;
198202 }
199- else if ( format == Formats . Markdown )
203+ else if ( format == Format . Markdown )
200204 {
201205 var value = JsonSerializer . Deserialize < MarkdownSchema > ( response . Text ) ;
202206
203207 output = value ? . Markdown ?? string . Empty ;
204208 }
205- else if ( format == Formats . ConventionalCommit )
209+ else if ( format == Format . ConventionalCommit )
206210 {
207211 var value = JsonSerializer . Deserialize < ConventionalCommitSchema > ( response . Text ) ;
208212
0 commit comments