@gravitykit/block-mcp 2.0.1 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +311 -195
- package/package.json +8 -4
- package/src/__tests__/coerce.test.ts +57 -0
- package/src/__tests__/fixtures/error-envelopes.ts +19 -7
- package/src/__tests__/integration/error-envelopes.test.ts +2 -2
- package/src/__tests__/tools/discovery/list_patterns.test.ts +25 -6
- package/src/__tests__/tools/mutate/edit_block_tree.test.ts +53 -0
- package/src/__tests__/tools/patterns/insert_pattern.test.ts +16 -0
- package/src/__tests__/tools/posts/update_post.test.ts +14 -0
- package/src/__tests__/tools/read/get_block.test.ts +35 -0
- package/src/__tests__/tools/read/get_page_blocks.test.ts +18 -0
- package/src/__tests__/tools/write/delete_block.test.ts +18 -0
- package/src/__tests__/tools/write/insert_blocks.test.ts +21 -0
- package/src/__tests__/tools/write/replace_block_range.test.ts +71 -0
- package/src/__tests__/tools/write/rewrite_post_blocks.test.ts +39 -0
- package/src/__tests__/tools/write/update_block.test.ts +16 -0
- package/src/__tests__/tools/write/update_blocks.test.ts +21 -0
- package/src/__tests__/tools/yoast/yoast_get_seo.test.ts +11 -3
- package/src/__tests__/tools/yoast/yoast_update_seo.test.ts +16 -0
- package/src/__tests__/unit/enrichers/cbp-enricher.test.ts +21 -0
- package/src/__tests__/unit/error-translator/translate-wp-error.test.ts +100 -29
- package/src/__tests__/unit/instructions.test.ts +3 -3
- package/src/__tests__/unit/preferences/enrich-pattern-list.test.ts +26 -10
- package/src/__tests__/unit/rest-url.test.ts +23 -0
- package/src/client.ts +53 -18
- package/src/coerce.ts +41 -0
- package/src/config.ts +96 -0
- package/src/connect.ts +17 -3
- package/src/enrichers.ts +6 -2
- package/src/error-translator.ts +62 -10
- package/src/index.ts +35 -27
- package/src/instructions.ts +3 -3
- package/src/preferences.ts +56 -43
- package/src/rest-url.ts +18 -0
- package/src/tools/discovery.ts +10 -14
- package/src/tools/mutate.ts +18 -12
- package/src/tools/patterns.ts +3 -2
- package/src/tools/posts.ts +26 -26
- package/src/tools/read.ts +7 -6
- package/src/tools/write.ts +26 -31
- package/src/tools/yoast.ts +30 -31
- package/src/types.ts +23 -13
package/src/tools/yoast.ts
CHANGED
|
@@ -11,27 +11,24 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import type { WordPressBlockClient } from '../client.js';
|
|
14
|
-
import
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
import { coercePostId } from '../coerce.js';
|
|
15
|
+
import {
|
|
16
|
+
YOAST_SCHEMA_PAGE_TYPES,
|
|
17
|
+
YOAST_SCHEMA_ARTICLE_TYPES,
|
|
18
|
+
YOAST_ROBOTS_ADVANCED,
|
|
19
|
+
type YoastSchemaPageType,
|
|
20
|
+
type YoastSchemaArticleType,
|
|
21
|
+
type YoastRobotsAdvanced,
|
|
22
|
+
type YoastUpdateRequest,
|
|
23
|
+
type YoastBulkUpdateItem,
|
|
20
24
|
} from '../types.js';
|
|
21
25
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const SCHEMA_ARTICLE_TYPES: YoastSchemaArticleType[] = [
|
|
29
|
-
'Article', 'BlogPosting', 'SocialMediaPosting', 'NewsArticle',
|
|
30
|
-
'AdvertiserContentArticle', 'SatiricalArticle', 'ScholarlyArticle',
|
|
31
|
-
'TechArticle', 'Report', 'None',
|
|
32
|
-
];
|
|
33
|
-
|
|
34
|
-
const ROBOTS_ADVANCED: YoastRobotsAdvanced[] = ['noimageindex', 'noarchive', 'nosnippet'];
|
|
26
|
+
// Local aliases: the enum values themselves live in types.ts (single source
|
|
27
|
+
// shared with the TS union types); these names keep the rest of this file
|
|
28
|
+
// unchanged.
|
|
29
|
+
const SCHEMA_PAGE_TYPES = YOAST_SCHEMA_PAGE_TYPES;
|
|
30
|
+
const SCHEMA_ARTICLE_TYPES = YOAST_SCHEMA_ARTICLE_TYPES;
|
|
31
|
+
const ROBOTS_ADVANCED = YOAST_ROBOTS_ADVANCED;
|
|
35
32
|
|
|
36
33
|
/** Field-level schema reused by yoast_update_seo and yoast_bulk_update_seo. */
|
|
37
34
|
const YOAST_FIELD_PROPERTIES = {
|
|
@@ -40,8 +37,8 @@ const YOAST_FIELD_PROPERTIES = {
|
|
|
40
37
|
canonical: { type: 'string', description: 'Canonical URL override.' },
|
|
41
38
|
focus_keyword: { type: 'string', description: 'Focus keyphrase.' },
|
|
42
39
|
noindex: {
|
|
43
|
-
type:
|
|
44
|
-
description: '
|
|
40
|
+
type: 'boolean',
|
|
41
|
+
description: 'true=noindex, false=explicit index. Pass null to reset to the post-type default; omit to leave the current value unchanged. (Advertised as a single boolean type because some AI clients — e.g. Google Gemini — reject a "null" member in a type array; the handler still accepts an explicit null.)',
|
|
45
42
|
},
|
|
46
43
|
nofollow: { type: 'boolean', description: 'true=nofollow, false=follow.' },
|
|
47
44
|
robots_advanced: {
|
|
@@ -132,17 +129,17 @@ export async function handleYoastTool(
|
|
|
132
129
|
): Promise<unknown> {
|
|
133
130
|
switch (toolName) {
|
|
134
131
|
case 'yoast_get_seo': {
|
|
135
|
-
const postId = args.post_id;
|
|
136
|
-
if (
|
|
137
|
-
throw new Error('yoast_get_seo: "post_id"
|
|
132
|
+
const postId = coercePostId(args.post_id, 'yoast_get_seo');
|
|
133
|
+
if (postId === undefined) {
|
|
134
|
+
throw new Error('yoast_get_seo: "post_id" is required');
|
|
138
135
|
}
|
|
139
136
|
return client.getYoastSEO(postId);
|
|
140
137
|
}
|
|
141
138
|
|
|
142
139
|
case 'yoast_update_seo': {
|
|
143
|
-
const postId = args.post_id;
|
|
144
|
-
if (
|
|
145
|
-
throw new Error('yoast_update_seo: "post_id"
|
|
140
|
+
const postId = coercePostId(args.post_id, 'yoast_update_seo');
|
|
141
|
+
if (postId === undefined) {
|
|
142
|
+
throw new Error('yoast_update_seo: "post_id" is required');
|
|
146
143
|
}
|
|
147
144
|
const { post_id: _omit, ...rest } = args;
|
|
148
145
|
void _omit;
|
|
@@ -163,11 +160,13 @@ export async function handleYoastTool(
|
|
|
163
160
|
throw new Error('yoast_bulk_update_seo: each item in `posts` must be an object');
|
|
164
161
|
}
|
|
165
162
|
const obj = raw as Record<string, unknown>;
|
|
166
|
-
|
|
167
|
-
|
|
163
|
+
const id = coercePostId(obj.post_id, 'yoast_bulk_update_seo');
|
|
164
|
+
if (id === undefined) {
|
|
165
|
+
throw new Error('yoast_bulk_update_seo: each item requires `post_id`');
|
|
168
166
|
}
|
|
169
|
-
const { post_id:
|
|
170
|
-
|
|
167
|
+
const { post_id: _omit, ...rest } = obj;
|
|
168
|
+
void _omit;
|
|
169
|
+
items.push({ post_id: id, ...narrowYoastFields(rest) });
|
|
171
170
|
}
|
|
172
171
|
return client.bulkUpdateYoastSEO(items);
|
|
173
172
|
}
|
package/src/types.ts
CHANGED
|
@@ -83,8 +83,8 @@ export interface BlockType {
|
|
|
83
83
|
export interface PatternPreference {
|
|
84
84
|
/** Computed preference score */
|
|
85
85
|
score: number;
|
|
86
|
-
/** Human-readable tier */
|
|
87
|
-
tier: '
|
|
86
|
+
/** Human-readable tier (matches the server: preferred/acceptable/avoid/legacy) */
|
|
87
|
+
tier: 'preferred' | 'acceptable' | 'avoid' | 'legacy';
|
|
88
88
|
/** Reasons contributing to the score */
|
|
89
89
|
reasons: string[];
|
|
90
90
|
}
|
|
@@ -799,17 +799,27 @@ export interface UploadMediaResponse {
|
|
|
799
799
|
// Routes only register when Yoast SEO is active on the target site.
|
|
800
800
|
// ============================================
|
|
801
801
|
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
export
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
export type
|
|
802
|
+
/**
|
|
803
|
+
* Single source of truth for the Yoast schema-page-type enum — the const
|
|
804
|
+
* array backs both the runtime value (JSON Schema `enum`, narrowing filters
|
|
805
|
+
* in src/tools/yoast.ts) and the TS union type below, so the two can't drift.
|
|
806
|
+
*/
|
|
807
|
+
export const YOAST_SCHEMA_PAGE_TYPES = [
|
|
808
|
+
'WebPage', 'ItemPage', 'AboutPage', 'FAQPage', 'QAPage',
|
|
809
|
+
'ProfilePage', 'ContactPage', 'MedicalWebPage', 'CollectionPage',
|
|
810
|
+
'CheckoutPage', 'RealEstateListing', 'SearchResultsPage',
|
|
811
|
+
] as const;
|
|
812
|
+
export type YoastSchemaPageType = typeof YOAST_SCHEMA_PAGE_TYPES[number];
|
|
813
|
+
|
|
814
|
+
export const YOAST_SCHEMA_ARTICLE_TYPES = [
|
|
815
|
+
'Article', 'BlogPosting', 'SocialMediaPosting', 'NewsArticle',
|
|
816
|
+
'AdvertiserContentArticle', 'SatiricalArticle', 'ScholarlyArticle',
|
|
817
|
+
'TechArticle', 'Report', 'None',
|
|
818
|
+
] as const;
|
|
819
|
+
export type YoastSchemaArticleType = typeof YOAST_SCHEMA_ARTICLE_TYPES[number];
|
|
820
|
+
|
|
821
|
+
export const YOAST_ROBOTS_ADVANCED = ['noimageindex', 'noarchive', 'nosnippet'] as const;
|
|
822
|
+
export type YoastRobotsAdvanced = typeof YOAST_ROBOTS_ADVANCED[number];
|
|
813
823
|
|
|
814
824
|
/**
|
|
815
825
|
* Writable Yoast SEO fields. All optional in update payloads — only the
|