Skip to main content
Glama
models.py10.3 kB
"""Data models and result types for the File System MCP Server.""" from dataclasses import dataclass from datetime import datetime from typing import Optional, List, Dict, Any, Union import stat import os @dataclass class FileMetadata: """Metadata information for a file or directory.""" size: int modified_time: str permissions: str is_directory: bool mime_type: str created_time: Optional[str] = None accessed_time: Optional[str] = None owner: Optional[str] = None group: Optional[str] = None @classmethod def from_path(cls, path: str, mime_type: str = "unknown") -> "FileMetadata": """Create FileMetadata from a file path.""" try: stat_result = os.stat(path) # Format permissions as octal string permissions = oct(stat.S_IMODE(stat_result.st_mode)) # Format timestamps modified_time = datetime.fromtimestamp(stat_result.st_mtime).isoformat() created_time = datetime.fromtimestamp(stat_result.st_ctime).isoformat() accessed_time = datetime.fromtimestamp(stat_result.st_atime).isoformat() # Get owner and group if available (Unix-like systems) owner = None group = None try: import pwd import grp owner = pwd.getpwuid(stat_result.st_uid).pw_name group = grp.getgrgid(stat_result.st_gid).gr_name except (ImportError, KeyError): # Not available on Windows or if user/group doesn't exist pass return cls( size=stat_result.st_size, modified_time=modified_time, permissions=permissions, is_directory=stat.S_ISDIR(stat_result.st_mode), mime_type=mime_type, created_time=created_time, accessed_time=accessed_time, owner=owner, group=group ) except OSError as e: raise ValueError(f"Cannot get metadata for {path}: {e}") @dataclass class ErrorResponse: """Structured error response with recovery suggestions.""" error_type: str message: str details: Optional[Dict[str, Any]] = None recovery_suggestions: Optional[List[str]] = None def to_dict(self) -> Dict[str, Any]: """Convert to dictionary for JSON serialization.""" result = { "error_type": self.error_type, "message": self.message } if self.details: result["details"] = self.details if self.recovery_suggestions: result["recovery_suggestions"] = self.recovery_suggestions return result @dataclass class FileReadResult: """Result of a file read operation.""" content: Optional[str] metadata: Optional[FileMetadata] success: bool error: Optional[ErrorResponse] = None is_binary: bool = False encoding: Optional[str] = None def to_dict(self) -> Dict[str, Any]: """Convert to dictionary for JSON serialization.""" result = { "success": self.success, "is_binary": self.is_binary } if self.content is not None: result["content"] = self.content if self.metadata: result["metadata"] = { "size": self.metadata.size, "modified_time": self.metadata.modified_time, "permissions": self.metadata.permissions, "is_directory": self.metadata.is_directory, "mime_type": self.metadata.mime_type, "created_time": self.metadata.created_time, "accessed_time": self.metadata.accessed_time, "owner": self.metadata.owner, "group": self.metadata.group } if self.encoding: result["encoding"] = self.encoding if self.error: result["error"] = self.error.to_dict() return result @dataclass class FileWriteResult: """Result of a file write operation.""" path: str metadata: Optional[FileMetadata] success: bool backup_created: Optional[str] = None error: Optional[ErrorResponse] = None bytes_written: Optional[int] = None def to_dict(self) -> Dict[str, Any]: """Convert to dictionary for JSON serialization.""" result = { "path": self.path, "success": self.success } if self.metadata: result["metadata"] = { "size": self.metadata.size, "modified_time": self.metadata.modified_time, "permissions": self.metadata.permissions, "is_directory": self.metadata.is_directory, "mime_type": self.metadata.mime_type } if self.backup_created: result["backup_created"] = self.backup_created if self.bytes_written is not None: result["bytes_written"] = self.bytes_written if self.error: result["error"] = self.error.to_dict() return result @dataclass class FileUpdateResult: """Result of a file update operation.""" path: str metadata: Optional[FileMetadata] success: bool backup_created: Optional[str] = None error: Optional[ErrorResponse] = None bytes_written: Optional[int] = None restored_from_backup: bool = False def to_dict(self) -> Dict[str, Any]: """Convert to dictionary for JSON serialization.""" result = { "path": self.path, "success": self.success, "restored_from_backup": self.restored_from_backup } if self.metadata: result["metadata"] = { "size": self.metadata.size, "modified_time": self.metadata.modified_time, "permissions": self.metadata.permissions, "is_directory": self.metadata.is_directory, "mime_type": self.metadata.mime_type } if self.backup_created: result["backup_created"] = self.backup_created if self.bytes_written is not None: result["bytes_written"] = self.bytes_written if self.error: result["error"] = self.error.to_dict() return result @dataclass class DirectoryEntry: """Information about a directory entry.""" name: str path: str metadata: FileMetadata def to_dict(self) -> Dict[str, Any]: """Convert to dictionary for JSON serialization.""" return { "name": self.name, "path": self.path, "metadata": { "size": self.metadata.size, "modified_time": self.metadata.modified_time, "permissions": self.metadata.permissions, "is_directory": self.metadata.is_directory, "mime_type": self.metadata.mime_type } } @dataclass class DirectoryListResult: """Result of a directory listing operation.""" path: str entries: List[DirectoryEntry] success: bool total_entries: int filtered_entries: int error: Optional[ErrorResponse] = None pattern_used: Optional[str] = None recursive: bool = False max_depth_reached: bool = False def to_dict(self) -> Dict[str, Any]: """Convert to dictionary for JSON serialization.""" result = { "path": self.path, "success": self.success, "total_entries": self.total_entries, "filtered_entries": self.filtered_entries, "recursive": self.recursive, "max_depth_reached": self.max_depth_reached, "entries": [entry.to_dict() for entry in self.entries] } if self.pattern_used: result["pattern_used"] = self.pattern_used if self.error: result["error"] = self.error.to_dict() return result @dataclass class FileDeleteResult: """Result of a file deletion operation.""" path: str success: bool backup_location: Optional[str] = None error: Optional[ErrorResponse] = None was_directory: bool = False files_deleted: int = 1 def to_dict(self) -> Dict[str, Any]: """Convert to dictionary for JSON serialization.""" result = { "path": self.path, "success": self.success, "was_directory": self.was_directory, "files_deleted": self.files_deleted } if self.backup_location: result["backup_location"] = self.backup_location if self.error: result["error"] = self.error.to_dict() return result @dataclass class FileInfoResult: """Result of a file info operation.""" path: str metadata: Optional[FileMetadata] success: bool error: Optional[ErrorResponse] = None exists: bool = False def to_dict(self) -> Dict[str, Any]: """Convert to dictionary for JSON serialization.""" result = { "path": self.path, "success": self.success, "exists": self.exists } if self.metadata: result["metadata"] = { "size": self.metadata.size, "modified_time": self.metadata.modified_time, "permissions": self.metadata.permissions, "is_directory": self.metadata.is_directory, "mime_type": self.metadata.mime_type, "created_time": self.metadata.created_time, "accessed_time": self.metadata.accessed_time, "owner": self.metadata.owner, "group": self.metadata.group } if self.error: result["error"] = self.error.to_dict() return result # Type aliases for common result types OperationResult = Union[ FileReadResult, FileWriteResult, FileUpdateResult, DirectoryListResult, FileDeleteResult, FileInfoResult ]

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/chidvilas1234/Project-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server