# Memona FTP plugin Opens an FTP or FTPS server as a folder in [Memona](https://memona.app), so files on it are browsed, read, written and renamed like local ones, and agents work in them. The plugin is a WebAssembly component built against the Memona filesystem contract, `memona:filesystem@0.1.0`. It uses only the host's sockets; it has no ambient filesystem, environment or network access of its own. ## What it registers One provider, `ftp`, for the `ftp` and `ftps` schemes. A connection is configured with a server name, an optional port, a TLS toggle for FTPS, and an optional username and password. An empty username signs in anonymously. Listing and stat need a server that answers `MLSD` and `MLST`, the machine-readable listing commands. A server without them reports the folder as unsupported rather than guessing at the older, human-formatted listing or changing its working directory to find out. FTP carries no version token, so a conditional write is reported as unsupported rather than simulated. ## Passive mode and the port range Transfers are passive: the plugin asks the server for a data port with `EPSV` or `PASV` and connects out to it. The server picks a fresh port for every transfer and announces it only as the transfer begins, so the range that has to be reachable is wide. `manifest.json` declares `networkPorts` as 21 and 1024-65535, and `networkHosts` as `*` because a server can be anywhere. Declaring is not granting: a connection reaches only the host and ports the person grants it, and a grant never accepts a wildcard host. Grant the control port and the span the server uses for its data channel, usually `21` and `1024-65535`. ## Build ```sh rustup target add wasm32-wasip2 cargo build --locked --release --target wasm32-wasip2 ``` The component lands at `target/wasm32-wasip2/release/memona_plugin_ftp.wasm`. `sdk/` is a vendored copy of the Memona plugin SDK, the WIT contract plus its generated Rust bindings, so this repository builds without the Memona repository present. ## Package for the plugin store Copy the component to `plugin.wasm` and ZIP it at the archive root together with `manifest.json`, `README.md` and `LICENSE`: ```sh cp target/wasm32-wasip2/release/memona_plugin_ftp.wasm plugin.wasm zip memona-plugin-ftp.memona-plugin \ manifest.json plugin.wasm README.md LICENSE ``` The archive must have no wrapping directory. Memona validates the package and its digest, and checks the component's imports against the supported WIT API, before activation. ## License MIT. See [LICENSE](LICENSE).