Batch update Yoast SEO metadata (titles, descriptions, focus keyphrases) in WordPress via GraphQL...
This skill manages Yoast SEO metadata in WordPress sites via the WPGraphQL API. It enables batch updates of:
Add this to your theme's functions.php to enable mutations:
// Enable Yoast SEO mutations via WPGraphQL
add_action('graphql_register_types', function() {
register_graphql_mutation('updatePostSeo', [
'inputFields' => [
'postId' => ['type' => 'Int', 'description' => 'Post ID'],
'title' => ['type' => 'String', 'description' => 'SEO Title'],
'metaDesc' => ['type' => 'String', 'description' => 'Meta Description'],
'focusKeyphrase' => ['type' => 'String', 'description' => 'Focus Keyphrase'],
],
'outputFields' => [
'success' => ['type' => 'Boolean'],
'post' => ['type' => 'Post'],
],
'mutateAndGetPayload' => function($input) {
$post_id = absint($input['postId']);
if (!current_user_can('edit_post', $post_id)) {
throw new \GraphQL\Error\UserError('You do not have permission to edit this post.');
}
if (isset($input['title'])) {
update_post_meta($post_id, '_yoast_wpseo_title', sanitize_text_field($input['title']));
}
if (isset($input['metaDesc'])) {
update_post_meta($post_id, '_yoast_wpseo_metadesc', sanitize_textarea_field($input['metaDesc']));
}
if (isset($input['focusKeyphrase'])) {
update_post_meta($post_id, '_yoast_wpseo_focuskw', sanitize_text_field($input['focusKeyphrase']));
}
return [
'success' => true,
'post' => get_post($post_id),
];
}
]);
});
Create a config.json in the skill directory:
{
"wordpress": {
"graphql_url": "https://your-site.com/graphql",
"username": "your-username",
"app_password": "your-app-password"
},
"batch": {
"size": 10,
"delay_seconds": 1
},
"state_file": "./seo_update_progress.json"
}
Or use environment variables:
WP_GRAPHQL_URLWP_USERNAMEWP_APP_PASSWORDpython scripts/analyze_seo.py --all --output analysis.json
This fetches posts and identifies SEO issues (missing titles, too long descriptions, etc.). Output includes instructions for Claude to generate optimized SEO content.
Claude analyzes the analysis.json output and generates a changes.json file with:
python scripts/preview_changes.py --input changes.json
python scripts/yoast_batch_updater.py --input changes.json --apply
python scripts/yoast_batch_updater.py --resume
The skill expects a JSON file with changes:
{
"updates": [
{
"post_id": 123,
"post_title": "Original Post Title",
"current": {
"seo_title": "Old Title | Site Name",
"meta_desc": "Old description"
},
"new": {
"seo_title": "New Optimized Title | Site Name",
"meta_desc": "New compelling meta description under 160 chars"
}
}
]
}
The skill produces:
User: "Update the meta descriptions for all posts in the 'tutorials' category to be more compelling"
Claude will:
analyze_seo.py to fetch posts and identify SEO issueschanges.json file with the improvementspreview_changes.py to show before/after comparisonyoast_batch_updater.py --apply to apply changes