Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 8 additions & 48 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ license = false
eula = false

[dependencies]
rust-mcp-sdk = { version = "0.4", default-features = false, features = [
rust-mcp-sdk = { version = "0.5", default-features = false, features = [
"server",
"macros",
"2025_03_26",
"2025_06_18",
] }

thiserror = { version = "2.0" }
Expand Down
1 change: 1 addition & 0 deletions src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub fn server_details() -> InitializeResult {
server_info: Implementation {
name: "rust-mcp-filesystem".to_string(),
version: env!("CARGO_PKG_VERSION").to_string(),
title:Some("Filesystem MCP Server: fast and efficient tools for managing filesystem operations.".to_string())
},
capabilities: ServerCapabilities {
experimental: None,
Expand Down
7 changes: 4 additions & 3 deletions src/tools/create_directory.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
use std::path::Path;

use rust_mcp_sdk::macros::{mcp_tool, JsonSchema};
use rust_mcp_sdk::schema::TextContent;
use rust_mcp_sdk::schema::{schema_utils::CallToolError, CallToolResult};

use crate::fs_service::FileSystemService;

#[mcp_tool(
name = "create_directory",
title="Create Directory",
description = concat!("Create a new directory or ensure a directory exists. ",
"Can create multiple nested directories in one operation. ",
"If the directory already exists, this operation will succeed silently. ",
Expand All @@ -33,9 +35,8 @@ impl CreateDirectoryTool {
.await
.map_err(CallToolError::new)?;

Ok(CallToolResult::text_content(
Ok(CallToolResult::text_content(vec![TextContent::from(
format!("Successfully created directory {}", &params.path),
None,
))
)]))
}
}
6 changes: 5 additions & 1 deletion src/tools/directory_tree.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use rust_mcp_sdk::macros::{mcp_tool, JsonSchema};
use rust_mcp_sdk::schema::TextContent;
use rust_mcp_sdk::schema::{schema_utils::CallToolError, CallToolResult};
use serde_json::json;

Expand All @@ -7,6 +8,7 @@ use crate::fs_service::FileSystemService;

#[mcp_tool(
name = "directory_tree",
title= "Directory Tree",
description = concat!("Get a recursive tree view of files and directories as a JSON structure. ",
"Each entry includes 'name', 'type' (file/directory), and 'children' for directories. ",
"Files have no children array, while directories always have a children array (which may be empty). ",
Expand Down Expand Up @@ -47,6 +49,8 @@ impl DirectoryTreeTool {
}

let json_str = serde_json::to_string_pretty(&json!(entries)).map_err(CallToolError::new)?;
Ok(CallToolResult::text_content(json_str, None))
Ok(CallToolResult::text_content(vec![TextContent::from(
json_str,
)]))
}
}
4 changes: 3 additions & 1 deletion src/tools/edit_file.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::path::Path;

use rust_mcp_sdk::macros::{mcp_tool, JsonSchema};
use rust_mcp_sdk::schema::TextContent;
use rust_mcp_sdk::schema::{schema_utils::CallToolError, CallToolResult};

use crate::fs_service::FileSystemService;
Expand All @@ -18,6 +19,7 @@ pub struct EditOperation {

#[mcp_tool(
name = "edit_file",
title="Edit File",
description = concat!("Make line-based edits to a text file. ",
"Each edit replaces exact line sequences with new content. ",
"Returns a git-style diff showing the changes made. ",
Expand Down Expand Up @@ -53,6 +55,6 @@ impl EditFileTool {
.await
.map_err(CallToolError::new)?;

Ok(CallToolResult::text_content(diff, None))
Ok(CallToolResult::text_content(vec![TextContent::from(diff)]))
}
}
6 changes: 5 additions & 1 deletion src/tools/get_file_info.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
use std::path::Path;

use rust_mcp_sdk::macros::{mcp_tool, JsonSchema};
use rust_mcp_sdk::schema::TextContent;
use rust_mcp_sdk::schema::{schema_utils::CallToolError, CallToolResult};

use crate::fs_service::FileSystemService;

#[mcp_tool(
name = "get_file_info",
title="Get File Info",
description = concat!("Retrieve detailed metadata about a file or directory. ",
"Returns comprehensive information including size, creation time, ",
"last modified time, permissions, and type. ",
Expand All @@ -32,6 +34,8 @@ impl GetFileInfoTool {
.get_file_stats(Path::new(&params.path))
.await
.map_err(CallToolError::new)?;
Ok(CallToolResult::text_content(stats.to_string(), None))
Ok(CallToolResult::text_content(vec![TextContent::from(
stats.to_string(),
)]))
}
}
6 changes: 5 additions & 1 deletion src/tools/list_allowed_directories.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use rust_mcp_sdk::macros::{mcp_tool, JsonSchema};
use rust_mcp_sdk::schema::TextContent;
use rust_mcp_sdk::schema::{schema_utils::CallToolError, CallToolResult};

use crate::fs_service::FileSystemService;

#[mcp_tool(
name = "list_allowed_directories",
title="List Allowed Directories",
description = concat!("Returns a list of directories that the server has permission ",
"to access Subdirectories within these allowed directories are also accessible. ",
"Use this to identify which directories and their nested paths are available ",
Expand All @@ -31,6 +33,8 @@ impl ListAllowedDirectoriesTool {
.collect::<Vec<_>>()
.join("\n")
);
Ok(CallToolResult::text_content(result, None))
Ok(CallToolResult::text_content(vec![TextContent::from(
result,
)]))
}
}
6 changes: 5 additions & 1 deletion src/tools/list_directory.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
use std::path::Path;

use rust_mcp_sdk::macros::{mcp_tool, JsonSchema};
use rust_mcp_sdk::schema::TextContent;
use rust_mcp_sdk::schema::{schema_utils::CallToolError, CallToolResult};

use crate::fs_service::FileSystemService;

#[mcp_tool(
name = "list_directory",
title="List Directory",
description = concat!("Get a detailed listing of all files and directories in a specified path. ",
"Results clearly distinguish between files and directories with [FILE] and [DIR] ",
"prefixes. This tool is essential for understanding directory structure and ",
Expand Down Expand Up @@ -47,6 +49,8 @@ impl ListDirectoryTool {
})
.collect();

Ok(CallToolResult::text_content(formatted.join("\n"), None))
Ok(CallToolResult::text_content(vec![TextContent::from(
formatted.join("\n"),
)]))
}
}
6 changes: 5 additions & 1 deletion src/tools/list_directory_with_sizes.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use rust_mcp_sdk::macros::{mcp_tool, JsonSchema};
use rust_mcp_sdk::schema::TextContent;
use rust_mcp_sdk::schema::{schema_utils::CallToolError, CallToolResult};
use std::fmt::Write;
use std::path::Path;
Expand All @@ -8,6 +9,7 @@ use crate::fs_service::FileSystemService;

#[mcp_tool(
name = "list_directory_with_sizes",
title="List Directory With File Sizes",
description = concat!("Get a detailed listing of all files and directories in a specified path, including sizes. " ,
"Results clearly distinguish between files and directories with [FILE] and [DIR] prefixes. " ,
"This tool is useful for understanding directory structure and " ,
Expand Down Expand Up @@ -86,6 +88,8 @@ impl ListDirectoryWithSizesTool {
.format_directory_entries(entries)
.await
.map_err(CallToolError::new)?;
Ok(CallToolResult::text_content(output, None))
Ok(CallToolResult::text_content(vec![TextContent::from(
output,
)]))
}
}
7 changes: 4 additions & 3 deletions src/tools/move_file.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
use std::path::Path;

use rust_mcp_sdk::macros::{mcp_tool, JsonSchema};
use rust_mcp_sdk::schema::TextContent;
use rust_mcp_sdk::schema::{schema_utils::CallToolError, CallToolResult};

use crate::fs_service::FileSystemService;

#[mcp_tool(
name = "move_file",
title="Move File",
description = concat!("Move or rename files and directories. Can move files between directories ",
"and rename them in a single operation. If the destination exists, the ",
"operation will fail. Works across different directories and can be used ",
Expand Down Expand Up @@ -35,12 +37,11 @@ impl MoveFileTool {
.await
.map_err(CallToolError::new)?;

Ok(CallToolResult::text_content(
Ok(CallToolResult::text_content(vec![TextContent::from(
format!(
"Successfully moved {} to {}",
&params.source, &params.destination
),
None,
))
)]))
}
}
6 changes: 5 additions & 1 deletion src/tools/read_files.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
use std::path::Path;

use rust_mcp_sdk::macros::{mcp_tool, JsonSchema};
use rust_mcp_sdk::schema::TextContent;
use rust_mcp_sdk::schema::{schema_utils::CallToolError, CallToolResult};

use crate::fs_service::FileSystemService;

#[mcp_tool(
name = "read_file",
title="Read File",
description = concat!("Read the complete contents of a file from the file system. ",
"Handles various text encodings and provides detailed error messages if the ",
"file cannot be read. Use this tool when you need to examine the contents of ",
Expand All @@ -32,6 +34,8 @@ impl ReadFileTool {
.await
.map_err(CallToolError::new)?;

Ok(CallToolResult::text_content(content, None))
Ok(CallToolResult::text_content(vec![TextContent::from(
content,
)]))
}
}
6 changes: 5 additions & 1 deletion src/tools/read_multiple_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ use std::path::Path;

use futures::future::join_all;
use rust_mcp_sdk::macros::{mcp_tool, JsonSchema};
use rust_mcp_sdk::schema::TextContent;
use rust_mcp_sdk::schema::{schema_utils::CallToolError, CallToolResult};

use crate::fs_service::FileSystemService;

#[mcp_tool(
name = "read_multiple_files",
title="Read Multiple Files",
description = concat!("Read the contents of multiple files simultaneously. ",
"This is more efficient than reading files one by one when you need to analyze ",
"or compare multiple files. Each file's content is returned with its ",
Expand Down Expand Up @@ -49,6 +51,8 @@ impl ReadMultipleFilesTool {

let contents = join_all(content_futures).await;

Ok(CallToolResult::text_content(contents.join("\n---\n"), None))
Ok(CallToolResult::text_content(vec![TextContent::from(
contents.join("\n---\n"),
)]))
}
}
Loading