@jgardner04/ghost-mcp-server 1.12.1 → 1.12.2
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/package.json
CHANGED
|
@@ -394,10 +394,11 @@ describe('mcp_server_improved - ghost_get_post tool', () => {
|
|
|
394
394
|
expect(tool).toBeDefined();
|
|
395
395
|
expect(tool.description).toContain('post');
|
|
396
396
|
expect(tool.schema).toBeDefined();
|
|
397
|
-
//
|
|
398
|
-
|
|
399
|
-
expect(
|
|
400
|
-
expect(
|
|
397
|
+
// ghost_get_post uses a refined schema, access via _def.schema.shape
|
|
398
|
+
const shape = tool.schema._def.schema.shape;
|
|
399
|
+
expect(shape.id).toBeDefined();
|
|
400
|
+
expect(shape.slug).toBeDefined();
|
|
401
|
+
expect(shape.include).toBeDefined();
|
|
401
402
|
});
|
|
402
403
|
|
|
403
404
|
it('should retrieve post by ID', async () => {
|
|
@@ -1027,10 +1028,11 @@ describe('ghost_get_tag', () => {
|
|
|
1027
1028
|
|
|
1028
1029
|
it('should have correct schema with id and slug as optional', () => {
|
|
1029
1030
|
const tool = mockTools.get('ghost_get_tag');
|
|
1030
|
-
//
|
|
1031
|
-
|
|
1032
|
-
expect(
|
|
1033
|
-
expect(
|
|
1031
|
+
// ghost_get_tag uses a refined schema, access via _def.schema.shape
|
|
1032
|
+
const shape = tool.schema._def.schema.shape;
|
|
1033
|
+
expect(shape.id).toBeDefined();
|
|
1034
|
+
expect(shape.slug).toBeDefined();
|
|
1035
|
+
expect(shape.include).toBeDefined();
|
|
1034
1036
|
});
|
|
1035
1037
|
|
|
1036
1038
|
it('should retrieve tag by ID', async () => {
|
|
@@ -1089,7 +1091,7 @@ describe('ghost_get_tag', () => {
|
|
|
1089
1091
|
const result = await tool.handler({});
|
|
1090
1092
|
|
|
1091
1093
|
expect(result.content[0].type).toBe('text');
|
|
1092
|
-
expect(result.content[0].text).toContain('Either id or slug
|
|
1094
|
+
expect(result.content[0].text).toContain('Either id or slug is required');
|
|
1093
1095
|
expect(result.isError).toBe(true);
|
|
1094
1096
|
});
|
|
1095
1097
|
|
package/src/errors/index.js
CHANGED
|
@@ -40,6 +40,13 @@ export class ValidationError extends BaseError {
|
|
|
40
40
|
this.errors = errors;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
toJSON() {
|
|
44
|
+
return {
|
|
45
|
+
...super.toJSON(),
|
|
46
|
+
...(this.errors.length > 0 && { errors: this.errors }),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
43
50
|
static fromJoi(joiError) {
|
|
44
51
|
const errors = joiError.details.map((detail) => ({
|
|
45
52
|
field: detail.path.join('.'),
|
|
@@ -82,11 +82,18 @@ const server = new McpServer({
|
|
|
82
82
|
|
|
83
83
|
// --- Schema Definitions for Tools ---
|
|
84
84
|
const getTagsSchema = tagQuerySchema.partial();
|
|
85
|
-
const getTagSchema = z
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
85
|
+
const getTagSchema = z
|
|
86
|
+
.object({
|
|
87
|
+
id: ghostIdSchema.optional().describe('The ID of the tag to retrieve.'),
|
|
88
|
+
slug: z.string().optional().describe('The slug of the tag to retrieve.'),
|
|
89
|
+
include: z
|
|
90
|
+
.string()
|
|
91
|
+
.optional()
|
|
92
|
+
.describe('Additional resources to include (e.g., "count.posts").'),
|
|
93
|
+
})
|
|
94
|
+
.refine((data) => data.id || data.slug, {
|
|
95
|
+
message: 'Either id or slug is required to retrieve a tag',
|
|
96
|
+
});
|
|
90
97
|
const updateTagInputSchema = updateTagSchema.extend({ id: ghostIdSchema });
|
|
91
98
|
const deleteTagSchema = z.object({ id: ghostIdSchema });
|
|
92
99
|
|
|
@@ -187,10 +194,6 @@ server.tool(
|
|
|
187
194
|
|
|
188
195
|
console.error(`Executing tool: ghost_get_tag`);
|
|
189
196
|
try {
|
|
190
|
-
if (!id && !slug) {
|
|
191
|
-
throw new Error('Either id or slug must be provided');
|
|
192
|
-
}
|
|
193
|
-
|
|
194
197
|
await loadServices();
|
|
195
198
|
|
|
196
199
|
// If slug is provided, use the slug/slug-name format
|
|
@@ -409,14 +412,18 @@ const getPostsSchema = postQuerySchema.extend({
|
|
|
409
412
|
.optional()
|
|
410
413
|
.describe('Filter posts by status. Options: published, draft, scheduled, all.'),
|
|
411
414
|
});
|
|
412
|
-
const getPostSchema = z
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
415
|
+
const getPostSchema = z
|
|
416
|
+
.object({
|
|
417
|
+
id: ghostIdSchema.optional().describe('The ID of the post to retrieve.'),
|
|
418
|
+
slug: z.string().optional().describe('The slug of the post to retrieve.'),
|
|
419
|
+
include: z
|
|
420
|
+
.string()
|
|
421
|
+
.optional()
|
|
422
|
+
.describe('Comma-separated list of relations to include (e.g., "tags,authors").'),
|
|
423
|
+
})
|
|
424
|
+
.refine((data) => data.id || data.slug, {
|
|
425
|
+
message: 'Either id or slug is required to retrieve a post',
|
|
426
|
+
});
|
|
420
427
|
const searchPostsSchema = z.object({
|
|
421
428
|
query: z.string().min(1).describe('Search query to find in post titles.'),
|
|
422
429
|
status: z
|
|
@@ -534,11 +541,6 @@ server.tool(
|
|
|
534
541
|
|
|
535
542
|
console.error(`Executing tool: ghost_get_post`);
|
|
536
543
|
try {
|
|
537
|
-
// Validate that at least one of id or slug is provided
|
|
538
|
-
if (!input.id && !input.slug) {
|
|
539
|
-
throw new Error('Either id or slug is required to retrieve a post');
|
|
540
|
-
}
|
|
541
|
-
|
|
542
544
|
await loadServices();
|
|
543
545
|
|
|
544
546
|
// Build options object
|