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-llms-txt.php

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

325 lines 10.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * MCP Tools: LLMs.txt & markdown export.
4 *
5 * Provides 5 tools:
6 * - wordpress_get_llms_txt
7 * - wordpress_regenerate_llms_txt
8 * - wordpress_get_llms_txt_settings
9 * - wordpress_update_llms_txt_settings
10 * - wordpress_get_post_markdown
11 *
12 * @package MetaSync
13 * @subpackage MCP_Server/Tools
14 */
15
16 if (!defined('ABSPATH')) {
17 exit;
18 }
19
20 /**
21 * Internal helper: locate and require generator/converter classes.
22 */
23 if (!function_exists('metasync_llms_require_dependencies')) {
24 function metasync_llms_require_dependencies() {
25 $base = plugin_dir_path(dirname(dirname(__FILE__)));
26 if (!class_exists('Metasync_Html_To_Markdown')) {
27 $file = $base . 'includes/class-metasync-html-to-markdown.php';
28 if (file_exists($file)) {
29 require_once $file;
30 }
31 }
32 if (!class_exists('Metasync_Llms_Txt_Generator')) {
33 $file = $base . 'llms-txt/class-metasync-llms-txt-generator.php';
34 if (file_exists($file)) {
35 require_once $file;
36 }
37 }
38 }
39 }
40
41 class MCP_Tool_Get_LLMs_Txt extends MCP_Tool_Base
42 {
43 public function get_name() {
44 return 'wordpress_get_llms_txt';
45 }
46
47 public function get_description() {
48 return 'Return the current generated /llms.txt content (from cache if available).';
49 }
50
51 public function get_input_schema() {
52 return [
53 'type' => 'object',
54 'properties' => [
55 'full' => [
56 'type' => 'boolean',
57 'description' => 'If true, return /llms-full.txt content instead.',
58 'default' => false,
59 ],
60 ],
61 'required' => [],
62 ];
63 }
64
65 public function execute($params) {
66 $this->validate_params($params);
67 $this->require_capability('manage_options');
68 metasync_llms_require_dependencies();
69
70 $full = isset($params['full']) ? (bool) $params['full'] : false;
71 $key = $full ? Metasync_Llms_Txt_Generator::TRANSIENT_FULL : Metasync_Llms_Txt_Generator::TRANSIENT_SHORT;
72
73 $content = get_transient($key);
74 if (false === $content || $content === '') {
75 $generator = new Metasync_Llms_Txt_Generator();
76 $content = $full ? $generator->generate_full() : $generator->generate();
77 if ($content !== '') {
78 set_transient($key, $content, Metasync_Llms_Txt_Generator::CACHE_TTL);
79 }
80 }
81
82 return $this->success([
83 'content' => $content,
84 'full' => $full,
85 ]);
86 }
87 }
88
89 class MCP_Tool_Regenerate_LLMs_Txt extends MCP_Tool_Base
90 {
91 public function get_name() {
92 return 'wordpress_regenerate_llms_txt';
93 }
94
95 public function get_description() {
96 return 'Force a regeneration of the /llms.txt cache (and /llms-full.txt if enabled).';
97 }
98
99 public function get_input_schema() {
100 return [
101 'type' => 'object',
102 'properties' => new \stdClass(),
103 'required' => [],
104 ];
105 }
106
107 public function execute($params) {
108 $this->validate_params($params);
109 $this->require_capability('manage_options');
110 metasync_llms_require_dependencies();
111
112 delete_transient(Metasync_Llms_Txt_Generator::TRANSIENT_SHORT);
113 delete_transient(Metasync_Llms_Txt_Generator::TRANSIENT_FULL);
114
115 $generator = new Metasync_Llms_Txt_Generator();
116 $short = $generator->generate();
117 if ($short !== '') {
118 set_transient(Metasync_Llms_Txt_Generator::TRANSIENT_SHORT, $short, Metasync_Llms_Txt_Generator::CACHE_TTL);
119 }
120
121 $settings = $generator->get_settings();
122 $full = '';
123 if (!empty($settings['llms_full_enabled'])) {
124 $full = $generator->generate_full();
125 if ($full !== '') {
126 set_transient(Metasync_Llms_Txt_Generator::TRANSIENT_FULL, $full, Metasync_Llms_Txt_Generator::CACHE_TTL);
127 }
128 }
129
130 return $this->success([
131 'regenerated' => true,
132 'short_bytes' => strlen($short),
133 'full_bytes' => strlen($full),
134 ]);
135 }
136 }
137
138 class MCP_Tool_Get_LLMs_Txt_Settings extends MCP_Tool_Base
139 {
140 public function get_name() {
141 return 'wordpress_get_llms_txt_settings';
142 }
143
144 public function get_description() {
145 return 'Return the stored LLMs.txt settings (enabled, post_types, max_posts, excluded_ids, custom_description, llms_full_enabled).';
146 }
147
148 public function get_input_schema() {
149 return [
150 'type' => 'object',
151 'properties' => new \stdClass(),
152 'required' => [],
153 ];
154 }
155
156 public function execute($params) {
157 $this->validate_params($params);
158 $this->require_capability('manage_options');
159 metasync_llms_require_dependencies();
160
161 $generator = new Metasync_Llms_Txt_Generator();
162 return $this->success([
163 'settings' => $generator->get_settings(),
164 ]);
165 }
166 }
167
168 class MCP_Tool_Update_LLMs_Txt_Settings extends MCP_Tool_Base
169 {
170 public function get_name() {
171 return 'wordpress_update_llms_txt_settings';
172 }
173
174 public function get_description() {
175 return 'Update LLMs.txt settings. Partial updates supported – only provided keys are modified.';
176 }
177
178 public function get_input_schema() {
179 return [
180 'type' => 'object',
181 'properties' => [
182 'enabled' => [
183 'type' => 'boolean',
184 'description' => 'Enable or disable LLMs.txt generation.',
185 ],
186 'post_types' => [
187 'type' => 'array',
188 'description' => 'Post types to include (e.g. ["page","post"]).',
189 'items' => ['type' => 'string'],
190 ],
191 'max_posts' => [
192 'type' => 'integer',
193 'description' => 'Maximum number of posts to include (1-500).',
194 'minimum' => 1,
195 'maximum' => 500,
196 ],
197 'excluded_ids' => [
198 'type' => 'array',
199 'description' => 'Post/page IDs to exclude.',
200 'items' => ['type' => 'integer'],
201 ],
202 'custom_description' => [
203 'type' => 'string',
204 'description' => 'Override for the site tagline.',
205 ],
206 'llms_full_enabled' => [
207 'type' => 'boolean',
208 'description' => 'Serve /llms-full.txt when enabled.',
209 ],
210 'max_posts_full' => [
211 'type' => 'integer',
212 'description' => 'Maximum posts for /llms-full.txt (1-500, default 25).',
213 'minimum' => 1,
214 'maximum' => 500,
215 ],
216 ],
217 'required' => [],
218 ];
219 }
220
221 public function execute($params) {
222 $this->validate_params($params);
223 $this->require_capability('manage_options');
224 metasync_llms_require_dependencies();
225
226 $existing = get_option(Metasync_Llms_Txt_Generator::OPTION_KEY, []);
227 if (!is_array($existing)) {
228 $existing = [];
229 }
230
231 $updated = $existing;
232
233 if (array_key_exists('enabled', $params)) {
234 $updated['enabled'] = (bool) $params['enabled'];
235 }
236 if (array_key_exists('post_types', $params) && is_array($params['post_types'])) {
237 $updated['post_types'] = array_values(array_filter(array_map('sanitize_text_field', $params['post_types'])));
238 }
239 if (array_key_exists('max_posts', $params)) {
240 $val = (int) $params['max_posts'];
241 $updated['max_posts'] = max(1, min(500, $val));
242 }
243 if (array_key_exists('excluded_ids', $params) && is_array($params['excluded_ids'])) {
244 $updated['excluded_ids'] = array_values(array_filter(array_map('absint', $params['excluded_ids'])));
245 }
246 if (array_key_exists('custom_description', $params)) {
247 $updated['custom_description'] = sanitize_text_field((string) $params['custom_description']);
248 }
249 if (array_key_exists('llms_full_enabled', $params)) {
250 $updated['llms_full_enabled'] = (bool) $params['llms_full_enabled'];
251 }
252 if (array_key_exists('max_posts_full', $params)) {
253 $val = (int) $params['max_posts_full'];
254 $updated['max_posts_full'] = max(1, min(500, $val));
255 }
256
257 update_option(Metasync_Llms_Txt_Generator::OPTION_KEY, $updated);
258
259 delete_transient(Metasync_Llms_Txt_Generator::TRANSIENT_SHORT);
260 delete_transient(Metasync_Llms_Txt_Generator::TRANSIENT_FULL);
261
262 return $this->success([
263 'updated' => true,
264 'settings' => $updated,
265 ]);
266 }
267 }
268
269 class MCP_Tool_Get_Post_Markdown extends MCP_Tool_Base
270 {
271 public function get_name() {
272 return 'wordpress_get_post_markdown';
273 }
274
275 public function get_description() {
276 return 'Convert any published post or page to clean markdown using Metasync_Html_To_Markdown.';
277 }
278
279 public function get_input_schema() {
280 return [
281 'type' => 'object',
282 'properties' => [
283 'post_id' => [
284 'type' => 'integer',
285 'description' => 'Post or page ID.',
286 'minimum' => 1,
287 ],
288 'include_frontmatter' => [
289 'type' => 'boolean',
290 'description' => 'Prepend YAML frontmatter (title/slug/date/author).',
291 'default' => true,
292 ],
293 'include_featured_image' => [
294 'type' => 'boolean',
295 'description' => 'Prepend the featured image as a markdown image.',
296 'default' => true,
297 ],
298 ],
299 'required' => ['post_id'],
300 ];
301 }
302
303 public function execute($params) {
304 $this->validate_params($params);
305 $this->require_capability('edit_posts');
306 metasync_llms_require_dependencies();
307
308 $post_id = absint($params['post_id']);
309 $this->verify_post_exists($post_id);
310 $this->check_post_permission($post_id);
311
312 $options = [
313 'include_frontmatter' => isset($params['include_frontmatter']) ? (bool) $params['include_frontmatter'] : true,
314 'include_featured_image' => isset($params['include_featured_image']) ? (bool) $params['include_featured_image'] : true,
315 ];
316
317 $markdown = Metasync_Html_To_Markdown::convert_post($post_id, $options);
318
319 return $this->success([
320 'post_id' => $post_id,
321 'markdown' => $markdown,
322 ]);
323 }
324 }
325