@@ -90,6 +90,13 @@ struct Cli {
9090 /// routes accept this token as workspace authentication.
9191 #[ arg( long) ]
9292 workspace_token : Option < String > ,
93+
94+ /// Enable offline / air-gapped mode. Disables the web dashboard, LLM endpoint,
95+ /// embedding endpoint, and external connectors. All core tools (remember, recall,
96+ /// search, journal, encryption) continue to function with zero network calls.
97+ /// NIST SP 800-53 SC-7 / DoD IL5+ / ICD 503 air-gapped environment support.
98+ #[ arg( long, default_value_t = false , hide = true ) ]
99+ offline : bool ,
93100}
94101
95102#[ derive( Subcommand ) ]
@@ -203,6 +210,11 @@ enum Commands {
203210 /// Token required for cross-workspace access (v1.2.0)
204211 #[ arg( long) ]
205212 workspace_token : Option < String > ,
213+
214+ /// Enable offline / air-gapped mode. Disables web dashboard, LLM,
215+ /// embedding, and connectors. NIST SP 800-53 SC-7 / DoD IL5+ support.
216+ #[ arg( long, default_value_t = false , hide = true ) ]
217+ offline : bool ,
206218 } ,
207219
208220 /// Migrate a v0.1.x Mimir database to v0.2.0 schema
@@ -577,6 +589,19 @@ fn main() {
577589 let db_path = db. clone ( ) ;
578590 check_legacy_db ( & db_path) ;
579591 eprintln ! ( "mimir: using database at {}" , db_path) ;
592+
593+ // Offline mode: disable network-dependent features
594+ let offline = cli. offline ;
595+ let effective_web = if offline { false } else { * web } ;
596+ let effective_llm = if offline { None } else { llm_endpoint. as_deref ( ) } ;
597+ let effective_embedding = if offline { None } else { embedding_endpoint. as_deref ( ) } ;
598+ let effective_connectors = if offline { None } else { connectors_config. as_deref ( ) } ;
599+
600+ if offline {
601+ eprintln ! ( "mimir: running in offline / air-gapped mode" ) ;
602+ eprintln ! ( "mimir: web dashboard, LLM, embedding, and connectors disabled" ) ;
603+ }
604+
580605 let mut database = match db:: Database :: open ( & db_path) {
581606 Ok ( db) => db,
582607 Err ( e) => {
@@ -593,13 +618,13 @@ fn main() {
593618 }
594619
595620 // Configure LLM for mimir_ask if endpoint is provided
596- if let Some ( ref endpoint) = llm_endpoint {
621+ if let Some ( ref endpoint) = effective_llm {
597622 database. set_llm (
598623 true ,
599624 endpoint,
600625 llm_model,
601626 llm_api_key. as_deref ( ) ,
602- embedding_endpoint . as_deref ( ) ,
627+ effective_embedding ,
603628 ) ;
604629 eprintln ! (
605630 "mimir: LLM enabled (endpoint: {}, model: {})" ,
@@ -614,7 +639,7 @@ fn main() {
614639 }
615640
616641 // Load connectors from YAML config if provided
617- if let Some ( ref config_path) = connectors_config {
642+ if let Some ( ref config_path) = effective_connectors {
618643 match load_connectors ( config_path) {
619644 Ok ( connectors) => {
620645 let count = connectors. len ( ) ;
@@ -629,7 +654,7 @@ fn main() {
629654 }
630655
631656 // Start web dashboard in background if requested
632- if * web {
657+ if effective_web {
633658 let web_port = * port;
634659 let web_bind_addr = web_bind. clone ( ) ;
635660 let web_key = encryption_key. clone ( ) ;
0 commit comments