PluginProbe
Search Atlas SEO – OTTO AI SEO Automation for WordPress / 2.6.14
Search Atlas SEO – OTTO AI SEO Automation for WordPress v2.6.14
2.7.0 2.6.26 2.6.25 2.6.24 2.6.23 2.6.22 2.6.21 2.6.20 2.6.19 2.6.18 2.6.17 2.6.16 2.6.15 2.6.14 2.6.13 2.6.12 2.6.11 2.6.10 2.6.9 2.6.8 2.6.7 2.6.6 2.6.5 2.6.4 2.6.3 All 139 releases
metasync / wp-mcp-server / tools / class-mcp-tool-seo-inventory.php

class-mcp-tool-seo-inventory.php in Search Atlas SEO – OTTO AI SEO Automation for WordPress 2.6.14, at wp-mcp-server/tools/class-mcp-tool-seo-inventory.php

97 lines 3.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * MCP Tool: SEO Inventory
4 *
5 * Bulk-fetches all posts/pages with their SEO metadata.
6 * Delegates to Metasync_SEO_Inventory_Builder so the logic
7 * is shared with the REST endpoint.
8 *
9 * @package MetaSync
10 * @subpackage MCP_Server/Tools
11 */
12
13 if (!defined('ABSPATH')) {
14 exit;
15 }
16
17 class MCP_Tool_List_Posts_SEO_Inventory extends MCP_Tool_Base {
18
19 public function get_name() {
20 return 'wordpress_list_posts_seo_inventory';
21 }
22
23 public function get_description() {
24 return 'Bulk list all posts/pages with their full SEO metadata (title, description, OG, twitter, schema, issue flags) — no crawling needed';
25 }
26
27 public function get_input_schema() {
28 return [
29 'type' => 'object',
30 'properties' => [
31 'post_type' => [
32 'type' => 'string',
33 'description' => 'Filter by post type',
34 'enum' => ['post', 'page', 'any'],
35 'default' => 'any',
36 ],
37 'post_status' => [
38 'type' => 'string',
39 'description' => 'Filter by post status',
40 'enum' => ['publish', 'draft', 'pending', 'private', 'any'],
41 'default' => 'publish',
42 ],
43 'limit' => [
44 'type' => 'integer',
45 'description' => 'Items per page (max 500)',
46 'default' => 200,
47 'minimum' => 1,
48 'maximum' => 500,
49 ],
50 'cursor' => [
51 'type' => 'integer',
52 'description' => 'Post ID to start after (use next_cursor from previous response)',
53 'default' => 0,
54 'minimum' => 0,
55 ],
56 'include_issues' => [
57 'type' => 'boolean',
58 'description' => 'Include pre-computed SEO issue flags per post',
59 'default' => true,
60 ],
61 'modified_after' => [
62 'type' => 'string',
63 'description' => 'Only return posts modified after this ISO 8601 date (e.g. 2026-03-01T00:00:00Z)',
64 ],
65 ],
66 'required' => [],
67 ];
68 }
69
70 public function execute($params) {
71 $this->validate_params($params);
72 $this->require_capability('read');
73
74 // Sanitize BEFORE the security check so trimming can't bypass it
75 $post_status = isset($params['post_status']) ? sanitize_text_field($params['post_status']) : 'publish';
76
77 // Sensitive statuses require edit_posts capability
78 $sensitive_statuses = ['private', 'draft', 'pending', 'any'];
79 if (in_array($post_status, $sensitive_statuses, true)) {
80 $this->require_capability('edit_posts');
81 }
82
83 $args = [
84 'post_type' => isset($params['post_type']) ? sanitize_text_field($params['post_type']) : 'any',
85 'post_status' => $post_status,
86 'limit' => isset($params['limit']) ? absint($params['limit']) : Metasync_SEO_Inventory_Builder::DEFAULT_LIMIT,
87 'cursor' => isset($params['cursor']) ? absint($params['cursor']) : 0,
88 'include_issues' => isset($params['include_issues']) ? (bool) $params['include_issues'] : true,
89 'modified_after' => isset($params['modified_after']) ? sanitize_text_field($params['modified_after']) : '',
90 ];
91
92 $result = Metasync_SEO_Inventory_Builder::build($args);
93
94 return $this->success($result);
95 }
96 }
97