Extract and index any WordPress site via its REST API. Per-item Markdown, CSV, JSON archive, and a Claude knowledge-base file. Standard-library Python, zero install. A Claude Code plugin.
  • Python 99.3%
  • Shell 0.7%
Find a file
juliandickie 943091557a Add dev-docs note - a blocked users endpoint leaves every author as Author N
Found on widebaykids.com.au (2,165 of 2,361 items) with v0.2.2 and v0.2.3. The
downstream launcher falls back to an authors.json read from the public bylines.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 12:32:14 +10:00
.claude-plugin Bump version to 0.2.3 2026-10-15 01:17:55 +10:00
.github/workflows Polish - pagination dedupe, knowledge-base splitting, CI 2026-07-20 07:32:21 +10:00
assets Rework README with a StoryBrand narrative and illustrations 2026-06-01 19:45:54 +10:00
commands Add /wp-index slash command 2026-06-01 15:55:46 +10:00
dev-docs Add dev-docs note - a blocked users endpoint leaves every author as Author N 2026-10-15 12:32:14 +10:00
scripts Fall back to a draft-posts query when /users/me is blocked 2026-10-15 01:17:55 +10:00
skills/wp-index Fall back to a draft-posts query when /users/me is blocked 2026-10-15 01:17:55 +10:00
test Fall back to a draft-posts query when /users/me is blocked 2026-10-15 01:17:55 +10:00
.gitignore Ignore .omc/ (oh-my-claudecode session artifacts) 2026-07-20 07:21:27 +10:00
CLAUDE.md Close review gaps - iframe capture, orphan reconciliation, e2e harness 2026-07-20 08:00:58 +10:00
LICENSE Scaffold wp-index plugin manifest and license 2026-06-01 15:33:18 +10:00
README.md Close review gaps - iframe capture, orphan reconciliation, e2e harness 2026-07-20 08:00:58 +10:00

wp-index - extract any WordPress site to clean Markdown, CSV, and JSON

wp-index

Your WordPress content, set free. Extract any WordPress site to clean Markdown, CSV, and JSON, from any Claude Code session, with zero install.


Your best content lives inside WordPress, and getting it back out is a chore. Exporting for an SEO audit, a site migration, or an AI knowledge base usually means wrestling with plugins, database dumps, or copy and paste. Content you own should not be this hard to use.

wp-index points at any WordPress site's public REST API and pulls every post, page, and custom post type into clean, structured files you actually own. One command, read-only against the site, nothing to install.

What you walk away with:

  • A per-item Markdown file for every post and page, with YAML frontmatter.

  • A CSV index you can open in a spreadsheet or feed to a script.

  • A full JSON archive of everything, as a backup or a data source.

  • A single knowledge-base Markdown file, ready to drop into a Claude project.

How it works

How wp-index works - WordPress through the wp-index engine into Markdown, CSV, JSON, and a knowledge base

It is one standard-library Python script. It walks the REST API (/wp-json/wp/v2), resolves authors and dates, cleans each item's HTML into Markdown, scores it for basic SEO, and writes everything out. It checkpoints as it goes, so an interrupted run resumes where it left off, and it stays polite with a one-second default delay between requests.

Three steps to your index

Three steps - point at your site, run the command, get your index

1. Install

Via the Outfit marketplace (recommended):

/plugin install wp-index@outfit

Standalone, direct from this repo:

/plugin marketplace add juliandickie/wp-index
/plugin install wp-index@wp-index

2. Run it

python3 scripts/wp_index.py --site https://example.com

Or, once installed, from any Claude Code session:

/wp-index https://example.com

3. Get your index

Output lands in ./example.com-wp-index/ by default. The full layout is below.


Flags

Flag Default What it does
--site (required) Base URL of the WordPress site
--type posts,pages Comma-separated REST bases, or all for every public type
--out ./<domain>-wp-index Output directory
--since off Flag items not modified since this date (YYYY-MM-DD)
--fresh off Ignore saved checkpoints and re-fetch everything
--delay 1.0 Seconds between requests (raise on rate-limited hosts)
--per-page 50 Items per API page (max 100, WordPress limit)
--drafts off Include drafts and private items (requires auth)
--no-score off Skip the SEO score calculation

--type all reads /wp-json/wp/v2/types and pulls every public post type, so the same tool covers a blog, a WooCommerce shop (products), or a LearnDash academy (sfwd-courses).

Output layout

<domain>-wp-index/
  index/
    posts-index.csv        one row per post
    pages-index.csv        one row per page
    archive.json           full JSON backup of every item
    knowledge-base.md      single Markdown file for Claude project knowledge
                           (numbered parts on very large sites)
    index.xlsx             only written if openpyxl is installed
  posts/
    2024-03-15_my-slug.md  one file per post, YAML frontmatter + Markdown body
  pages/
    2024-01-10_about.md
  orphaned/                files whose items disappeared from the site (moved, not deleted)

The run resumes from checkpoints if interrupted, at per-post-type granularity, and clears them after a completed run so the next one fetches fresh data. Use --fresh to force a refetch at any time.

Authentication - Application Passwords

Published content needs no authentication. You only need credentials if you want to include drafts and private items, or to resolve author display names reliably.

When you do need auth, set these environment variables before running:

export WP_USER="your-wp-username"
export WP_APP_PASSWORD="xxxx xxxx xxxx xxxx xxxx xxxx"

The most common friction point is that security plugins (Patchstack, Wordfence, Solid Security) hide the Application Passwords option in the WordPress admin by default, and the site must be on HTTPS. Full setup steps and per-plugin fixes are in skills/wp-index/references/application-passwords.md.

Requirements

Python 3.8 or newer. No packages to install. openpyxl is optional and used only if it is already present in the environment. The tool is read-only against the site it runs against.