Export WordPress pages, posts, and custom posts to portable local packages with builder data, media, and human-readable markdown. Import to another site with smart ID remapping. Auto-backup before AI edits. Use when user says "export my site", "backup my pages", "migrate
Installs just this skill. Get the whole plugin for auto-invocation.
⚡ How it fires
How this skill gets triggered: by you, by Claude, or both.
Fires itselfClaude auto-loads it when your prompt matches the work.
You can call itInvoke it directly when you want it.
Slash command/content-portability
👁️ Context preview
The summary Claude sees to decide when to auto-load this skill.
Export WordPress pages, posts, and custom posts to portable local packages with builder data, media, and human-readable markdown. Import to another site with smart ID remapping. Auto-backup before AI edits. Use when user says "export my site", "backup my pages", "migrate
---name: content-portability
description: Export WordPress pages, posts, and custom posts to portable local packages with builder data, media, and human-readable markdown. Import to another site with smart ID remapping. Auto-backup before AI edits. Use when user says "export my site", "backup my pages", "migrate content", "download my content", or "content portability".
license: MIT
metadata:
author: Respira for WordPress
author_url: https://respira.press
version: 1.0.0
mcp-server: respira-wordpress
category: migration
---# Content Portability
Export WordPress content to portable local packages. Import to another site with smart ID remapping. Auto-backup before AI edits. Full builder data preservation, human-readable markdown previews, and optional media download.
## What This Skill Does
**Exports:**
- Pages, posts, and custom post types — individually or in bulk
- Full builder data (Elementor, Bricks, Divi, etc.) alongside standard content
- Allowlisted post meta (SEO fields, featured images, builder config)
- Human-readable markdown preview of every page/post
- Optional media binary download for fully offline packages
- Manifest with hashes, stats, and export metadata
**Imports:**
- Reads a local Respira Content Package and pushes to a target WordPress site
- Respira for WordPress plugin installed and activated
- MCP connection configured (site URL + API key)
- For import: write access on the target site
- For media download: sufficient local disk space
## How to Use
### Trigger Phrases
- "export my site"
- "export the homepage"
- "backup my pages before editing"
- "download my content locally"
- "migrate content to my other site"
- "content portability"
- "create a local backup"
- "export with media"
### Export Workflow
**Phase 1: Scope Selection**
1. Ask the user what to export:
- **Single page/post**: "export the homepage", "backup the about page"
- **Full site**: "export everything", "download all my content"
- **By type**: "export all blog posts", "export portfolio items"
2. Ask whether to include media downloads:
- **Without media** (default): Fast, small packages with URL references
- **With media**: Downloads all referenced images/files locally for full offline portability
**Phase 2: Content Enumeration**
3. Call `wordpress_list_pages`, `wordpress_list_posts`, and/or `wordpress_list_custom_posts` to enumerate content in scope
4. For each item, call `wordpress_read_page` or `wordpress_read_post` with `include=builder.extracted,meta.allowlisted` to get full content with builder data
5. Report progress every 10 items: "Exported 30/120 pages..."
> Import the content package from ./respira-export/
## Package format
- content.json files contain full machine-readable content with builder data
- content.md files are human-readable previews
- media/ contains downloaded media files (if included)
```
11. Show export stats summary:
```
Export Complete
━━━━━━━━━━━━━━━━━━━━━━━━━━
Pages exported: 23
Posts exported: 8
Custom posts: 17
Media files: 156
Package size: 52.4 MB
Warnings: 0
Skipped: 0
━━━━━━━━━━━━━━━━━━━━━━━━━━
Saved to: ./respira-export/
```
### Import Workflow
**Phase 1: Read & Validate Package**
1. Read `manifest.json` from the local package
2. Validate export version compatibility
3. Report what will be imported: "Found 23 pages, 8 posts, 156 media files from example.com"
**Phase 2: Upload Media (if included)**
4. If `media/` directory exists with files:
- For each media file, call `wordpress_upload_media` on the target site
- Build the **media ID mapping table**: `{ old_id: 108, new_id: 342 }`
- Log each upload; skip failures with warning
5. If media was not included in the package:
- Media references will point to original URLs (cross-site references)
- Warn the user about this
**Phase 3: Detect Conflicts**
6. For each content item in the package, check if a page/post with the same slug already exists on the target site
7. Present all conflicts upfront in a single table:
```
Slug Conflicts Detected (5 of 23 pages)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Slug Source Title Target Title
about About Us About Our Company
contact Contact Contact Us
team Our Team The Team
services Services Our Services
faq FAQ FAQ
```
8. Ask the user for a bulk resolution strategy:
- **Overwrite all**: Replace target content with package content
- **Skip conflicts**: Only import non-conflicting content
- **Rename imports**: Add suffix to conflicting slugs (e.g., `about-imported`)
**Phase 4: Snapshot Existing Content**
9. **MANDATORY**: Before overwriting any existing content, take a server-side snapshot of each target page/post using the existing snapshot system
- This uses the `before_edit` snapshot kind automatically via MCP write operations
- Ensures rollback is always possible
**Phase 5: Create/Update Content**
10. For each content item:
- If no conflict or overwrite strategy: call `wordpress_update_page` or `wordpress_update_post`
- Set title, content, excerpt, status, and allowlisted meta
- Build the **post ID mapping table**: `{ old_id: 42, new_id: 187 }`
11. Report progress every 10 items
**Phase 6: Rewrite & Inject Builder Data**
12. For each imported page/post that has builder data:
- Take the builder JSON from `content.json`
- Rewrite all media IDs using the media ID mapping table
- Rewrite all internal post/page IDs using the post ID mapping table
- Rewrite all internal URLs from source domain to target domain
- Call `wordpress_inject_builder_content` to apply the rewritten builder data
**Phase 7: Verify & Report**
13. For each imported page/post:
- Re-read via `wordpress_read_page`/`wordpress_read_post`
- Compare content hashes to source hashes
- Flag any mismatches
14. Show import report:
```
Import Complete
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Pages imported: 23 (5 overwrites, 18 new)
Posts imported: 8 (0 overwrites, 8 new)
Media uploaded: 156 (2 skipped — too large)
Builder data: 19 pages with builder content rewritten
ID remappings: 187 references updated
Hash verification: 46/48 match (2 minor diffs flagged)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Server-side snapshots taken for all overwrites.
```
### Auto-Backup Workflow
A lightweight mode for quick local backups before AI editing:
1. User says "backup the homepage before editing" or "save a local copy first"
2. Call `wordpress_read_page` with full includes
3. Write a single timestamped file: `./respira-backups/home-2026-03-16-1430.json`
4. Also write the markdown preview: `./respira-backups/home-2026-03-16-1430.md`
5. Confirm: "Backed up homepage to ./respira-backups/home-2026-03-16-1430.json"
6. Proceed with the requested edit
### Diff Workflow
Compare local export against current site state:
1. User says "what changed since my last export?" or "diff my backup"
2. Read the local `manifest.json` to identify exported content
3. For each exported page/post, call `wordpress_read_page`/`wordpress_read_post`
4. Compare content hashes from local `content.json` against current site hashes
5. Report differences:
```
Content Changes Since Export (2026-03-16)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Changed:
about Content updated (builder + text)
homepage Builder layout changed
pricing Text content changed
Unchanged: 21 pages, 8 posts
New on site: 2 pages (not in export)
Deleted: 0 pages
```
## Error Handling
The skill must handle these scenarios gracefully:
| Error | Action | User Sees |
|-------|--------|-----------|
| Site disconnected | Stop, report what was saved | "Site unreachable — 45/120 pages saved" |
| Page not found mid-export | Skip, log in manifest warnings | "Skipped: About (deleted)" |
| Malformed builder data | Export raw content without builder | Warning in manifest |
| Disk full | Stop, report progress | "Disk full after 45 pages" |
| Media download 404/403 | Skip file, log in media-index | "Skipped 3 media files" |
| Slug conflict on import | Bulk resolution (see Phase 3) | Conflict table |
| Media upload too large | Skip, log | "Skipped: hero.webp (too large)" |
| Builder version mismatch | Warn, import anyway | Warning in report |
**Key rule**: Always continue on non-fatal errors (skip the item, log it). Never silently drop content. Always produce a summary of warnings/skips at the end.
## Safety Model
- **Read-only export**: No changes to the source site during export
- **Mandatory snapshots**: Server-side snapshot taken before every import overwrite
- **Non-destructive import**: Creates new content or overwrites with snapshot safety net
- **Rollback ready**: Server-side snapshots enable one-click restoration via `wordpress_restore_snapshot`
- **No credential exposure**: Only allowlisted meta is exported — no API keys, passwords, or sensitive plugin settings
## Honest Disclaimer
**What this skill CANNOT do:**
- Export/import WordPress settings, options, or configuration