Skip to content

Add directory move support to move_note tool #516

Description

@phernandez

Summary

Extend the move_note MCP tool to support moving entire directories, not just individual files. Also rename the folder parameter in write_note to directory for consistency.

Motivation

Currently, move_note only moves single files. Users need to move directories to reorganize their knowledge base structure efficiently.

Requirements

1. Add is_directory parameter to move_note

async def move_note(
    identifier: str,
    destination_path: str,
    is_directory: bool = False,  # NEW
    project: Optional[str] = None,
    context: Context | None = None,
) -> str:

When is_directory=True:

  • identifier is a directory path (e.g., "docs", "projects/2025")
  • destination_path is the new directory path (no file extension required)
  • All files within the directory are moved, preserving relative structure

2. Service layer changes

New method in EntityService:

async def move_directory(
    self, source_dir: str, dest_dir: str, project_config, app_config
) -> DirectoryMoveResult:
    # 1. Find all entities with file_path starting with source_dir/
    entities = await self.entity_repository.find_by_directory_prefix(source_dir)
    
    # 2. Validate no conflicts at destination
    # 3. Move each file, updating database
    # 4. Return results (success count, failures, etc.)

3. API endpoint

New endpoint or enhanced existing:

  • POST /knowledge/move-directory
  • Request: { "source_directory": str, "destination_directory": str }
  • Response: { "total_files": int, "successful_moves": int, "failed_moves": int, "errors": [...] }

4. Rename folderdirectory in write_note

For naming consistency across all tools:

  • write_note(..., folder: str, ...)write_note(..., directory: str, ...)
  • Update docstrings and examples

Existing Infrastructure to Reuse

  • EntityRepository.find_by_directory_prefix() - SQL LIKE query for finding entities in a directory
  • FileService.move_file() - Atomic file moves with concurrency control
  • FileService.ensure_directory() - Creates destination directories
  • Existing error handling patterns in move_note

Design Considerations

  • Transaction safety: Wrap DB updates in transaction; rollback file moves on failure
  • Conflict detection: Check all destination paths before starting moves
  • Path transformation: old_path.replace(f"{source}/", f"{dest}/", 1)
  • Progress reporting: Return detailed results for large directory moves

Testing Requirements

  • Unit tests for path transformation
  • Integration tests for directories with 1, 10, 100+ files
  • Error cases: permission denied, conflicts, partial failures
  • Concurrent directory move operations

Acceptance Criteria

  • move_note("docs", "archive/docs", is_directory=True) moves all files in docs/ to archive/docs/
  • Nested directories are preserved (e.g., docs/a/b.mdarchive/docs/a/b.md)
  • Database records updated for all moved files
  • Search index re-indexed for all moved files
  • Clear error messages for conflicts and failures
  • write_note parameter renamed from folder to directory

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions