A flexible and capable cross-platform MCP server intended to be run on your own device, inspired by classic AI assistants like Apple Siri, Amazon Alexa and Google Assistant, with the power of an LLM
shell_exec allows arbitrary command execution with no input validation, no sandbox, no permission gates. Critical code injection risk if LLM is prompted to execute untrusted input.
File operations (write_file, delete_file, move_file) have no path validation visible. LLM could write to arbitrary locations or delete critical files. No path traversal protection confirmed in code excerpt.
Recommendations
Add complete output schema documentation to all 35 tools. Example for get_memories: 'Returns { memories: [ { id: int, content: string, persistent: bool, created_date: ISO8601 } ], total: int }'. This is non-negotiable for production.
Expand descriptions on 16+ minimal-description tools to 80-150 characters. Include WHEN to call and WHAT it returns. E.g., get_time: 'Returns the current time in HH:MM:SS format. Use this before time-dependent operations to avoid assuming the user's timezone.'
Add input validation visible in code or error responses. For shell_exec, return: 'This tool is disabled for safety. Use task-specific tools instead (create_file, write_file, etc.)'. For file paths, validate against a whitelist or return: 'Invalid path: must be under /allowed/directory. Got: {path}'.
Implement permission gates for high-risk tools (shell_exec, nmap, delete_file, delete_memory, empty_trash, etc.). Require explicit capability set or user confirmation. Document required scopes in tool descriptions: 'Requires scope: write:file'.
Add error recovery guidance to all tools. Examples: 'If category not found, call search_entire_database() first.' 'If file locked, try again in 1 second.' These guide LLM retry logic and prevent silent failures.
Introduce enum constraints for parameters with known values. E.g., search_web 'limit' should constrain to 1-50 (not unbounded int). memory 'persistent' is already boolean, good. Networking tools should have 'protocol' enum (tcp|udp) if applicable.
Add dry-run support to destructive tools (delete_file, delete_memory, empty_trash, shell_exec). Return 'This action cannot be undone. To confirm, call this tool again with confirm=true.' Prevents accidental destruction.
No error handling guidance visible in tool descriptions. Error messages in code (e.g., 'invalid category') do not guide LLM recovery. No recovery instructions like 'try search_users() first'.
Memory tools (store_memory, edit_memory, delete_memory) have restrictive descriptions but no clear idempotency guarantees or dry-run capability. edit_memory and delete_memory require visibility of prior get_memories() call, this constraint is enforced in description but risky.
db_rename_note_category and db_delete_note_category lack clear descriptions of consequences. No batch variants offered for common multi-item operations.
search_entire_database and search_within_memories accept free-form query strings with no validation or constraints. No regex pattern validation or injection protection visible.
No enum constraints on parameters that should have fixed options. E.g., move_multiple_files accepts arbitrary JSON structure; parameter descriptions lack format examples.
move_multiple_filessearch_web
Document tool composition chains in descriptions. E.g., 'To create a note, call db_add_note(). To see all notes, call db_get_notes(). To find a specific note, search_entire_database() first.' This reduces agent confusion and wasted discovery calls.
Cap result sizes and add pagination. If search_entire_database can return 1000+ results, cap at 50 and add next_cursor or limit parameter. Document in description: 'Returns max 50 results. Use limit parameter to reduce.'
Implement audit logging for all write/delete operations. Include: timestamp, tool name, parameters (redacted for secrets), success/failure, LLM session ID. Log output shown in tool response or hidden, spec doesn't mandate, but logging is essential for debugging and compliance.
Move secrets (if any exist in the code not shown) to environment variables via fastmcp config. Never expose tokens or API keys in parameter definitions or responses.
Add descriptive parameter names and types where inferred. E.g., 'limit' should specify type=integer, minimum=1, maximum=100. 'query' should specify type=string, minimum_length=1.