Gravity Central
WordPress hub plugin for managing Gravity Forms configuration (forms, fields, feeds) across multiple sites via each site's Gravity Forms MCP Server.
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/rstibal/gravity-central/archive/refs/heads/master.zipA hub WordPress plugin for viewing Gravity Forms configuration (forms, fields, notifications, confirmations, feeds) across multiple sites, by connecting to each site's own Gravity Forms MCP Server.
What this does
- Register managed sites (label, site URL, MCP endpoint URL, WP username + Application Password). Passwords are encrypted at rest.
- Forms: list a site's forms, drill into one to see its fields,
notifications, and confirmations. Add Hidden Field on a form adds a
new hidden field (label + optional default value/merge tag) via
gravityforms/forms-update— the only other write ability this MCP Server exposes, alongside feeds-update. Existing fields are preserved by re-fetching the form's current field list before appending, but this still writes to the live form immediately. - Feeds: clicking Feeds on a site lists its forms, same as Forms —
click a form to see just its feeds. A "Show feeds for all forms" link
still gives the old flat, site-wide list across every form. The feeds
table shows each feed's name rather than its raw config. Edit on
a feed row opens a
typed editor (Feed Name, Method, URL, Format, plus addable/removable
Header and Body mapping rows — each row's value can point at a static
string or a specific form field) for feeds shaped like the two add-ons
actually in use (Webhooks and a "Send to Third Party"-style add-on),
with the full raw JSON still viewable (read-only) below it; any
other add-on shape falls back to a raw JSON editor. Saves via
gravityforms/feeds-update— the only write ability this MCP Server exposes for feeds. This changes live configuration immediately; there's no draft/preview step. Note: this ability has no way to toggle a feed's active/inactive status (Gravity Forms stores that separately from the feed config, and there's no ability for it) — active status is display-only here. - Convert to Webhooks: on a
gravityplus-third-party-postfeed's Edit screen, a "Convert to Webhooks add-on" button appears only if this site already has at least one feed using the Webhooks add-on somewhere (there's no MCP ability to check whether an add-on is installed, so this is a heuristic — a site that just installed Webhooks with zero feeds yet won't show the button until it has one). Otherwise a note explains that no Webhooks feeds were found, with a "show the Convert button anyway" link for exactly that just-installed case (feeds-createitself still fails cleanly with a clear error if the add-on genuinely isn't there). The button translates the feed's config into the official Webhooks add-on's meta shape and creates it as a new, separate feed viagravityforms/feeds-create— the old feed is left completely untouched. Because the MCP Server has no ability to create a feed inactive (is_activeisn't afeeds-createparameter, and there's still no ability forGFAPI::update_feed_active()), the new feed comes in active immediately — for a short window both feeds are live. The results screen links straight to that form's Settings in wp-admin so you can deactivate the old one right away. The field translation has not been verified against a real Webhooks feed's actual stored config — review every field there before trusting it in production. - Copy Feed to Another Site: on a feed's Edit screen (typed editor only
— feeds shown as raw JSON can't be copied this way), a "Copy to another
site…" button lets you pick any target site and form, including a sibling
form on the same site. Only the feed's name, method, URL, and format carry
over; Header/Body mappings and any conditional logic are not copied
since they reference the source form's specific field IDs — you rebuild
them on the next screen against the target form's own fields before
saving. The target must use the same add-on as the source feed; a
"no feeds found on that add-on" notice (with a "continue anyway" override,
same idea as Convert to Webhooks) appears if it can't be detected there.
Creates a brand-new, immediately active feed via
gravityforms/feeds-create— the source feed is never touched. - Compare Feeds Across Sites: a matrix of add-on/feed type by site, so you can spot at a glance which sites are missing an integration the others have. Each populated cell expands to that site's full feed config for side-by-side comparison.
- Copy Hidden Fields Across Forms: pick a source form's hidden fields, pick any number of target forms across any managed sites, review a conflict list (a target already having a same-labeled hidden field defaults to Skip; you opt into Overwrite per conflict), then apply. Each target form is re-fetched immediately before writing and only saved if something actually changed for it.
- Tools: a generic MCP tool browser/runner for anything not yet covered by a dedicated view above — lists enabled tools with their input schemas and lets you call one manually with hand-entered JSON arguments.
- Export / Import Sites: quickly stand up a new Gravity Central hub with
the same managed sites instead of re-registering each one by hand.
Export Sites downloads a JSON file of the registry as stored — Site
URL, MCP endpoint, username, and the Application Password still encrypted
with this site's
GFHUB_ENCRYPTION_KEY. The key itself is never included in that file (see Security notes); a "Show encryption key" panel on the Sites screen lets you copy it to paste into the new site'swp-config.phpby hand instead. Import Sites uploads that file on the new hub — it validates every row decrypts under the local key before writing anything (aborting the whole import on a mismatch, rather than leaving some sites silently broken), and skips any site already registered there (matched by Site URL + username).
Install
-
Copy this
gravity-centralfolder intowp-content/plugins/on the hub site. -
Add a dedicated encryption key to that site's
wp-config.php(generate one, don't reuse a WP salt):define( 'GFHUB_ENCRYPTION_KEY', 'base64:PASTE_A_GENERATED_KEY_HERE' );The plugin's Sites screen will show you a freshly generated one to paste in if this constant is missing.
-
Activate the plugin. This creates one table,
wp_gfhub_sites.
Per-site setup (on each managed site, not the hub)
-
Confirm WP ≥ 6.9 and a Gravity Forms version that includes the MCP Server feature.
-
Create a dedicated WordPress user for the hub to connect as — not your own admin account — and give it its own custom role rather than a stock one. Gravity Forms has no separate read-only capability for viewing forms:
List Forms,Get Form,List Feeds,List Notifications, andList Confirmationsare all gated bygravityforms_edit_forms, which also grants write access if those write abilities are ever enabled.wp role create gravitycentral_reader "Gravity Central Reader" wp cap add gravitycentral_reader read gravityforms_edit_forms gravityforms_view_entries gravityforms_view_settings wp user create <dedicated-username> <email> --role=gravitycentral_reader wp user application-password create <dedicated-username> "Gravity Central" --porcelainThe real read-only boundary for now is which abilities are enabled in the next step, not the capability grant. This same help text (with the snippet above) is also shown in the plugin's Add Site screen.
-
The last command above prints the Application Password to use in step 5 (generate it under that user's Profile → Application Passwords instead, if you didn't use wp-cli).
-
Under Forms → Settings → MCP Server, note the exact MCP endpoint URL and enable the read abilities (List Forms, Get Form, List Feeds, List Notifications, List Confirmations, etc.). Only enable Update Feed and/or Update Form (for Feeds → Edit and Forms → Add Hidden Field respectively), and/or Create Feed (for Convert to Webhooks), on a site once you're ready for it to make live changes there — leave those, and every other write/destructive ability, off otherwise.
-
Add the site in the hub (Sites → Add Site) using that URL, endpoint, username, and Application Password.
-
Click Tools next to the site to confirm the connection, or Forms to see its forms right away.
-
If Feeds shows nothing despite a form having an active integration,
gravityforms_edit_formsalone isn't enough —List Feeds(and Create/Update/Delete Feed) also require the specific add-on's own capability, and without it the ability silently returns an empty list rather than an error. Grant the capability for each add-on actually used on that site, e.g. for Webhooks:wp cap add gravitycentral_reader gravityforms_webhooksOther official Gravity Forms add-ons follow the same
gravityforms_<addon_slug>pattern (e.g.gravityforms_mailchimp). Third-party add-ons (not built by Gravity Forms) do not — they define their own arbitrary capability name. If thegravityforms_<slug>guess doesn't work, find the real one from the add-on's own code:wp plugin path <plugin-slug> grep -rn "_capabilities" <that plugin's folder>/Use the value from
$_capabilities_form_settings— that's the one that gates feed access, not$_capabilitiesor$_capabilities_uninstall.
Security notes
- Application Passwords are stored encrypted (libsodium secretbox) using
GFHUB_ENCRYPTION_KEY, which only ever lives in this hub'swp-config.php. - Only enable read abilities on managed sites by default. Update Feed
(Feeds → Edit) and Update Form (Forms → Add Hidden Field) are the two
write abilities the hub supports — enable each per site only when you
intend to use it there; leave every other write/destructive ability off.
There's no confirmation beyond a single JS
confirm()dialog and no undo — the previous config/field list isn't saved anywhere before it's overwritten. - Treat the hub site itself as sensitive: anyone with
manage_optionsthere can decrypt every managed site's Application Password via this plugin's own code path (though not directly through the UI, which never displays the stored value back). - Export Sites produces a file containing every managed site's
Application Password in encrypted-but-usable form (usable by anyone who
also has
GFHUB_ENCRYPTION_KEY) — handle that download like a credentials file: don't email it or drop it somewhere shared, and delete it once the new hub has imported it.