Skip to main content
Glama
ArsNovaSingers

ars-nova-wordpress-mcp

Official

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
WP_SITE_URLYesThe base URL of the WordPress site (e.g., https://arsnovasingers.org)
WP_USERNAMEYesWordPress username with application password access
WP_APP_PASSWORDYesThe 24-character WordPress application password (generated from the user's profile)

Capabilities

Features and capabilities supported by this server

CapabilityDetails
tools
{
  "listChanged": true
}

Tools

Functions exposed to the LLM to take actions

NameDescription
wp_list_postsA

List blog posts on arsnovasingers.org with filtering, pagination, and sorting.

Returns a paginated list of posts (default 20 per page). Posts are returned newest-first by default. Use status='any' to include drafts/pending/private (requires edit_posts capability).

Args:

  • limit (number): Page size, 1-100. Default 20.

  • offset (number): Pagination offset. Default 0.

  • status (enum): publish | future | draft | pending | private | trash | any. Default 'publish'.

  • search (string): Optional keyword to search title + content.

  • author (number): Optional author ID filter.

  • categories (number[]): Optional list of category IDs to filter to.

  • tags (number[]): Optional list of tag IDs to filter to.

  • orderby (enum): date | modified | id | title | slug | author | relevance. Default 'date'.

  • order (enum): asc | desc. Default 'desc'.

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: Paginated envelope with shape: { "total": number, // Total matching posts on the server "count": number, // Posts in this response "offset": number, // Pagination offset "items": [WPContentItem], // Trimmed post shape (id, title, slug, status, link, excerpt, content_preview, author_id, etc.) "has_more": boolean, "next_offset": number // Present if has_more }

wp_get_postA

Fetch a single blog post by ID or slug. Returns the full content of the post (rendered to plain text — HTML stripped).

At least one of 'id' or 'slug' must be provided.

Args:

  • id (number): Numeric post ID. Mutually exclusive with slug.

  • slug (string): URL handle of the post. Mutually exclusive with id.

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: A single WPContentItem object with the full content_preview field expanded to up to 500 characters of plain-text content. For full content, the JSON response includes the original raw body.

wp_list_pagesA

List static pages on arsnovasingers.org. Pages differ from posts: they are hierarchical, ordered by menu_order rather than date, and used for evergreen content (About, Concerts, Education, Contact, etc.).

Args:

  • limit (number): Page size, 1-100. Default 20.

  • offset (number): Pagination offset. Default 0.

  • status (enum): publish | future | draft | pending | private | trash | any. Default 'publish'.

  • search (string): Optional keyword filter.

  • parent (number): Optional parent page ID filter. Use 0 for top-level pages.

  • orderby (enum): Default 'menu_order' (respects WP page tree).

  • order (enum): Default 'asc'.

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: Paginated envelope (same shape as wp_list_posts) of WPContentItem objects.

wp_get_pageA

Fetch a single page by ID or slug. Returns the full content (rendered to plain text — HTML stripped).

At least one of 'id' or 'slug' must be provided.

Args:

  • id (number): Numeric page ID. Mutually exclusive with slug.

  • slug (string): URL handle of the page (e.g. "about", "concerts"). Mutually exclusive with id.

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: A single WPContentItem object with full content_preview expanded.

wp_search_contentA

Cross-content keyword search across posts and pages using WP's built-in /wp/v2/search endpoint. Lighter-weight than wp_list_posts(search=...) because it returns just (id, title, url, type, subtype) per match.

Args:

  • query (string): Required, minimum 2 characters.

  • type (enum): post | page | any. Default 'any' (searches both).

  • limit (number): Page size, 1-100. Default 20.

  • offset (number): Pagination offset. Default 0.

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: Paginated envelope of search hits with shape: { "total": number, "count": number, "offset": number, "items": [{ "id": number, "title": string, "url": string, "type": string, "subtype": string }], "has_more": boolean, "next_offset": number }

wp_create_postA

Create a new blog post. Defaults to status='draft' for safety — set status='publish' to publish immediately.

Args:

  • title (string): Post title.

  • content (string): HTML body.

  • excerpt (string): Optional short summary.

  • slug (string): URL slug. Auto-generated from title if omitted.

  • status (enum): publish | future | draft | pending | private. Default 'draft'.

  • author (number): Author user ID. Defaults to authenticated user.

  • featured_media (number): Featured image media ID.

  • date (string): ISO 8601 schedule date. Set status='future' for scheduling.

  • categories (number[]): Category IDs.

  • tags (number[]): Tag IDs.

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: The created WPContentItem (id, slug, status, link, etc.)

wp_update_postA

Update an existing post. Only the fields you pass will change; omitted fields preserve their current values.

Args:

  • id (number): Post ID to update. Required.

  • title, content, excerpt, slug, status, author, featured_media, date, categories, tags: all optional, same shape as wp_create_post.

  • content_path (string): Optional. Absolute local file path; its contents become the post content (for bodies too large to pass inline). Overrides 'content'.

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: The updated WPContentItem.

wp_delete_postA

Delete a post. Defaults to trash (recoverable for 30 days). Set force=true to permanently delete.

Args:

  • id (number): Post ID to delete. Required.

  • force (boolean): Default false. True = permanent delete (skip trash).

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: JSON with deletion outcome:

  • force=false: the post object with status='trash'

  • force=true: { deleted: true, previous: }

wp_create_pageA

Create a new static page. Defaults to status='draft'.

Args:

  • title, content, excerpt, slug, status, author, featured_media, date: same as wp_create_post.

  • parent (number): Parent page ID. 0 for top-level.

  • menu_order (number): Numeric position in the page hierarchy.

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: The created WPContentItem.

wp_update_pageA

Update an existing page. Only the fields you pass will change.

Args:

  • id (number): Page ID. Required.

  • All other fields optional, same shape as wp_create_page.

  • content_path (string): Optional. Absolute local file path; its contents become the page content (for bodies too large to pass inline). Overrides 'content'.

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: The updated WPContentItem.

wp_delete_pageA

Delete a page. Defaults to trash. Set force=true to permanently delete.

Args:

  • id (number): Page ID. Required.

  • force (boolean): Default false (trash). True = permanent.

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: Deletion outcome (see wp_delete_post for shape).

wp_list_mediaA

List items in the WP media library with filtering and pagination.

Args:

  • limit (number): Page size, 1-100. Default 20.

  • offset (number): Pagination offset.

  • media_type (enum): image | video | audio | file | any. Default 'any'.

  • search (string): Optional keyword filter.

  • parent (number): Optional attachment-to-post-ID filter (0 = unattached).

  • orderby (enum): date | title | id | modified. Default 'date'.

  • order (enum): asc | desc. Default 'desc'.

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: Paginated envelope of WPMediaItem objects with shape: { id, date, slug, title, alt_text, caption, description, media_type, mime_type, source_url, file_size, width, height, author_id, attached_to_id }

wp_get_media_itemA

Fetch a single media item by ID. Returns full metadata including dimensions, file size, MIME type, alt text, caption, and source URL.

Args:

  • id (number): Numeric media item ID.

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: A single WPMediaItem object.

wp_upload_mediaA

Upload a local file to the WP media library as a new attachment. Reads the file from file_path on the MCP host machine, sends as multipart/form-data, and returns the created media item.

Args:

  • file_path (string): Absolute path to the file on disk. Required.

  • title (string): Optional title (defaults to filename).

  • alt_text (string): Optional alt text.

  • caption (string): Optional caption.

  • description (string): Optional description.

  • post (number): Optional post/page ID to attach the media to (0 = unattached).

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: The newly-created WPMediaItem with id, source_url, dimensions, etc.

Notes:

  • The MCP host process must have read access to file_path.

  • For best SEO, always pass alt_text on image uploads.

  • WP MIME-sniffs the file; the upload will be rejected if the extension is on WP's disallowed list (e.g. executables).

wp_update_mediaA

Update metadata on an existing media item — title, alt text, caption, description, or attachment target. Most common use: backfilling alt_text on images that don't have it.

Args:

  • id (number): Media item ID. Required.

  • alt_text (string): New alt text. Pass empty string to clear.

  • title, caption, description (string): Optional.

  • post (number): Reassign to a different post/page ID (0 = unattach).

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: The updated WPMediaItem.

wp_delete_mediaA

Permanently delete a media item. WP REST does NOT support trashing media; deletion is always permanent.

Args:

  • id (number): Media item ID. Required.

  • force (boolean): Default true. False will trigger a WP validation error.

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: { deleted: true, previous: }

wp_list_usersA

List users on the WP site. Use context='edit' to see roles/capabilities (requires admin).

Args:

  • limit (number): Page size, 1-100. Default 20.

  • offset (number): Pagination offset.

  • search (string): Optional keyword filter (matches username, email, name).

  • roles (string[]): Optional filter to users in these roles.

  • orderby (enum): id | name | registered_date | slug | include. Default 'name'.

  • order (enum): asc | desc. Default 'asc'.

  • context (enum): view | embed | edit. Default 'view'. Use 'edit' to get roles/capabilities.

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: Paginated envelope of WPUserItem objects with shape: { id, name, slug, url, description, link, roles?, capabilities?, registered_date? }

wp_get_userA

Fetch a single user by ID. Use context='edit' to get roles/capabilities (requires admin).

Args:

  • id (number): Numeric user ID.

  • context (enum): view | embed | edit. Default 'view'.

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: A single WPUserItem object.

wp_update_userA

Update an existing user's name, email, roles, or profile fields. Common use: demoting an admin to editor or subscriber.

Args:

  • id (number): User ID. Required.

  • name, email, first_name, last_name, url, description, slug: optional fields to update.

  • roles (string[]): Replaces existing roles. e.g. ['editor'], ['subscriber'], ['administrator'].

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: The updated WPUserItem.

wp_delete_userA

Permanently delete a user. WP requires a reassign target — the deleted user's content (posts, pages, media) gets transferred to that user ID. WP REST does NOT support trashing users; deletion is always permanent.

Args:

  • id (number): User ID to delete. Required.

  • reassign (number): User ID to receive the deleted user's content. Required.

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: { deleted: true, previous: }

wp_list_categoriesA

List post categories with hierarchy + post counts.

Args:

  • limit (number): Page size, 1-100. Default 20.

  • offset (number): Pagination offset.

  • search (string): Optional keyword filter.

  • hide_empty (boolean): Default false. Set true to skip categories with no posts.

  • orderby (enum): id | name | slug | count | include. Default 'name'.

  • order (enum): asc | desc. Default 'asc'.

  • parent (number): Optional parent category ID filter. Use 0 for top-level.

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: Paginated envelope of WPTermItem objects with shape: { id, name, slug, description, count, parent, link }

wp_list_tagsA

List post tags with post counts.

Args:

  • limit (number): Page size, 1-100. Default 20.

  • offset (number): Pagination offset.

  • search (string): Optional keyword filter.

  • hide_empty (boolean): Default false.

  • orderby (enum): id | name | slug | count | include. Default 'name'.

  • order (enum): asc | desc. Default 'asc'.

  • parent (number): Tags do not have hierarchy on most sites; this is usually ignored.

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: Paginated envelope of WPTermItem objects.

wp_create_categoryA

Create a new post category.

Args:

  • name (string): Required. Display name.

  • slug (string): Optional. Auto-generated from name if omitted.

  • description (string): Optional.

  • parent (number): Optional parent category ID. 0 for top-level.

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: The created WPTermItem.

wp_update_categoryA

Update an existing category's name, slug, description, or parent.

Args:

  • id (number): Category ID. Required.

  • name, slug, description (string): Optional.

  • parent (number): New parent category ID.

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: The updated WPTermItem.

wp_create_tagA

Create a new post tag.

Args:

  • name (string): Required. Display name.

  • slug (string): Optional. Auto-generated from name if omitted.

  • description (string): Optional.

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: The created WPTermItem.

wp_update_tagA

Update an existing tag's name, slug, or description.

Args:

  • id (number): Tag ID. Required.

  • name, slug, description (string): Optional.

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: The updated WPTermItem.

wp_check_environmentA

⚠️ SAFETY CHECK — Call this before any write, update, or delete operation. Returns the site URL and environment label so you can confirm you are on the correct site (LIVE vs DEV) before making changes. Never skip this on write operations.

wp_get_site_infoA

Get high-level info about the WordPress site: name, tagline, admin email, REST API namespaces, supported authentication, plus general WP settings.

Combines /wp-json (root, public) with /wp/v2/settings (admin-only). Settings fields will be omitted gracefully if your user lacks the manage_options capability.

Args:

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: WPSiteInfo object with shape: { "site_url": string, "api_namespaces": string[], "api_authentication": string[], "title"?: string, "description"?: string, "url"?: string, "email"?: string, "timezone"?: string, "language"?: string, "posts_per_page"?: number, "show_on_front"?: "posts" | "page", "page_on_front"?: number, "page_for_posts"?: number, "default_category"?: number, "default_post_format"?: string }

wp_list_themesA

List installed themes. The active theme is flagged with status='active'. Child themes are detected (template != stylesheet).

Note: This endpoint requires admin (edit_themes capability). Will return 403 if the Application Password user is not an admin.

Args:

  • status (enum): active | inactive | any. Default 'any'.

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: Array of WPThemeItem objects with shape: { stylesheet, template, name, status, version, author, author_uri, description, theme_uri, is_child_theme, requires_wp, requires_php, tags, textdomain, screenshot? }

wp_list_pluginsA

List installed plugins with version, status, and metadata. The active plugins are flagged with status='active'.

Note: This endpoint requires admin (activate_plugins capability). Returns 403 otherwise.

Args:

  • status (enum): active | inactive | any. Default 'any'.

  • search (string): Optional keyword filter against plugin name/description.

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: Array of WPPluginItem objects with shape: { plugin, status, name, plugin_uri, author, version, description, network_only, requires_wp, requires_php, textdomain }

wp_get_settingsA

Fetch WP general settings (title, tagline, admin email, timezone, date/time formats, posts-per-page, front page mode, default category, etc.).

Note: Requires admin (manage_options capability).

Args:

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: RawWpSettings object — see wp_get_site_info for the field list.

wp_list_post_typesA

List all registered post types (built-in + custom). Useful for discovering custom post types added by Stagehand or other plugins (e.g. 'event', 'concert', 'season').

Args:

  • context (enum): view | edit. Default 'view'.

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: Object keyed by post type slug, each value containing { name, slug, rest_base, rest_namespace, hierarchical, has_archive, taxonomies, description }

wp_get_seo_metaA

Get SEO meta (title, description, canonical, OG/Twitter, focus keyword) for a single post or page. Auto-detects the active SEO plugin (Yoast, RankMath, AIOSEO) and normalizes the fields where possible.

Either 'id' or 'slug' must be provided.

Args:

  • content_type (enum): post | page. Required.

  • id (number): Numeric ID of target. Mutually exclusive with slug.

  • slug (string): Slug of target. Mutually exclusive with id.

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: WPSeoMetaResult object with shape: { "detected_plugin": "yoast" | "rankmath" | "aioseo" | "none", "meta_title"?: string, "meta_description"?: string, "canonical_url"?: string, "noindex"?: boolean, "og_title"?: string, "og_description"?: string, "og_image"?: string, "twitter_title"?: string, "twitter_description"?: string, "twitter_image"?: string, "focus_keyword"?: string, "raw"?: object // The raw plugin-specific blob for reference }

wp_audit_alt_textA

Scan the media library and report which IMAGE items are missing alt text. Skips non-image media (video/audio/file). Designed to be paginated for large libraries — start at offset 0, then re-run with the returned next_offset.

Args:

  • scan_limit (number): How many media items to scan in this call, 1-500. Default 100.

  • limit (number): How many missing-alt items to return in the result. Default 20.

  • offset (number): Pagination offset INTO THE MEDIA LIBRARY (not into the missing list). Default 0.

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: WPAltTextAuditResult object with shape: { "total_media_scanned": number, "total_images_scanned": number, "missing_alt_count": number, "missing_alt_items": [ { "id": number, "title": string, "source_url": string, "attached_to_id": number } ], "has_more": boolean, "next_offset": number // Present if has_more }

Note: missing_alt_count is the count WITHIN this scan window only. Re-run with the returned next_offset to continue scanning the rest of the library.

wp_update_seo_metaA

Update Yoast SEO meta on a post or page: title, description, canonical, noindex, focus keyword, OG, Twitter. Writes via WP REST's meta sub-object using Yoast's underlying postmeta keys.

Args:

  • content_type (enum): post | page. Required.

  • id (number): ID of the post/page. Required.

  • meta_title, meta_description, canonical_url, focus_keyword: optional strings.

  • noindex (boolean): true = noindex, false = index, undefined = leave Yoast's default.

  • og_title, og_description, twitter_title, twitter_description: optional social-share overrides.

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: The updated content item (with the new Yoast meta applied — re-fetch with wp_get_seo_meta to verify rendering).

Note: This is for Yoast specifically. RankMath / AIOSEO sites need different keys (not supported in v1).

wp_bulk_update_postsA

Update many posts from a CSV. Required column: id. Optional: title, content, status, slug, excerpt, categories (comma-separated IDs), tags (comma-separated IDs), featured_media. Empty cells are SKIPPED (no change to that field). Defaults to dry_run=true.

Args:

  • csv_path (string): Path to CSV file. Required.

  • dry_run (boolean): Default true. Set false to apply changes.

  • stop_on_error (boolean): Default false.

  • response_format (enum): markdown | json. Default 'markdown'.

Use case: backfill categories on the 45 "Uncategorized" posts.

wp_bulk_update_media_alt_textA

Backfill alt text (and optionally caption/description/title) across many media items from a CSV. Required columns: id, alt_text. Optional: caption, description, title. Defaults to dry_run=true.

Use case: the 2020-era alt-text backfill on arsnovasingers.org.

wp_bulk_update_usersA

Update many users from a CSV. Required column: id. Optional: roles (single role like 'subscriber' or comma-sep for multiple), email, first_name, last_name, name, description. Defaults to dry_run=true.

Use case: demote stale admins identified in the website audit.

wp_bulk_create_postsA

Create many posts from a CSV. Required columns: title, content. Optional: status (default 'draft'), slug, excerpt, categories (comma-sep IDs), tags (comma-sep IDs), date, featured_media. Defaults to dry_run=true.

Use case: import a content calendar.

wp_bulk_assign_termsA

Assign categories or tags to many posts using term NAMES (not IDs). Missing tag names are auto-created by default. Required columns: post_id, taxonomy (category|tag), term_names (comma-separated). Defaults to dry_run=true.

This REPLACES existing terms in that taxonomy on each post. To merge with existing terms, look those up first and include them in term_names.

wp_get_acf_optionsA

Read fields from an ACF (Advanced Custom Fields) Options page on arsnovasingers.org.

Requires the "ACF to REST API" plugin (airesvsg) to be installed and active. Reads from /wp-json/acf/v3/options/{option_page}.

Use this for Stagehand's global site content — footer columns/headers, alert bars, sponsor blocks, etc. — that aren't stored on a specific page.

Args:

  • option_page (string): Options page slug. Default 'options' (Stagehand's main Options page).

  • field (string, optional): Specific field name to return. If omitted, returns all fields.

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: WPACFOptionsResult { acf: { [field_name]: value, ... } }

wp_update_acf_optionsA

Write one or more fields to an ACF Options page on arsnovasingers.org.

Requires the "ACF to REST API" plugin (airesvsg) to be installed and active. Posts to /wp-json/acf/v3/options/{option_page} with body { fields: {...} }.

ONLY the field names you include in 'fields' are modified — omitted fields are untouched. This is safe for incremental edits to the footer, alert bar, etc., without needing to re-send the entire Options page.

For repeater fields (e.g. footer_sponsors, alert_bar), you must send the COMPLETE new array — repeaters are replaced wholesale, not merged. Read first with wp_get_acf_options to get the current array, modify it locally, then send back.

Args:

  • option_page (string): Options page slug. Default 'options'.

  • fields (object): { field_name: new_value, ... }. Values: strings (HTML for WYSIWYG, plain text), numbers, booleans, arrays (full replacement for repeaters), or nested objects (for groups).

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: Result of the write including the updated fields and any plugin-returned metadata.

wp_list_menusA

List all WordPress navigation menus with their IDs, slugs, and assigned theme locations. Requires admin (edit_theme_options).

Args:

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: { count, items: [{ id, name, slug, locations }] }

wp_list_menu_itemsA

List the items in a navigation menu, in order, including nesting (parent IDs). Use the menu_id from wp_list_menus.

Args:

  • menu_id (number): The menu ID.

  • response_format (enum): markdown | json. Default 'markdown'.

Returns: { count, items: [{ id, title, type, object, object_id, url, parent, menu_order }] }

wp_create_menuA

Create an empty navigation menu, optionally assigning it to theme locations (e.g. ['primary']). Returns the new menu ID. Requires admin.

Args:

  • name (string): Menu name.

  • locations (string[]): Optional theme locations to assign.

  • response_format (enum): markdown | json.

wp_update_menuA

Rename a menu and/or change its theme-location assignments. Requires admin.

Args:

  • menu_id (number): Menu to update.

  • name (string): Optional new name.

  • locations (string[]): Optional new location list (replaces existing).

  • response_format (enum): markdown | json.

wp_delete_menuA

Permanently delete a navigation menu and all its items (force delete). Requires admin. This cannot be undone via the API.

Args:

  • menu_id (number): Menu to delete.

  • response_format (enum): markdown | json.

wp_create_menu_itemA

Add a single item to a menu. Link it to a page (page_id) or to a custom URL (url). Nest it by setting parent to another item's ID. Requires admin.

Args:

  • menu_id (number): Menu to add to.

  • title (string): Label.

  • page_id (number): Link to this page ID (or use url).

  • url (string): Custom URL (or use page_id).

  • parent (number): Parent item ID for nesting. 0 = top level.

  • menu_order (number): Position within its level.

  • response_format (enum): markdown | json.

wp_update_menu_itemA

Update a single existing menu item IN PLACE — rename it, repoint it, re-nest it, or reorder it — without rebuilding the menu. Only the fields you pass are changed. Requires admin.

Prefer this over wp_build_menu for small edits. Rebuilding a menu regenerates EVERY item ID, which breaks anything referencing them and leaves orphaned rows behind; this changes one row.

Args:

  • item_id (number): Menu-item ID to update (from wp_list_menu_items). Required.

  • title (string): New label.

  • page_id (number): Repoint at this page ID. Mutually exclusive with url.

  • url (string): Repoint at this custom URL. Mutually exclusive with page_id.

  • parent (number): New parent item ID. 0 = top level.

  • menu_order (number): New position within its level.

  • target (enum): '' (same tab) | '_blank' (new tab).

  • description (string), attr_title (string), classes (string[]).

  • response_format (enum): markdown | json.

Returns: the updated menu item.

wp_delete_menu_itemA

Permanently remove a single menu item (force delete). Requires admin.

Args:

  • item_id (number): Menu-item ID to remove.

  • response_format (enum): markdown | json.

wp_build_menuA

Create an entire navigation menu — nested submenus, ordering, and theme-location assignment — from one structured spec. Ideal for rebuilding a site's primary navigation by command.

Each item links to a page (page_id) OR a custom URL (url), OR neither (a non-linking dropdown parent that just holds children). Children create submenus. Order follows array order.

Args:

  • name (string): Menu name to create.

  • locations (string[]): Optional theme locations, e.g. ['primary'].

  • items: ordered array of { title, page_id?, url?, children?[] }.

  • response_format (enum): markdown | json.

Example items: [ { "title": "Concerts", "children": [ { "title": "This Season", "page_id": 123 }, { "title": "Tickets", "page_id": 3285 } ]}, { "title": "Donate", "url": "/support/donate/" } ]

Returns: { menu_id, items_created, locations }. Note: creates a NEW menu; it does not merge into an existing one. Use wp_list_menus / wp_delete_menu first if replacing.

wp_update_settingsA

Update core WP general settings (title, tagline, posts-per-page, and the front-page / blog-page assignment). Requires admin (manage_options). Only the fields you pass are changed.

The most common use is setting the static homepage: show_on_front='page', page_on_front=, page_for_posts=.

NOTE: This cannot toggle "Discourage search engines" (blog_public) — core does not expose it via REST. Use the WP Admin Reading screen or the planned control plugin for that.

Args:

  • title, description (string)

  • posts_per_page (number)

  • show_on_front ('posts' | 'page')

  • page_on_front, page_for_posts, default_category (number)

  • response_format (enum): markdown | json.

Returns: the updated settings object.

wp_get_theme_modsA

Read the active theme's theme_mods — the storage behind Kadence/Customizer settings (header layout, logo, colors, fonts, page-title display, etc.). Core REST does not expose these; this uses the companion "Ars Nova Bridge" plugin (must be active).

Args:

  • keys (string[]): optional filter to specific theme_mod keys.

  • response_format (enum): markdown | json.

Returns: active theme slug/name and the theme_mods map.

wp_set_theme_modsA

Set and/or remove the active theme's theme_mods — drives Kadence/Customizer settings by command. Uses the companion "Ars Nova Bridge" plugin (must be active). Requires admin.

CAUTION: theme_mods control header/layout/colors. ALWAYS read current values with wp_get_theme_mods and back them up before bulk changes. Removing a key resets it to the theme default.

Args:

  • mods (object): key:value pairs to set. Values may be string/number/bool/array/object.

  • remove (string[]): keys to reset to default.

  • response_format (enum): markdown | json.

Returns: what changed/removed plus the full updated theme_mods map.

wp_get_sidebarsA

List all registered widget areas / sidebars (incl. Kadence footer areas) with their IDs and the widgets currently in each. Core REST /wp/v2/sidebars. Requires admin.

Returns: array of { id, name, status, widgets[] }.

wp_get_widgetsA

List all widget instances across sidebars, with their IDs, sidebar assignment, and rendered/raw content. Core REST /wp/v2/widgets. Requires admin.

wp_create_widgetA

Create a block-based widget in a sidebar/widget area. Use for populating Kadence footer columns. Requires admin.

Args:

  • sidebar (string): target widget-area ID (from wp_get_sidebars).

  • content (string): block markup for the widget body.

Returns: the created widget (incl. its new id).

wp_update_widgetA

Update a widget's content and/or move it to another sidebar (use sidebar 'wp_inactive_widgets' to deactivate). Core REST PUT /wp/v2/widgets/{id}. Requires admin.

wp_read_theme_fileA

Read theme source on the server (sandboxed to wp-content/themes) via the Ars Nova Bridge plugin. Directory path -> listing; file path -> contents (cap 500 KB). Use to discover Kadence footer-builder option keys. Requires Bridge plugin active + admin.

Args:

  • path (string): relative to wp-content/themes (e.g. 'kadence/inc'). Omit to list themes.

wp_get_raw_contentA

Read a page/post's RAW Gutenberg block markup (comment-delimited blocks), via core REST with context=edit. This is the editable source that wp_get_page/wp_get_post strip away. Use to inspect and transform page content, then write it back with wp_update_page. Requires admin.

Args:

  • id (number): page/post ID.

  • type ('page' | 'post'): default 'page'.

  • response_format (enum): markdown | json.

Returns: { id, title, slug, content } where content is the raw block markup.

wp_set_page_metaA

Write post meta on a page/post (e.g. Kadence per-page settings such as _kad_post_title to disable the title on one page). POSTs { meta: {...} } to core REST. Only REST-registered meta keys can be written. Requires admin.

Args:

  • id (number): page/post ID.

  • type ('page' | 'post'): default 'page'.

  • meta (object): key:value pairs to set.

  • response_format (enum): markdown | json.

Returns: the updated meta object.

wp_strip_leading_coverA

Remove the embedded leading core/cover hero block from one or more pages, so the theme's page-title bar takes over. SAFE: only removes a block that is BOTH the first block AND a core/cover; pages without a leading cover are left unchanged. Reads/strips/writes server-side (no page content passes through the client), so it scales to many pages in one call. Requires admin.

Args:

  • ids (number[]): page/post IDs.

  • type ('page' | 'post'): default 'page'.

  • dry_run (bool): if true, report what would change WITHOUT saving.

  • response_format (enum): markdown | json.

Returns: per-id { title, removedCover, saved }.

wp_list_site_notesA

List the in-context notes/change-tasks captured on the front end via the companion "Ars Nova Site Notes" plugin (must be active). Each note carries page URL/title, priority (1-10), type, done/completed status, who added it + when, and an optional linked element. Use this to sync notes into the project tracker + wiki, or to review what's outstanding on a site.

Whichever site this connector targets (DEV or LIVE) is the source. Run on both connectors and tag rows by site to get the full picture.

Args:

  • status (enum): open | done | all. Default 'all'.

  • page_url (string): optional path filter for a single page.

  • response_format (enum): markdown | json.

Returns: the notes, sorted open-first then priority high->low.

wc_get_settingsA

Read a WooCommerce settings group. Groups include: general, products, tax, shipping, checkout (= payments), advanced, email. Returns all setting IDs and their current values for the group.

wc_update_settingA

Update a single WooCommerce setting by group and setting ID. Example: group='general', setting_id='woocommerce_currency', value='USD'. Common settings: general: woocommerce_currency, woocommerce_store_address, woocommerce_store_city, woocommerce_default_country, woocommerce_store_postcode, woocommerce_calc_taxes (yes/no) tax: woocommerce_prices_include_tax, woocommerce_tax_based_on, woocommerce_tax_display_shop, woocommerce_tax_display_cart advanced: woocommerce_cart_page_id, woocommerce_checkout_page_id, woocommerce_myaccount_page_id, woocommerce_terms_page_id

wc_list_productsA

List WooCommerce products with optional filters. Returns product ID, name, type, status, price, SKU, and stock info.

wc_create_productA

Create a new WooCommerce product. For Tickera ticket products, set type='simple' and the product will be available for Tickera bridge mapping. Supports simple products with price, description, categories, and images.

wc_update_productA

Update an existing WooCommerce product by ID. Only the fields you pass are changed.

wc_list_payment_gatewaysA

List all registered payment gateways and their enabled/disabled status. Shows gateway ID, title, description, enabled state, and method title. Use this to check if Stripe is enabled and in test mode.

wc_update_payment_gatewayA

Update a payment gateway's settings. Use to enable/disable a gateway or change its title/description. For Stripe test mode keys, Jon handles those directly in WP Admin — this tool can enable/disable the gateway only.

wc_list_ordersA

List WooCommerce orders with optional status filter. Returns order ID, status, total, customer info, and line items.

wc_get_system_statusA

Get WooCommerce system status including environment info, database, active plugins, theme, settings, and pages. Use for health checks.

wc_list_shipping_zonesA

List shipping zones and their methods. Use to verify shipping is disabled or check what zones exist.

wc_list_tax_classesA

List available tax classes.

tickera_statusA

Check that the Ars Nova Ticketing Bridge plugin is active and that WooCommerce, Tickera, and the Bridge for WooCommerce are all present. Returns the default ticket-template ID. Call this before creating events/tickets.

tickera_list_eventsA

List all Tickera events (tc_events) with their date, location, status, and any linked ticket-type products.

tickera_get_eventA

Get one Tickera event by ID, including its ticket-type products.

tickera_create_eventA

Create a Tickera event (tc_events). Use for one performance/show date. Defaults to status='draft' so nothing goes public until you're ready. Date accepts any parseable value (e.g. '2026-09-19 19:30'); stored as Tickera's 'Y-m-d H:i'. After creating the event, add ticket tiers with tickera_create_ticket_type.

tickera_list_templatesA

List Tickera ticket templates (used on PDF/printed tickets). Use to pick a ticket_template ID for tickera_create_ticket_type; if omitted there, the plugin uses the default template.

tickera_create_ticket_typeA

Create a ticket tier for an event (e.g. Orchestra / Balcony / GA / Student). Creates a WooCommerce product and wires it to the event via the Bridge meta, so it sells through the normal Woo cart/Stripe checkout. Requires an existing event_id (from tickera_create_event or tickera_list_events).

tickera_list_ticket_typesA

List ticket-type products, optionally filtered to one event_id.

wp_ops_statusA

Check that the Ars Nova Ops (Plugin Installer) plugin is active on the target site. Returns whether this is the production site, whether file modifications are allowed (DISALLOW_FILE_MODS), the current user's install capability, and the allow-listed zip hosts. Call before installing/updating plugins.

wp_install_pluginA

Install a plugin on the target WordPress site. Pick ONE source: slug (from WordPress.org), url (allow-listed zip), zip_b64, or zip_path (a local zip file the connector reads for you). Set activate=true to activate right after install. For updating an already-installed plugin, use wp_update_plugin instead (or pass overwrite=true here). On the LIVE production site this refuses unless confirm_production=true.

wp_update_pluginA

Update / replace an already-installed plugin in place (overwrite forced on). Pick ONE source: slug, url, zip_b64, or zip_path (a local zip the connector reads for you). Keeps the plugin's activation state. On the LIVE production site this refuses unless confirm_production=true.

wp_set_plugin_statusA

Activate or deactivate an installed plugin. 'plugin' is the plugin basename (folder/file.php), e.g. 'ars-nova-site-notes/ars-nova-site-notes.php' — the value shown as "plugin" by wp_list_plugins.

wp_delete_pluginA

Deactivate (if needed) and permanently delete an installed plugin from the site. 'plugin' is the basename (folder/file.php). On the LIVE production site this refuses unless confirm_production=true. This cannot be undone.

wp_list_redirectsA

List the 301/302 redirects managed by the Redirection plugin. Requires the plugin to be active and admin rights.

Args:

  • search (string): Optional keyword filter on source/target URLs.

  • per_page (number): Page size, 1-200. Default 50.

  • page (number): 1-based page number. Default 1.

  • response_format (enum): markdown | json.

Returns: { count, total, items: [{ id, url, action_code, action_data, enabled, hits }] }

wp_create_redirectA

Create a 301 (or 302/307/308) redirect in the Redirection plugin. Use after any slug change or page re-parenting so the old URL keeps working and search authority transfers.

Requires the Redirection plugin to be active and admin rights.

Args:

  • source (string): Old path to redirect FROM, e.g. '/listen/current-season/'. Required.

  • target (string): Path or URL to redirect TO, e.g. '/concerts/this-season/'. Required.

  • code (301|302|307|308): Default 301 (permanent).

  • title (string): Optional note shown in the admin list.

  • group_id (number): Redirection group. Default 1.

  • regex (boolean): Treat source as a regex. Default false.

  • response_format (enum): markdown | json.

Returns: the created redirect.

ans_rest_callA

Call any route in one of the Ars Nova plugins' own REST namespaces. Use this for capabilities that have no dedicated tool yet — it means a new plugin endpoint is usable the moment it is deployed, with no connector rebuild.

RESTRICTED BY DESIGN to namespaces we author: ars-nova/v1, ans-ops/v1, ans-notes/v1, ansg/v1. It cannot call wp/v2, wc/v3 or third-party plugin routes — those have their own purpose-built tools with validation this does not provide.

Environment safety: this goes through the same client as every other tool, so it hits whichever site this connector is configured for. Call wp_check_environment first if you are unsure whether you are on DEV or LIVE.

Useful ars-nova/v1 routes (ars-nova-ticketing-bridge v1.4.0):

  • GET tickera/introspect — what is ACTUALLY registered: shortcodes, post types, taxonomies, ticket-product meta keys. Use this instead of assuming.

  • GET tickera/status

  • GET tickera/events | tickera/event/{id}

  • POST tickera/event/{id} — update title/date/location/status

  • DEL tickera/event/{id} — trash (?force=1 to delete)

  • GET tickera/ticket-types | tickera/ticket-type/{id}

  • POST tickera/ticket-type/{id} — update price/status/template/stock/virtual

  • POST tickera/assign-template — { template_id, event_id?, product_ids? }

  • GET tickera/event-categories — the season's "projects"

  • POST tickera/event-categories — { name, slug?, description?, ans_page_id? }

  • POST tickera/event-category/{id} — rename, re-describe, re-link, reassign events

  • GET tickera/attendees — issued tickets

Args:

  • namespace (enum): one of the allowed namespaces. Required.

  • route (string): path within it, no leading slash. Required.

  • method (enum): GET | POST | PUT | PATCH | DELETE. Default GET.

  • query (object): query-string parameters.

  • body (object): JSON body for writes.

  • response_format (enum): markdown | json.

Returns: the endpoint's JSON response verbatim.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ArsNovaSingers/ars-nova-wordpress-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server