Skip to content
Media, menus, categories & tags Manage a WordPress site's media library, navigation menus and taxonomy — no wp-admin login, no child plugin.

Media, menus, categories & tags

Four sections of a WordPress site’s content shell let you manage everything that isn’t a post or page: the Media library (/sites/:srv/:dom/media), the navigation Menus builder (/menus), and the Categories (/categories) and Tags (/tags) taxonomies. They all read and write WordPress directly through the site’s agent — no wp-admin login, no page-builder dependency, no child plugin to install. Available on all plans for any WordPress site.

  • Media (/media) — a searchable, filterable grid of the site’s attachments. Filter by All types / Images / Files, open any item to edit its Title, Alt text and Caption, copy its URL or open it in a new tab, and delete it. Select tiles for bulk actions: Edit alt / caption across many items at once, or delete the selection. Load more pages through large libraries.
  • Menus (/menus) — a two-column navigation workbench. Pick or create a menu on the left, then drag items into a nested tree on the right. Add Pages, Posts, Categories or a Custom link from the source panels, rename or remove items inline, nest them by dragging, and click Save changes to write the whole tree. Classic themes also expose Display location (assign the menu to the theme’s nav slots).
  • Categories (/categories) — hierarchical taxonomy CRUD. Create, edit (Name · Slug · Parent · Description) and delete categories, nest them under a parent, and mark one as the site’s default category with the star action.
  • Tags (/tags) — the same CRUD as categories but flat (no parent, no default).
  1. Open Media from the site’s left rail.
  2. Use the search box (matches file names) and the Type filter (All types / Images / Files) to narrow the grid.
  3. Click a tile to open its details drawer. Edit the Title, Alt text and Caption, then Save — or Copy URL / Open the original.
  4. To act on many files, hover a tile and tick its checkbox (or Select all from the bulk dock). Then Edit alt / caption to apply the same values across the selection, or delete them.
  1. Open Menus. MZPanel auto-detects whether the active theme is classic or block, and drives the right backend for you.
  2. Pick a menu from the dropdown, or click + to create one.
  3. Expand a source panel (Pages / Posts / Categories / Custom link), tick the items you want and click Add — they append to the tree on the right.
  4. Drag items to reorder or nest them, rename or remove an item inline, and (classic themes) tick a Display location to place the menu in the theme.
  5. Click Save changes. Nothing is written to WordPress until you save — a yellow “Unsaved changes” bar lets you Discard instead.

All four sections are powered by one job kind, wp.content, which proxies the site’s native WordPress REST API (wp/v2) through the agent:

  • The dashboard calls the API, which dispatches wp.content with a method, a wp/v2 path and (for writes) a JSON body.
  • The agent runs mz wp <domain> content <method> <path> natively. It resolves the site, ensures the embedded mzpanel-agent mu-plugin is installed and a per-site token exists (self-healing — no manual install step), then makes a localhost HTTPS call to the mu-plugin route mzpanel/v1/wp/<path>, which forwards to wp/v2.
  • The mu-plugin’s JSON response is returned verbatim. The per-site token is read on the box and sent as an X-MZP-Token header — it never leaves the server.

State lives entirely in WordPress: media are attachments, menus are the nav_menu taxonomy (classic) or a core/navigation block (block themes), and categories/tags are the category and post_tag taxonomies. The default category is stored in WordPress Settings (default_category). MZPanel keeps no copy of any of it.

Every action maps to mz wp <domain> content … on the box — the same engine the dashboard drives. The <method> and <path> are a native wp/v2 REST call; writes carry a JSON body via --data. SSH in and run them, or let an on-box AI (ClaudeCode) run them the same way:

Terminal window
mz wp example.com content GET media --json # list media
mz wp example.com content GET categories --json # list categories
mz wp example.com content POST tags --data '{"name":"featured"}' --json
mz wp example.com content DELETE media/123 --json # delete attachment 123

The path and body are a straight wp/v2 request, so anything the WordPress REST API exposes (pagination, ?per_page=, menus, menu-items, navigation, settings, …) works here. Always pass --json. See The mz CLI and the command catalog.

  • Media upload isn’t wired yet. The Upload button is intentionally disabled — new uploads need the direct-to-box ingress plus a wp media import agent action that isn’t built yet. For now, upload files in wp-admin; everything else (browse, edit, bulk-edit, delete) is fully live here.
  • Needs a WordPress site + the agent online. These sections read and write live through the agent and the mu-plugin. On other site types they don’t apply, and when the agent is offline you’ll see the site shell’s “agent offline” banner.
  • The bridge installs itself. The first wp.content call materializes the mzpanel-agent mu-plugin and mints a per-site token automatically. If it can’t (a locked-down filesystem, for example) the section shows a “bridge install failed” error pointing at mz wp <domain> agent install.
  • Menu edits are all-or-nothing until you save. Reordering, renaming and removing items only touch the in-memory tree; Save changes reconciles the whole menu in one pass. Leaving without saving discards the edits.
  • The default category can’t be deleted. Its delete action is disabled; make a different category the default first, then delete the old one. Deleting any other category re-homes its orphaned posts onto the default.