From 41bacde739fad8362abb65127d18c3e5a2ab073e Mon Sep 17 00:00:00 2001 From: Mostafa Ashraf Date: Wed, 17 Dec 2025 14:25:14 +0200 Subject: [PATCH] Improve conciseness and clarity of tool descriptions for local and remote operations. --- libs/mcp/server/src/local_tools.rs | 177 +++++++++------------------- libs/mcp/server/src/remote_tools.rs | 21 ++-- 2 files changed, 61 insertions(+), 137 deletions(-) diff --git a/libs/mcp/server/src/local_tools.rs b/libs/mcp/server/src/local_tools.rs index bd442f1b..69eb082c 100644 --- a/libs/mcp/server/src/local_tools.rs +++ b/libs/mcp/server/src/local_tools.rs @@ -177,25 +177,18 @@ pub struct ViewWebPageRequest { #[tool_router(router = tool_router_local, vis = "pub")] impl ToolContainer { - #[tool( - description = "A system command execution tool that allows running shell commands with full system access on local or remote systems via SSH. + #[tool(description = "Execute shell commands locally or remotely via SSH. REMOTE EXECUTION: -- Set 'remote' parameter to 'user@host' or 'user@host:port' for SSH execution -- Use 'password' for password authentication or 'private_key_path' for key-based auth -- Automatic SSH key discovery from ~/.ssh/ (id_ed25519, id_rsa, etc.) if no credentials provided -- Examples: - * 'user@server.com' (uses default port 22 and auto-discovered keys) - * 'user@server.com:2222' with password authentication - * Remote paths: 'ssh://user@host/path' or 'user@host:/path' - -SECRET HANDLING: -- Output containing secrets will be redacted and shown as placeholders like [REDACTED_SECRET:rule-id:hash] -- You can use these placeholders in subsequent commands - they will be automatically restored to actual values before execution -- Example: If you see 'export API_KEY=[REDACTED_SECRET:api-key:abc123]', you can use '[REDACTED_SECRET:api-key:abc123]' in later commands - -If the command's output exceeds 300 lines the result will be truncated and the full output will be saved to a file in the current directory" - )] +- Set 'remote' to 'user@host' or 'user@host:port' for SSH +- Use 'password' or 'private_key_path' for auth (auto-discovers ~/.ssh keys if not provided) + +SECRET HANDLING: +- Secrets in output are redacted as [REDACTED_SECRET:rule-id:hash] +- Use these placeholders in subsequent commands - they auto-restore before execution +- Example: If output shows 'API_KEY=[REDACTED_SECRET:api-key:abc123]', use that placeholder in later commands + +Output exceeding 300 lines is truncated and saved to a file.")] pub async fn run_command( &self, ctx: RequestContext, @@ -248,37 +241,19 @@ If the command's output exceeds 300 lines the result will be truncated and the f } #[tool( - description = "Execute a shell command asynchronously in the background on LOCAL OR REMOTE systems and return immediately with task information without waiting for completion. - -REMOTE EXECUTION SUPPORT: -- Set 'remote' parameter to 'user@host' or 'user@host:port' for SSH background execution -- Use 'password' for password authentication or 'private_key_path' for key-based auth -- Automatic SSH key discovery from ~/.ssh/ if no credentials provided -- Examples: - * 'user@server.com' - Remote background task with auto-discovered keys - * 'user@server.com:2222' - Remote background task with custom port + description = "Execute a shell command asynchronously in the background on local or remote systems. Returns immediately with task info. -Use this for port-forwarding, starting servers, tailing logs, or other long-running commands that you want to monitor separately, or whenever the user wants to run a command in the background. +REMOTE EXECUTION: +- Set 'remote' to 'user@host' or 'user@host:port' for SSH background execution +- Use 'password' or 'private_key_path' for auth (auto-discovers ~/.ssh keys if not provided) -PARAMETERS: -- command: The shell command to execute (locally or remotely) -- description: Optional description of the command (not used in execution) -- timeout: Optional timeout in seconds after which the task will be terminated -- remote: Optional remote connection string for SSH execution -- password: Optional password for remote authentication -- private_key_path: Optional path to private key for remote authentication +Use for port-forwarding, servers, log tailing, or long-running commands. -RETURNS: -- task_id: Unique identifier for the background task -- status: Current task status (will be 'Running' initially) -- start_time: When the task was started +RETURNS: task_id, status ('Running' initially), start_time -SECRET HANDLING: -- Commands containing secrets will have them restored before execution -- Task output will be redacted when retrieved -- Use secret placeholders like [REDACTED_SECRET:rule-id:hash] in commands +SECRET HANDLING: Secrets are restored before execution; output is redacted when retrieved. -Use the get_all_tasks tool to monitor task progress, or the cancel_task tool to cancel a task." +Use get_all_tasks to monitor progress, cancel_task to cancel." )] pub async fn run_command_task( &self, @@ -632,29 +607,19 @@ Use this tool to check the progress and results of long-running background tasks } #[tool( - description = "View the contents of a local or remote file/directory. Can read entire files or specific line ranges. - -REMOTE FILE ACCESS: -- Use path formats: 'user@host:/path' or 'user@host#port:/path' for remote files -- IMPORTANT: Use ABSOLUTE paths for remote files/directories (e.g., '/etc/config' not 'config') -- Use 'password' for password authentication or 'private_key_path' for key-based auth -- Automatic SSH key discovery from ~/.ssh/ if no credentials provided -- Examples: - * 'user@server.com:/etc/nginx/nginx.conf' - Remote file with auto-discovered keys - * 'ssh://user@server.com/var/log/app.log' - Remote file with SSH URL format - * 'user@server.com:/home/user/documents' - Remote directory listing - * '/local/path/file.txt' - Local file (default behavior) - -For directories: -- Default behavior: Lists immediate directory contents -- With tree=true: Displays nested directory structure as a tree (limited to 3 levels deep) + description = "View contents of a local or remote file/directory. Supports line ranges. -SECRET HANDLING: -- File contents containing secrets will be redacted and shown as placeholders like [REDACTED_SECRET:rule-id:hash] -- These placeholders represent actual secret values that are safely stored for later use -- You can reference these placeholders when working with the file content +REMOTE ACCESS: +- Path format: 'user@host:/path' or 'user@host#port:/path' (use ABSOLUTE paths) +- Use 'password' or 'private_key_path' for auth (auto-discovers ~/.ssh keys if not provided) -A maximum of 300 lines will be shown at a time, the rest will be truncated." +DIRECTORIES: +- Default: Lists immediate contents +- tree=true: Nested tree structure (max 3 levels) + +SECRET HANDLING: Secrets are redacted as [REDACTED_SECRET:rule-id:hash] placeholders. + +Max 300 lines shown; rest is truncated." )] pub async fn view( &self, @@ -689,24 +654,15 @@ A maximum of 300 lines will be shown at a time, the rest will be truncated." } #[tool( - description = "Replace a specific string in a local or remote file with new text. The old_str must match exactly including whitespace and indentation. - -REMOTE FILE EDITING: -- Use path formats: 'user@host:/path' or 'user@host#port:/path' for remote files -- IMPORTANT: Use ABSOLUTE paths for remote files (e.g., '/etc/config' not 'config') -- Use 'password' for password authentication or 'private_key_path' for key-based auth -- Automatic SSH key discovery from ~/.ssh/ if no credentials provided -- Examples: - * 'user@server.com:/etc/nginx/sites-available/default' - Edit remote config - * 'ssh://user@server.com/var/www/app/config.php' - Edit remote application config - * '/local/path/file.txt' - Edit local file (default behavior) + description = "Replace a string in a local or remote file. old_str must match exactly (including whitespace). -SECRET HANDLING: -- You can use secret placeholders like [REDACTED_SECRET:rule-id:hash] in both old_str and new_str parameters -- These placeholders will be automatically restored to actual secret values before performing the replacement -- This allows you to safely work with secret values without exposing them +REMOTE EDITING: +- Path format: 'user@host:/path' or 'user@host#port:/path' (use ABSOLUTE paths) +- Use 'password' or 'private_key_path' for auth (auto-discovers ~/.ssh keys if not provided) -When replacing code, ensure the new text maintains proper syntax, indentation, and follows the codebase style." +SECRET HANDLING: Use [REDACTED_SECRET:rule-id:hash] placeholders in old_str/new_str - they auto-restore before replacement. + +Ensure new text maintains proper syntax and follows codebase style." )] pub async fn str_replace( &self, @@ -747,22 +703,15 @@ When replacing code, ensure the new text maintains proper syntax, indentation, a } #[tool( - description = "Create a new local or remote file with the specified content. Will fail if file already exists. When creating code, ensure the new text has proper syntax, indentation, and follows the codebase style. Parent directories will be created automatically if they don't exist. - -REMOTE FILE CREATION: -- Use path formats: 'user@host:/path' or 'user@host#port:/path' for remote files -- IMPORTANT: Use ABSOLUTE paths for remote files (e.g., '/tmp/script.sh' not 'script.sh') -- Use 'password' for password authentication or 'private_key_path' for key-based auth -- Automatic SSH key discovery from ~/.ssh/ if no credentials provided -- Parent directories will be created automatically on remote systems -- Examples: - * 'user@server.com:/tmp/script.sh' - Create remote script - * 'ssh://user@server.com/var/www/new-config.json' - Create remote config - * '/local/path/file.txt' - Create local file (default behavior) + description = "Create a new local or remote file with specified content. Fails if file exists. Parent directories are auto-created. -SECRET HANDLING: -- File content containing secrets will have them restored before writing to ensure functionality -- Use secret placeholders like [REDACTED_SECRET:rule-id:hash] in file_text parameter" +REMOTE CREATION: +- Path format: 'user@host:/path' or 'user@host#port:/path' (use ABSOLUTE paths) +- Use 'password' or 'private_key_path' for auth (auto-discovers ~/.ssh keys if not provided) + +SECRET HANDLING: Use [REDACTED_SECRET:rule-id:hash] placeholders - they auto-restore before writing. + +Ensure code has proper syntax and follows codebase style." )] pub async fn create( &self, @@ -934,35 +883,15 @@ The response will be truncated if it exceeds 300 lines, with the full content sa } #[tool( - description = "Remove/delete a local or remote file or directory. Files are automatically backed up before removal and can be recovered. - -REMOTE FILE REMOVAL: -- Supports SSH connections for remote file operations -- Use format: 'user@host:/path' or 'user@host#port:/path' -- IMPORTANT: Use ABSOLUTE paths for remote files (e.g., '/tmp/file.txt' not 'file.txt') -- Use 'password' for password authentication or 'private_key_path' for key-based auth -- Automatic SSH key discovery from ~/.ssh/ if no credentials provided -- Examples: - * 'user@server.com:/tmp/old-file.txt' - Remove remote file - * 'user@server.com#2222:/var/log/old-logs/' - Remove remote directory (with recursive=true) - * '/local/path/file.txt' - Remove local file (default behavior) - -DIRECTORY REMOVAL: -- Use 'recursive=true' to remove directories and their contents -- Files can be removed without the recursive flag - -BACKUP & RECOVERY: -- ALL removed files and directories are automatically backed up before deletion -- Local files: Moved to '.stakpak/session/backups/{uuid}/' on the local machine -- Remote files: Moved to '.stakpak/session/backups/{uuid}/' on the remote machine -- Backup paths are returned in XML format showing original and backup locations -- Files are moved (not copied) to backup location, making removal efficient -- Both files and entire directories can be recovered from backup locations - -SAFETY NOTES: -- Files are moved to backup location (not permanently deleted) -- Backup locations are preserved until manually cleaned up -- Use backup paths from XML output to restore files if needed" + description = "Remove/delete a local or remote file or directory. Files are safely backed up before removal. + +REMOTE REMOVAL: +- Path format: 'user@host:/path' or 'user@host#port:/path' (use ABSOLUTE paths) +- Use 'password' or 'private_key_path' for auth (auto-discovers ~/.ssh keys if not provided) + +DIRECTORIES: Use 'recursive=true' for directories with contents. + +SAFETY: Files are NOT permanently deleted - they are moved to '.stakpak/session/backups/{uuid}/'. Backup paths are returned in output for easy recovery." )] pub async fn remove( &self, diff --git a/libs/mcp/server/src/remote_tools.rs b/libs/mcp/server/src/remote_tools.rs index 6a7db7f9..c2730bf0 100644 --- a/libs/mcp/server/src/remote_tools.rs +++ b/libs/mcp/server/src/remote_tools.rs @@ -373,21 +373,16 @@ impl ToolContainer { // } #[tool( - description = "Web search for technical documentation. This includes documentation for tools, cloud providers, development frameworks, release notes, and other technical resources. searches against the url, title, description, and content of documentation chunks. -KEYWORD FORMAT REQUIREMENTS: -- Keywords should be provided as space-separated strings -- Use hyphens for compound terms (e.g., 'cloud-native', 'service-mesh') -- keywords must include version numbers if specified by the user , if not specified, use the keyword *latest* + description = "Search technical documentation for tools, cloud providers, frameworks, and release notes. -CORRECT EXAMPLES: -✅ keywords: 'kubernetes ingress nginx ssl' -✅ keywords: 'docker multi-stage build' +KEYWORD FORMAT: +- Space-separated strings, e.g., 'kubernetes ingress nginx ssl' or 'docker multi-stage build' +- Use hyphens for compound terms ('cloud-native', 'service-mesh') +- Include version numbers if specified, otherwise use 'latest' -QUERY STRATEGY GUIDANCE: -- For more fine-grained queries: Use many keywords in a single call to get highly targeted results (e.g., 'kubernetes ingress nginx ssl tls' for a specific SSL setup question) -- For broader knowledge gathering: Break down your query into multiple parallel calls with fewer keywords each to cover more ground (e.g., separate calls for 'kubernetes networking', 'kubernetes storage', 'kubernetes security' instead of cramming all topics into one call) - -If your goal requires understanding multiple distinct topics or technologies, make separate search calls rather than combining all keywords into one overly-specific search that may miss relevant documentation." +QUERY STRATEGY: +- Fine-grained queries: Use many keywords for targeted results +- Broad knowledge: Make separate calls with fewer keywords each to cover more topics" )] pub async fn search_docs( &self,