@@ -5,11 +5,13 @@ use std::collections::HashSet;
55use std:: fs;
66use std:: net:: SocketAddr ;
77use std:: path:: { Path , PathBuf } ;
8+ use std:: time:: Duration ;
89
910const DEFAULT_CACHE_CAPACITY : usize = 5 ;
1011const DEFAULT_MAX_RECALCS : usize = 2 ;
1112const DEFAULT_EXTENSIONS : & [ & str ] = & [ "xlsx" , "xlsm" , "xls" , "xlsb" ] ;
1213const DEFAULT_HTTP_BIND : & str = "127.0.0.1:8079" ;
14+ const DEFAULT_TOOL_TIMEOUT_MS : u64 = 30_000 ;
1315
1416#[ derive( Debug , Clone , Copy , PartialEq , Eq , ValueEnum , Serialize , Deserialize ) ]
1517#[ serde( rename_all = "lowercase" ) ]
@@ -41,6 +43,7 @@ pub struct ServerConfig {
4143 pub recalc_enabled : bool ,
4244 pub vba_enabled : bool ,
4345 pub max_concurrent_recalcs : usize ,
46+ pub tool_timeout_ms : Option < u64 > ,
4447 pub allow_overwrite : bool ,
4548}
4649
@@ -58,6 +61,7 @@ impl ServerConfig {
5861 recalc_enabled : cli_recalc_enabled,
5962 vba_enabled : cli_vba_enabled,
6063 max_concurrent_recalcs : cli_max_concurrent_recalcs,
64+ tool_timeout_ms : cli_tool_timeout_ms,
6165 allow_overwrite : cli_allow_overwrite,
6266 } = args;
6367
@@ -78,6 +82,7 @@ impl ServerConfig {
7882 recalc_enabled : file_recalc_enabled,
7983 vba_enabled : file_vba_enabled,
8084 max_concurrent_recalcs : file_max_concurrent_recalcs,
85+ tool_timeout_ms : file_tool_timeout_ms,
8186 allow_overwrite : file_allow_overwrite,
8287 } = file_config;
8388
@@ -184,6 +189,15 @@ impl ServerConfig {
184189 . unwrap_or ( DEFAULT_MAX_RECALCS )
185190 . max ( 1 ) ;
186191
192+ let tool_timeout_ms = cli_tool_timeout_ms
193+ . or ( file_tool_timeout_ms)
194+ . unwrap_or ( DEFAULT_TOOL_TIMEOUT_MS ) ;
195+ let tool_timeout_ms = if tool_timeout_ms == 0 {
196+ None
197+ } else {
198+ Some ( tool_timeout_ms)
199+ } ;
200+
187201 let allow_overwrite = cli_allow_overwrite || file_allow_overwrite. unwrap_or ( false ) ;
188202
189203 Ok ( Self {
@@ -197,6 +211,7 @@ impl ServerConfig {
197211 recalc_enabled,
198212 vba_enabled,
199213 max_concurrent_recalcs,
214+ tool_timeout_ms,
200215 allow_overwrite,
201216 } )
202217 }
@@ -246,6 +261,16 @@ impl ServerConfig {
246261 None => true ,
247262 }
248263 }
264+
265+ pub fn tool_timeout ( & self ) -> Option < Duration > {
266+ self . tool_timeout_ms . and_then ( |ms| {
267+ if ms > 0 {
268+ Some ( Duration :: from_millis ( ms) )
269+ } else {
270+ None
271+ }
272+ } )
273+ }
249274}
250275
251276#[ derive( Parser , Debug , Default , Clone ) ]
@@ -340,6 +365,15 @@ pub struct CliArgs {
340365 ) ]
341366 pub max_concurrent_recalcs : Option < usize > ,
342367
368+ #[ arg(
369+ long,
370+ env = "SPREADSHEET_MCP_TOOL_TIMEOUT_MS" ,
371+ value_name = "MS" ,
372+ help = "Tool request timeout in milliseconds (default: 30000; 0 disables)" ,
373+ value_parser = clap:: value_parser!( u64 )
374+ ) ]
375+ pub tool_timeout_ms : Option < u64 > ,
376+
343377 #[ arg(
344378 long,
345379 env = "SPREADSHEET_MCP_ALLOW_OVERWRITE" ,
@@ -360,6 +394,7 @@ struct PartialConfig {
360394 recalc_enabled : Option < bool > ,
361395 vba_enabled : Option < bool > ,
362396 max_concurrent_recalcs : Option < usize > ,
397+ tool_timeout_ms : Option < u64 > ,
363398 allow_overwrite : Option < bool > ,
364399}
365400
0 commit comments