use crate::types::SandboxConfig;
use crate::unified_sandbox::{SandboxBackend, UnifiedSandbox};
use anyhow::Result;
use std::sync::Arc;
#[cfg(feature = "javy-backend")]
use tracing::debug;
pub fn determine_sandbox_backend() -> SandboxBackend {
match std::env::var("MCP_USE_WASM")
.unwrap_or_else(|_| "auto".to_string())
.as_str()
{
"true" | "wasm" => SandboxBackend::Wasm,
"false" | "node" => SandboxBackend::NodeJs,
_ => {
let ratio = std::env::var("MCP_WASM_RATIO")
.ok()
.and_then(|v| v.parse::<f64>().ok())
.unwrap_or(0.25);
let intelligent = std::env::var("MCP_INTELLIGENT_ROUTING")
.map(|v| v.to_lowercase())
.ok()
.map(|v| v == "true" || v == "1" || v == "yes")
.unwrap_or(true);
SandboxBackend::Hybrid {
wasm_ratio: ratio.clamp(0.0, 1.0),
intelligent_routing: intelligent,
}
}
}
}
#[cfg(feature = "javy-backend")]
pub fn is_javy_plugin_valid() -> bool {
use std::path::Path;
let manifest_dir = env!("CARGO_MANIFEST_DIR");
let plugin_path = Path::new(manifest_dir).join("javy-plugin.wasm");
if let Ok(metadata) = std::fs::metadata(&plugin_path) {
if metadata.len() > 100 {
if let Ok(mut file) = std::fs::File::open(&plugin_path) {
let mut magic = [0u8; 4];
if std::io::Read::read_exact(&mut file, &mut magic).is_ok() {
if &magic == b"\0asm" {
debug!("Valid Javy plugin found ({} bytes)", metadata.len());
return true;
}
}
}
}
}
const EMBEDDED_PLUGIN: &[u8] = include_bytes!("../../javy-plugin.wasm");
if EMBEDDED_PLUGIN.len() > 100 && EMBEDDED_PLUGIN.starts_with(b"\0asm") {
debug!(
"Valid embedded Javy plugin ({} bytes)",
EMBEDDED_PLUGIN.len()
);
return true;
}
debug!(
"Javy plugin not valid ({} bytes, expected >100 bytes with WASM magic bytes)",
EMBEDDED_PLUGIN.len()
);
false
}
#[cfg(not(feature = "javy-backend"))]
#[allow(dead_code)]
pub fn is_javy_plugin_valid() -> bool {
false
}
pub fn is_wasm_sandbox_available() -> bool {
if let Ok(val) = std::env::var("MCP_USE_WASM") {
match val.to_lowercase().as_str() {
"true" | "wasm" => return true,
"false" | "node" => return false,
_ => {}
}
}
#[cfg(feature = "javy-backend")]
{
if !is_javy_plugin_valid() {
debug!("WASM sandbox may be limited due to invalid Javy plugin");
}
}
true
}
pub async fn create_sandbox(config: SandboxConfig) -> Result<Arc<UnifiedSandbox>> {
let backend = determine_sandbox_backend();
let sandbox = Arc::new(UnifiedSandbox::new(config, backend).await?);
Ok(sandbox)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[allow(unsafe_code)]
fn test_is_wasm_sandbox_available_explicit_false() {
unsafe {
std::env::set_var("MCP_USE_WASM", "false");
}
assert!(!is_wasm_sandbox_available());
unsafe {
std::env::remove_var("MCP_USE_WASM");
}
}
}