@@ -141,6 +141,16 @@ fn configure_bash(args: &Args, mode: CliMode) -> bashkit::BashBuilder {
141141
142142 #[ cfg( feature = "realfs" ) ]
143143 {
144+ // THREAT[TM-ESC-030]: Warn when --mount-rw is used in MCP mode — LLM agents
145+ // get read-write access to the host filesystem, breaking the sandbox boundary.
146+ if mode == CliMode :: Mcp && !args. mount_rw . is_empty ( ) {
147+ eprintln ! (
148+ "WARNING: --mount-rw in MCP mode gives LLM agents read-write access to host files."
149+ ) ;
150+ eprintln ! (
151+ " This breaks the sandbox boundary. Use --mount-ro for safer access."
152+ ) ;
153+ }
144154 builder = apply_real_mounts ( builder, & args. mount_ro , & args. mount_rw ) ;
145155 }
146156
@@ -514,6 +524,28 @@ mod tests {
514524 assert_eq ! ( content, "result\n " ) ;
515525 }
516526
527+ #[ cfg( feature = "realfs" ) ]
528+ #[ test]
529+ fn mount_rw_mcp_mode_emits_warning ( ) {
530+ // THREAT[TM-ESC-030]: Verify warning is emitted when --mount-rw is used with MCP mode.
531+ let args = Args :: parse_from ( [ "bashkit" , "--mount-rw" , "/tmp" , "mcp" ] ) ;
532+ assert_eq ! ( cli_mode( & args) , CliMode :: Mcp ) ;
533+ assert ! ( !args. mount_rw. is_empty( ) ) ;
534+ // configure_bash emits the warning to stderr; verify it doesn't panic
535+ // and the builder still succeeds (mounts are still applied).
536+ let _builder = configure_bash ( & args, CliMode :: Mcp ) ;
537+ }
538+
539+ #[ cfg( feature = "realfs" ) ]
540+ #[ test]
541+ fn mount_ro_mcp_mode_no_warning ( ) {
542+ // Read-only mounts in MCP mode should not trigger a warning.
543+ let args = Args :: parse_from ( [ "bashkit" , "--mount-ro" , "/tmp" , "mcp" ] ) ;
544+ assert_eq ! ( cli_mode( & args) , CliMode :: Mcp ) ;
545+ assert ! ( args. mount_rw. is_empty( ) ) ;
546+ let _builder = configure_bash ( & args, CliMode :: Mcp ) ;
547+ }
548+
517549 #[ test]
518550 fn panic_message_str_payload ( ) {
519551 let msg = format_panic_message ( & "something went wrong" as & dyn std:: any:: Any ) ;
0 commit comments