fix(mcp): require managed runtime

This commit is contained in:
Guoyu Su 2026-07-15 19:33:31 +08:00 committed by GitHub
parent 60b88c90e0
commit b9ac69f79a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 29 additions and 6 deletions

View File

@ -89,16 +89,17 @@ pub async fn ai_agent_stream(
allow_write_sql: Option<bool>,
) -> Result<String, String> {
let request = resolve_codex_cli_request(request);
let cancelled = dbx_core::ai::register_stream(&session_id).await;
let parsed_db_type: DatabaseType =
serde_json::from_str(&format!("\"{}\"", db_type)).map_err(|_| format!("Unknown database type: {db_type}"))?;
let cli_mcp_server_command = if matches!(request.config.provider, AiProvider::CodexCli) {
super::mcp::resolve_mcp_server_command().await.map(|(program, args)| CliAgentCommandSpec { program, args })
let (program, args) = super::mcp::resolve_mcp_server_command().await?;
Some(CliAgentCommandSpec { program, args })
} else {
None
};
let cancelled = dbx_core::ai::register_stream(&session_id).await;
let production_database = state
.configs
.read()

View File

@ -201,8 +201,11 @@ async fn fetch_latest_mcp_version() -> Result<String, String> {
Ok(package.version)
}
pub(crate) async fn resolve_mcp_server_command() -> Option<(String, Vec<String>)> {
tauri::async_runtime::spawn_blocking(resolve_mcp_server_command_sync).await.ok().flatten()
pub(crate) async fn resolve_mcp_server_command() -> Result<(String, Vec<String>), String> {
let command = tauri::async_runtime::spawn_blocking(resolve_mcp_server_command_sync)
.await
.map_err(|err| format!("Failed to resolve DBX MCP Server runtime: {err}"))?;
require_managed_mcp_command(command)
}
fn resolve_mcp_server_command_sync() -> Option<(String, Vec<String>)> {
@ -225,6 +228,15 @@ fn resolve_managed_mcp_command(
None
}
fn require_managed_mcp_command(command: Option<(String, Vec<String>)>) -> Result<(String, Vec<String>), String> {
command.ok_or_else(|| {
format!(
"DBX MCP Server is unavailable: no compatible Node.js ({}) installation containing {} was found. Install MCP Server from DBX settings and try again.",
MCP_MIN_NODE_VERSION_REQUIREMENT, MCP_PACKAGE_NAME
)
})
}
fn resolve_node_runtime() -> Option<NodeRuntime> {
let mut seen = HashSet::new();
let mut fallback = None;
@ -799,8 +811,9 @@ mod tests {
use super::{bash_login_script, canonical_runtime_path, NodeRuntimeCandidate};
use super::{
is_mcp_compatible_node_version, mcp_command_for_runtime, normalized_reported_path, npm_cli_candidates,
parse_node_version, prefer_runtime, prefixed_output_path, resolve_managed_mcp_command,
stdout_after_shell_marker, NodeRuntime, NodeVersion, SHELL_COMMAND_MARKER,
parse_node_version, prefer_runtime, prefixed_output_path, require_managed_mcp_command,
resolve_managed_mcp_command, stdout_after_shell_marker, NodeRuntime, NodeVersion,
MCP_MIN_NODE_VERSION_REQUIREMENT, MCP_PACKAGE_NAME, SHELL_COMMAND_MARKER,
};
#[cfg(not(windows))]
use super::{shell_command_script, shell_quote};
@ -944,6 +957,15 @@ mod tests {
assert!(command.is_none());
}
#[test]
fn desktop_launch_requires_a_managed_mcp_command() {
let error = require_managed_mcp_command(None).unwrap_err();
assert!(error.contains(MCP_MIN_NODE_VERSION_REQUIREMENT));
assert!(error.contains(MCP_PACKAGE_NAME));
assert!(error.contains("DBX settings"));
}
#[test]
fn npm_cli_candidates_stay_with_the_selected_node_installation() {
let candidates = npm_cli_candidates(PathBuf::from("/runtime/node-24/bin/node").as_path());