systemprompt-runtime 0.1.22

Application runtime context and module registry for systemprompt.io
Documentation
use std::path::Path;
use systemprompt_loader::ExtensionRegistry as McpExtensionRegistry;
use systemprompt_models::{Config, ServicesConfig};
use systemprompt_traits::validation_report::ValidationError;
use systemprompt_traits::{StartupValidationReport, ValidationReport};

pub fn validate_mcp_manifests(
    config: &Config,
    services_config: &ServicesConfig,
    report: &mut StartupValidationReport,
) {
    let registry = McpExtensionRegistry::build(
        Path::new(&config.system_path),
        config.is_cloud,
        &config.bin_path,
    );

    let mut mcp_errors: Vec<ValidationError> = Vec::new();

    for (name, deployment) in &services_config.mcp_servers {
        if !deployment.enabled {
            continue;
        }
        if deployment.dev_only && config.is_cloud {
            continue;
        }

        if let Err(e) = registry.get_path(&deployment.binary) {
            mcp_errors.push(
                ValidationError::new(
                    format!("mcp_servers.{}.binary", name),
                    format!(
                        "Manifest not found for binary '{}': {}",
                        deployment.binary, e
                    ),
                )
                .with_suggestion(format!(
                    "Ensure manifest.yaml exists at extensions/mcp/{}/manifest.yaml",
                    deployment.binary
                )),
            );
        }
    }

    if mcp_errors.is_empty() {
        return;
    }

    if let Some(mcp_report) = report.domains.iter_mut().find(|d| d.domain == "mcp") {
        for error in mcp_errors {
            mcp_report.add_error(error);
        }
    } else {
        let mut mcp_report = ValidationReport::new("mcp");
        for error in mcp_errors {
            mcp_report.add_error(error);
        }
        report.add_domain(mcp_report);
    }
}