fix(mcp): include portable data directory in configs
This commit is contained in:
parent
bcafc4a474
commit
8efe83aaa1
|
|
@ -1719,16 +1719,18 @@ const mcpLaunchConfig = computed<McpLaunchConfig | undefined>(() => {
|
|||
},
|
||||
};
|
||||
}
|
||||
const env = mcpStatus.value?.data_dir ? { DBX_DATA_DIR: mcpStatus.value.data_dir } : undefined;
|
||||
if (mcpStatus.value?.node_path && mcpStatus.value.script_path) {
|
||||
return {
|
||||
command: mcpStatus.value.node_path,
|
||||
args: [mcpStatus.value.script_path],
|
||||
env,
|
||||
};
|
||||
}
|
||||
if (mcpStatus.value?.bin_path) {
|
||||
return { command: mcpStatus.value.bin_path };
|
||||
return { command: mcpStatus.value.bin_path, env };
|
||||
}
|
||||
return undefined;
|
||||
return env ? { command: "dbx-mcp-server", env } : undefined;
|
||||
});
|
||||
|
||||
const mcpJsonRecommendedConfig = computed(() => buildMcpJsonConfig(mcpLaunchConfig.value));
|
||||
|
|
|
|||
|
|
@ -31,11 +31,12 @@ describe("MCP config templates", () => {
|
|||
const nodeLaunch = {
|
||||
command: "C:\\Program Files\\nodejs\\node.exe",
|
||||
args: ["C:\\Users\\supervisor\\AppData\\Roaming\\npm\\node_modules\\@dbx-app\\mcp-server\\bin\\dbx-mcp-server.js"],
|
||||
env: { DBX_DATA_DIR: "D:\\GreenSoft\\DBX\\data" },
|
||||
};
|
||||
const nativeBinPath = "C:\\Users\\supervisor\\AppData\\Roaming\\npm\\node_modules\\@dbx-app\\mcp-win32-x64\\bin\\dbx-mcp.exe";
|
||||
|
||||
expect(JSON.parse(buildMcpTraeConfig(nodeLaunch, nativeBinPath))).toEqual({
|
||||
mcpServers: { dbx: { command: nativeBinPath } },
|
||||
mcpServers: { dbx: { command: nativeBinPath, env: nodeLaunch.env } },
|
||||
});
|
||||
expect(JSON.parse(buildMcpTraeConfig(nodeLaunch))).toEqual({
|
||||
mcpServers: { dbx: nodeLaunch },
|
||||
|
|
@ -59,6 +60,16 @@ describe("MCP config templates", () => {
|
|||
expect(buildMcpJsonConfig(launch)).not.toContain("DBX_MCP_ALLOW_WRITES");
|
||||
});
|
||||
|
||||
it("includes the portable DBX data directory in JSON and Codex configs", () => {
|
||||
const launch = {
|
||||
command: "dbx-mcp-server",
|
||||
env: { DBX_DATA_DIR: "D:\\GreenSoft\\DBX\\data" },
|
||||
};
|
||||
|
||||
expect(JSON.parse(buildMcpJsonConfig(launch)).mcpServers.dbx.env).toEqual(launch.env);
|
||||
expect(buildMcpCodexConfig(launch)).toContain('DBX_DATA_DIR = "D:\\\\GreenSoft\\\\DBX\\\\data"');
|
||||
});
|
||||
|
||||
it("keeps a deployed Web base path in DBX_WEB_URL", () => {
|
||||
expect(mcpWebBackendUrl("https://dbx.example.com", "/tools/dbx/api")).toBe("https://dbx.example.com/tools/dbx");
|
||||
});
|
||||
|
|
|
|||
|
|
@ -3288,6 +3288,7 @@ export async function checkMcpServerStatus(): Promise<import("@/lib/backend/taur
|
|||
bin_path: null,
|
||||
native_bin_path: null,
|
||||
script_path: null,
|
||||
data_dir: null,
|
||||
install_command: "npm install -g @dbx-app/mcp-server@latest --registry=https://registry.npmjs.org",
|
||||
update_command: "npm install -g @dbx-app/mcp-server@latest --registry=https://registry.npmjs.org",
|
||||
error: "MCP Server status is only available in the desktop app.",
|
||||
|
|
|
|||
|
|
@ -1897,6 +1897,7 @@ export interface McpServerStatus {
|
|||
bin_path: string | null;
|
||||
native_bin_path: string | null;
|
||||
script_path: string | null;
|
||||
data_dir: string | null;
|
||||
install_command: string;
|
||||
update_command: string;
|
||||
error: string | null;
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ export function buildMcpJsonConfig(config?: McpLaunchConfig): string {
|
|||
}
|
||||
|
||||
export function buildMcpTraeConfig(config?: McpLaunchConfig, nativeBinPath?: string): string {
|
||||
return buildMcpJsonConfig(nativeBinPath ? { command: nativeBinPath } : config);
|
||||
return buildMcpJsonConfig(nativeBinPath ? { command: nativeBinPath, env: config?.env } : config);
|
||||
}
|
||||
|
||||
export function buildMcpVsCodeConfig(config?: McpLaunchConfig): string {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ use std::path::{Path, PathBuf};
|
|||
use std::time::Duration;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tauri::{AppHandle, Manager};
|
||||
|
||||
const MCP_PACKAGE_NAME: &str = "@dbx-app/mcp-server";
|
||||
const MCP_LATEST_URL: &str = "https://registry.npmjs.org/@dbx-app%2fmcp-server/latest";
|
||||
|
|
@ -26,6 +27,7 @@ pub struct McpServerStatus {
|
|||
pub bin_path: Option<String>,
|
||||
pub native_bin_path: Option<String>,
|
||||
pub script_path: Option<String>,
|
||||
pub data_dir: Option<String>,
|
||||
pub install_command: String,
|
||||
pub update_command: String,
|
||||
pub error: Option<String>,
|
||||
|
|
@ -178,7 +180,9 @@ struct NodeVersion {
|
|||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn check_mcp_server_status() -> Result<McpServerStatus, String> {
|
||||
pub async fn check_mcp_server_status(app: AppHandle) -> Result<McpServerStatus, String> {
|
||||
let default_data_dir = app.path().app_data_dir().map_err(|error| error.to_string())?;
|
||||
let data_dir = crate::data_dir::resolve_data_dir_with_mode(default_data_dir).custom_data_dir().map(path_string);
|
||||
let local_status = tauri::async_runtime::spawn_blocking(|| {
|
||||
let runtime = resolve_node_runtime();
|
||||
let fallback_bin = match runtime.as_ref() {
|
||||
|
|
@ -221,6 +225,7 @@ pub async fn check_mcp_server_status() -> Result<McpServerStatus, String> {
|
|||
bin_path,
|
||||
native_bin_path,
|
||||
script_path,
|
||||
data_dir,
|
||||
install_command: MCP_INSTALL_COMMAND.to_string(),
|
||||
update_command: runtime.as_ref().map(NodeRuntime::update_command).unwrap_or(MCP_INSTALL_COMMAND).to_string(),
|
||||
error,
|
||||
|
|
|
|||
|
|
@ -25,6 +25,10 @@ impl DataDirResolution {
|
|||
matches!(self.mode, DataDirMode::EnvOverride | DataDirMode::Portable { .. })
|
||||
}
|
||||
|
||||
pub fn custom_data_dir(&self) -> Option<&Path> {
|
||||
self.uses_custom_data_dir().then_some(self.data_dir.as_path())
|
||||
}
|
||||
|
||||
pub fn is_portable_mode(&self) -> bool {
|
||||
matches!(self.mode, DataDirMode::Portable { .. })
|
||||
}
|
||||
|
|
@ -138,6 +142,7 @@ mod tests {
|
|||
let resolution = resolve_data_dir_from_inputs(default_dir, Some(exe_dir.clone()), true, false, None);
|
||||
|
||||
assert_eq!(resolution.data_dir, exe_dir.join("data"));
|
||||
assert_eq!(resolution.custom_data_dir(), Some(resolution.data_dir.as_path()));
|
||||
assert_eq!(resolution.mode, DataDirMode::Portable { exe_dir });
|
||||
assert!(resolution.uses_custom_data_dir());
|
||||
assert!(resolution.is_portable_mode());
|
||||
|
|
@ -151,6 +156,7 @@ mod tests {
|
|||
let resolution = resolve_data_dir_from_inputs(default_dir.clone(), Some(exe_dir), true, true, None);
|
||||
|
||||
assert_eq!(resolution.data_dir, default_dir);
|
||||
assert_eq!(resolution.custom_data_dir(), None);
|
||||
assert_eq!(resolution.mode, DataDirMode::Default);
|
||||
assert!(!resolution.uses_custom_data_dir());
|
||||
assert!(!resolution.is_portable_mode());
|
||||
|
|
@ -165,6 +171,7 @@ mod tests {
|
|||
let resolution = resolve_data_dir_from_inputs(default_dir, Some(exe_dir), true, true, Some(env_dir.clone()));
|
||||
|
||||
assert_eq!(resolution.data_dir, env_dir);
|
||||
assert_eq!(resolution.custom_data_dir(), Some(resolution.data_dir.as_path()));
|
||||
assert_eq!(resolution.mode, DataDirMode::EnvOverride);
|
||||
assert!(resolution.uses_custom_data_dir());
|
||||
assert!(!resolution.is_portable_mode());
|
||||
|
|
|
|||
Loading…
Reference in New Issue