pull_file_from_sandbox
Copy files from Modal sandbox environments to your local filesystem for analysis, backup, or debugging purposes.
Instructions
Copies a file from a Modal sandbox to the local filesystem.
Parameters:
- sandbox_id: The unique identifier of the sandbox
- sandbox_path: Path to the file in the sandbox
- local_path: Destination path on local filesystem
Returns a PullFileFromSandboxResponse containing:
- success: Boolean indicating if copy was successful
- message: Descriptive message about the copy operation
- sandbox_path: The source path in sandbox
- local_path: The destination path on local filesystem
- file_size: Size of the file in bytes
This tool is useful for:
- Retrieving output files from sandbox executions
- Backing up sandbox data
- Analyzing sandbox-generated content locally
- Debugging sandbox operations
The tool will:
1. Verify sandbox and source file exist
2. Create local destination directory if needed
3. Copy file contents from sandbox to local system
4. Return status of the operation
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| sandbox_id | Yes | ||
| sandbox_path | Yes | ||
| local_path | Yes |
Implementation Reference
- The core handler function that implements the pull_file_from_sandbox tool. It retrieves the sandbox, checks if it's running, reads the file content from the sandbox using a thread executor, writes it to the local path, and returns a response.
async def pull_file_from_sandbox( self, sandbox_id: str, sandbox_path: str, local_path: str ) -> PullFileFromSandboxResponse: # Get sandbox from Modal using from_id modal_sandbox = await modal.Sandbox.from_id.aio(sandbox_id) # Check if sandbox is running before copying file from sandbox sandbox_status = await modal_sandbox.poll.aio() if sandbox_status is not None: raise ToolError(f"Sandbox {sandbox_id} is not running") # Read from sandbox using thread executor content = await self._read_sandbox_file_in_thread(modal_sandbox, sandbox_path, 'rb') file_size = len(content) # Write to local file asynchronously makedirs(path.dirname(local_path), exist_ok=True) async with aiofiles.open(local_path, 'wb') as file_pointer: await file_pointer.write(content) logger.info(f"Copied file from {sandbox_path} to {local_path} from sandbox {sandbox_id}") return PullFileFromSandboxResponse( success=True, message=f"File copied successfully to {local_path}", file_size=file_size, sandbox_path=sandbox_path, local_path=local_path, ) - src/mcp4modal_sandbox/backend/mcp_server.py:127-129 (registration)The registration of the pull_file_from_sandbox tool in the FastMCP app, linking the name, description, and handler function.
name="pull_file_from_sandbox", description=ToolDescriptions.PULL_FILE_FROM_SANDBOX, )(self.pull_file_from_sandbox) - Pydantic model defining the output schema/response structure for the pull_file_from_sandbox tool.
class PullFileFromSandboxResponse(BaseModel): success: bool message: str sandbox_path: str local_path: str file_size: int - Tool description string used in registration, detailing parameters, returns, and usage of pull_file_from_sandbox.
PULL_FILE_FROM_SANDBOX = """ Copies a file from a Modal sandbox to the local filesystem. Parameters: - sandbox_id: The unique identifier of the sandbox - sandbox_path: Path to the file in the sandbox - local_path: Destination path on local filesystem Returns a PullFileFromSandboxResponse containing: - success: Boolean indicating if copy was successful - message: Descriptive message about the copy operation - sandbox_path: The source path in sandbox - local_path: The destination path on local filesystem - file_size: Size of the file in bytes This tool is useful for: - Retrieving output files from sandbox executions - Backing up sandbox data - Analyzing sandbox-generated content locally - Debugging sandbox operations The tool will: 1. Verify sandbox and source file exist 2. Create local destination directory if needed 3. Copy file contents from sandbox to local system 4. Return status of the operation """ - Helper method to read file content from sandbox in a synchronous context via thread pool executor, used by the pull_file_from_sandbox handler.
async def _read_sandbox_file_in_thread(self, modal_sandbox, file_path: str, mode: str = 'rb'): def _sync_read(): with modal_sandbox.open(file_path, mode) as f: return f.read() loop = asyncio.get_event_loop() return await loop.run_in_executor(self.thread_pool_executor, _sync_read)