push_file_to_sandbox
Copy files from your local system to a Modal sandbox environment for uploading inputs, transferring configurations, or deploying code to isolated cloud-based Python environments.
Instructions
Copies a file from the local filesystem to a Modal sandbox.
Parameters:
- sandbox_id: The unique identifier of the sandbox
- local_path: Path to the source file on local filesystem
- sandbox_path: Destination path in the sandbox
- read_file_mode: Optional mode for reading local file (default: "rb")
- writefile_mode: Optional mode for writing to sandbox (default: "wb")
Returns a PushFileToSandboxResponse containing:
- success: Boolean indicating if copy was successful
- message: Descriptive message about the copy operation
- local_path: The source path on local filesystem
- sandbox_path: The destination path in sandbox
- file_size: Size of the file in bytes
This tool is useful for:
- Uploading input files to sandboxes
- Transferring configuration files
- Setting up sandbox environments
- Deploying code to sandboxes
The tool will:
1. Verify sandbox is running and local file exists
2. Read contents from local file
3. Write contents to sandbox path
4. Return status of the operation
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| sandbox_id | Yes | ||
| local_path | Yes | ||
| sandbox_path | Yes | ||
| read_file_mode | No | rb | |
| writefile_mode | No | wb |
Implementation Reference
- The handler function that implements the tool logic: validates sandbox is running and local file exists, reads the local file asynchronously, writes content to sandbox via thread executor, and returns a success response.async def push_file_to_sandbox( self, sandbox_id: str, local_path: str, sandbox_path: str, read_file_mode: str = "rb", writefile_mode: str = "wb" ) -> PushFileToSandboxResponse: # 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 sandbox_status = await modal_sandbox.poll.aio() if sandbox_status is not None: raise ToolError(f"Sandbox {sandbox_id} is not running") if not path.exists(local_path): raise ToolError(f"Local file {local_path} does not exist") # Get file size file_size = os.path.getsize(local_path) # Read local file asynchronously async with aiofiles.open(local_path, read_file_mode) as file_pointer: content = await file_pointer.read() # Write to sandbox using thread executor await self._write_sandbox_file_in_thread(modal_sandbox, sandbox_path, content, writefile_mode) logger.info(f"Copied file from {local_path} to {sandbox_path} in sandbox {sandbox_id}") return PushFileToSandboxResponse( success=True, message=f"File copied successfully to {sandbox_path}", local_path=local_path, sandbox_path=sandbox_path, file_size=file_size, )
- Pydantic BaseModel defining the structure of the tool's response, including success status, message, paths, and file size.class PushFileToSandboxResponse(BaseModel): success: bool message: str local_path: str sandbox_path: str file_size: int
- src/mcp4modal_sandbox/backend/mcp_server.py:121-124 (registration)Registers the 'push_file_to_sandbox' tool with the FastMCP app, specifying name and description, binding to the handler method.mcp_app.tool( name="push_file_to_sandbox", description=ToolDescriptions.PUSH_FILE_TO_SANDBOX, )(self.push_file_to_sandbox)
- Helper method used by the handler to write file content to the sandbox in a synchronous context via thread pool executor, as Modal sandbox operations are sync.async def _write_sandbox_file_in_thread(self, modal_sandbox, file_path: str, content, mode: str = 'wb'): def _sync_write(): with modal_sandbox.open(file_path, mode) as f: f.write(content) loop = asyncio.get_event_loop() return await loop.run_in_executor(self.thread_pool_executor, _sync_write)