Everything below reflects the current release (v1.1.0). From install to a completed, fully reported batch is typically under five minutes.
You need WordPress 6.2+ on PHP 7.4+, an administrator login, and the plugin zip plus licence key from your purchase email. One honest note first: this tool installs plugins, which means it writes to wp-content/plugins. That is why the preflight is the product and the install is core's job — every archive is fully checked before WordPress is asked to do anything, and both destructive options are off until you turn them on.
WordPress 6.2 or newer on PHP 7.4 or newer, and an administrator account holding the WordPress capability to install plugins. Check your server's upload limits at the same time — upload_max_filesize, post_max_size, max_file_uploads and max_execution_time under Tools → Site Health → Info → Server — because those, not the plugin, decide how many ZIPs you can send in one batch and how large they may be. PHP ZipArchive is the preferred archive reader and is present on nearly every host; where it is missing the plugin falls back to PclZip, which WordPress bundles. Symlink detection is weaker on the PclZip route, and that difference is real rather than theoretical.
Go to Plugins → Add Plugin → Upload Plugin, choose the zip from your purchase email, install and activate. It adds a Multi Plugin Installer item under Plugins.
Open Plugins → MPI Licence and paste the key from your purchase email — a long code starting VPC1., so paste the whole thing into the textarea rather than typing it. Verification happens on your own server with no call home, so the plugin keeps working if our site is down. A key is either domain-locked or valid on any site, depending on what you bought.
Select or drag your plugin ZIP files onto the batch panel — up to twenty-five in one pass, as far as your server allows. Twenty-five is the plugin's ceiling; your host's PHP settings may impose a lower one, and max_file_uploads commonly defaults to 20. Nothing is read from the files yet and nothing has touched the disk. This is the point at which you decide what the run is allowed to do.
Allow replacement/update and Activate after installation are both OFF by default, which is the opposite of most batch tools and is deliberate. A batch that silently replaces a working plugin on a live site is a worse failure than one that stops and tells you the folder already exists. Turn replacement on only when you positively intend to overwrite.
Every archive goes through the full preflight before WordPress writes a byte. Passing archives are handed to WordPress's own upgrader APIs rather than to any unpacking code of ours. A refusal names its own reason, the rest of the batch carries on regardless, and the whole run is saved as a report you can hand to somebody else.
A refusal always names its own reason rather than reporting a generic failure, so every one of these is actionable. Nothing has been written to disk when you see one. A batch that hits your server's limits behaves differently: PHP discards the surplus before the request arrives, so files go missing from the run or the submission fails outright rather than producing a named refusal. That case is covered under Everyday use below.
The file is corrupt or was truncated in transit. Download it again. The companion message “empty or cannot be read” means the same thing.
Symlinks inside an archive are refused where the ZIP reader can see them. Repackage without them. Detection is weaker on the PclZip fallback, so on a host without ZipArchive treat this check as best-effort rather than a guarantee.
Either nothing inside, or an implausible number of entries for a WordPress plugin. Both are signs this is not the file you think it is.
The ceiling is on the expanded size, not the file you uploaded, because compression ratios are a weapon as well as a convenience. A small zip can hold an enormous payload.
You have a bundle of several plugins in one archive. Split it into one zip per plugin. This is refused rather than half-unpacked, so nothing lands on disk.
The top-level directory name is not usable as a WordPress plugin folder. Repackage with a plain lowercase name and no unusual characters.
There is no plugin header block to read, so this is not a WordPress plugin. A theme zip lands here, as does a stray backup.
You have a zip of a zip, or an extra wrapper directory added by the download. WordPress cannot find a main file nested a level deeper, so a plugin installed that way is not installed in any useful sense.
An entry carries a .. segment or an otherwise unsafe path. Refused outright and never sanitised — quietly rewriting a hostile path leaves you trusting the rewrite instead of rejecting the archive.
The declared minimum in the plugin header is not met by this server. Upgrade PHP or use an older release of that plugin. The message names both versions so it is actionable.
Same again for the WordPress minimum. Better to be told now than to discover it as a white screen after activation.
Filename, plugin name, version, the operation performed and the WordPress error message where there was one — for every archive in the batch. Reports live in your own database until you delete them, individually or by clearing the history. They never store the contents of the uploaded ZIPs and they never store credentials.
The rest carry on. One invalid archive never hides the results for the others: every file receives its own operation and its own outcome, so a bad download appears as a named line rather than an abandoned run.
Any retained report downloads as Excel-safe CSV, which makes it usable as handover documentation without anyone writing a document.
The twenty-five cap sits on a real data path rather than on a hidden button: the batch is truncated in the installer itself. The mpip_max_batch_size filter is clamped against it, so the filter can lower the cap and never raise it.
A batch is an ordinary PHP file upload, so your host decides what actually gets through before WordPress or this plugin sees anything. Four settings matter: max_file_uploads (how many files one request may carry — often 20 by default, which caps the batch at twenty), upload_max_filesize (the largest single ZIP), post_max_size (the whole submission, so it must exceed the combined size of the batch) and max_execution_time (how long the run may take). Exceeding them does not produce a preflight refusal, because the request never arrives intact: files go missing from the batch, or the submission fails outright. Read the current values under Tools → Site Health → Info → Server, raise them in php.ini or your hosting panel if you control the server, and otherwise send fewer files per run. No plugin can raise a limit that PHP applies before the request reaches it.
They install normally. The header inside the ZIP is read and the validated archive is handed to WordPress's own upgrader, so anything that installs through Add New, Upload Plugin installs here. Licence activation is still whatever that plugin does after installation — this tool installs, it does not activate third-party licences.
Only administrators holding the WordPress plugin-installation capability can open the screen or run a batch. This is a tool for the person who already holds the keys, not a way to give somebody a lesser set of keys.
Deactivate and delete through the Plugins screen as normal. Your saved reports live in a plugin table, so clear the report history first if you want them gone.