Skip to content

Commit 2ba5a00

Browse files
committed
Merge branch 'main' of github.com:rust-mcp-stack/rust-mcp-filesystem into refactor/fs-service
2 parents 5070a17 + 3ca810a commit 2ba5a00

File tree

6 files changed

+39
-27
lines changed

6 files changed

+39
-27
lines changed

rust-toolchain.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
[toolchain]
2-
channel = "1.88.0"
2+
channel = "1.89.0"
33
components = ["rustfmt", "clippy"]

src/fs_service/utils.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,11 @@ pub fn normalize_path(path: &Path) -> PathBuf {
7777
}
7878

7979
pub fn expand_home(path: PathBuf) -> PathBuf {
80-
if let Some(home_dir) = home_dir() {
81-
if path.starts_with("~") {
82-
let stripped_path = path.strip_prefix("~").unwrap_or(&path);
83-
return home_dir.join(stripped_path);
84-
}
80+
if let Some(home_dir) = home_dir()
81+
&& path.starts_with("~")
82+
{
83+
let stripped_path = path.strip_prefix("~").unwrap_or(&path);
84+
return home_dir.join(stripped_path);
8585
}
8686
path
8787
}

src/handler.rs

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -70,23 +70,29 @@ impl FileSystemHandler {
7070
}
7171

7272
pub(crate) async fn update_allowed_directories(&self, runtime: Arc<dyn McpServer>) {
73-
// if client does not support roots
73+
// return if roots_support is not enabled
74+
if !self.mcp_roots_support {
75+
return;
76+
}
77+
7478
let allowed_directories = self.fs_service.allowed_directories().await;
79+
// if client does NOT support roots
7580
if !runtime.client_supports_root_list().unwrap_or(false) {
81+
// use allowed directories from command line
7682
if !allowed_directories.is_empty() {
77-
let _ = runtime.stderr_message(format!("Client does not support MCP Roots, using allowed directories set from server args:\n{}", allowed_directories
78-
.iter()
79-
.map(|p| p.display().to_string())
80-
.collect::<Vec<String>>()
81-
.join(",\n"))).await;
83+
// display message only if mcp_roots_support is enabled, otherwise this message will be redundant
84+
if self.mcp_roots_support {
85+
let _ = runtime.stderr_message("Client does not support MCP Roots. Allowed directories passed from command-line will be used.".to_string()).await;
86+
}
8287
} else {
83-
// let message = "Server cannot operate: No allowed directories available. Server was started without command-line directories and client either does not support MCP roots protocol or provided empty roots. Please either: 1) Start server with directory arguments, or 2) Use a client that supports MCP roots protocol and provides valid root directories.";
88+
// root lists not supported AND allowed directories are empty
8489
let message = "Server cannot operate: No allowed directories available. Server was started without command-line directories and client does not support MCP roots protocol. Please either: 1) Start server with directory arguments, or 2) Use a client that supports MCP roots protocol and provides valid root directories.";
8590
let _ = runtime.stderr_message(message.to_string()).await;
91+
std::process::exit(1); // exit the server
8692
}
8793
} else {
94+
// client supports roots
8895
let fs_service = self.fs_service.clone();
89-
let mcp_roots_support = self.mcp_roots_support;
9096
// retrieve roots from the client and update the allowed directories accordingly
9197
let roots = match runtime.clone().list_roots(None).await {
9298
Ok(roots_result) => roots_result.roots,
@@ -111,7 +117,7 @@ impl FileSystemHandler {
111117
}
112118
};
113119

114-
if valid_roots.is_empty() && !mcp_roots_support {
120+
if valid_roots.is_empty() {
115121
let message = if allowed_directories.is_empty() {
116122
"Server cannot operate: No allowed directories available. Server was started without command-line directories and client provided empty roots. Please either: 1) Start server with directory arguments, or 2) Use a client that supports MCP roots protocol and provides valid root directories."
117123
} else {
@@ -120,7 +126,6 @@ impl FileSystemHandler {
120126
let _ = runtime.stderr_message(message.to_string()).await;
121127
} else {
122128
let num_valid_roots = valid_roots.len();
123-
124129
fs_service.update_allowed_paths(valid_roots).await;
125130
let message = format!(
126131
"Updated allowed directories from MCP roots: {num_valid_roots} valid directories",
@@ -142,7 +147,14 @@ impl ServerHandler for FileSystemHandler {
142147
_notification: RootsListChangedNotification,
143148
runtime: Arc<dyn McpServer>,
144149
) -> std::result::Result<(), RpcError> {
145-
self.update_allowed_directories(runtime).await;
150+
if self.mcp_roots_support {
151+
self.update_allowed_directories(runtime).await;
152+
} else {
153+
let message =
154+
"Skipping ROOTS client updates, server launched without the --enable-roots flag."
155+
.to_string();
156+
let _ = runtime.stderr_message(message).await;
157+
};
146158
Ok(())
147159
}
148160

src/tools/read_media_file.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::fs_service::FileSystemService;
99

1010
#[mcp_tool(
1111
name = "read_media_file",
12-
title="Read an Image or Audio file",
12+
title="Read a media (Image/Audio) file",
1313
description = concat!("Reads an image or audio file and returns its Base64-encoded content along with the corresponding MIME type. ",
1414
"The max_bytes argument could be used to enforce an upper limit on the size of a file to read ",
1515
"if the media file exceeds this limit, the operation will return an error instead of reading the media file. ",

src/tools/search_files_content.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rust_mcp_sdk::schema::{CallToolResult, schema_utils::CallToolError};
66
use std::fmt::Write;
77
#[mcp_tool(
88
name = "search_files_content",
9-
title="Move files content",
9+
title="Search files content",
1010
description = concat!("Searches for text or regex patterns in the content of files matching matching a GLOB pattern.",
1111
"Returns detailed matches with file path, line number, column number and a preview of matched text.",
1212
"By default, it performs a literal text search; if the 'is_regex' parameter is set to true, it performs a regular expression (regex) search instead.",

tests/test_tools.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -147,16 +147,16 @@ async fn ensure_tools_duplication() {
147147
duplicate_names.push(t.name.to_string());
148148
}
149149

150-
if let Some(title) = t.title {
151-
if !titles.insert(title.to_string()) {
152-
duplicate_titles.push(title.to_string());
153-
}
150+
if let Some(title) = t.title
151+
&& !titles.insert(title.to_string())
152+
{
153+
duplicate_titles.push(title.to_string());
154154
}
155155

156-
if let Some(description) = t.description {
157-
if !descriptions.insert(description.to_string()) {
158-
duplicate_descriptions.push(description.to_string());
159-
}
156+
if let Some(description) = t.description
157+
&& !descriptions.insert(description.to_string())
158+
{
159+
duplicate_descriptions.push(description.to_string());
160160
}
161161
}
162162

0 commit comments

Comments
 (0)