@jgardner04/ghost-mcp-server 1.12.0 → 1.12.1
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/README.md +199 -43
- package/package.json +2 -1
- package/src/__tests__/mcp_server_improved.test.js +69 -7
- package/src/mcp_server_improved.js +31 -58
- package/src/schemas/__tests__/memberSchemas.test.js +447 -0
- package/src/schemas/__tests__/newsletterSchemas.test.js +399 -0
- package/src/schemas/__tests__/pageSchemas.test.js +518 -0
- package/src/schemas/__tests__/tierSchemas.test.js +574 -0
|
@@ -40,13 +40,17 @@ dotenv.config();
|
|
|
40
40
|
// Lazy-loaded modules (to avoid Node.js v25 Buffer compatibility issues at startup)
|
|
41
41
|
let ghostService = null;
|
|
42
42
|
let postService = null;
|
|
43
|
+
let pageService = null;
|
|
44
|
+
let newsletterService = null;
|
|
43
45
|
let imageProcessingService = null;
|
|
44
46
|
let urlValidator = null;
|
|
45
47
|
|
|
46
48
|
const loadServices = async () => {
|
|
47
49
|
if (!ghostService) {
|
|
48
|
-
ghostService = await import('./services/
|
|
50
|
+
ghostService = await import('./services/ghostServiceImproved.js');
|
|
49
51
|
postService = await import('./services/postService.js');
|
|
52
|
+
pageService = await import('./services/pageService.js');
|
|
53
|
+
newsletterService = await import('./services/newsletterService.js');
|
|
50
54
|
imageProcessingService = await import('./services/imageProcessingService.js');
|
|
51
55
|
urlValidator = await import('./utils/urlValidator.js');
|
|
52
56
|
}
|
|
@@ -193,8 +197,7 @@ server.tool(
|
|
|
193
197
|
const identifier = slug ? `slug/${slug}` : id;
|
|
194
198
|
const options = include ? { include } : {};
|
|
195
199
|
|
|
196
|
-
const
|
|
197
|
-
const tag = await ghostServiceImproved.getTag(identifier, options);
|
|
200
|
+
const tag = await ghostService.getTag(identifier, options);
|
|
198
201
|
console.error(`Tag retrieved successfully. Tag ID: ${tag.id}`);
|
|
199
202
|
|
|
200
203
|
return {
|
|
@@ -240,8 +243,7 @@ server.tool(
|
|
|
240
243
|
// Build update data object with only provided fields (exclude id from update data)
|
|
241
244
|
const { id, ...updateData } = input;
|
|
242
245
|
|
|
243
|
-
const
|
|
244
|
-
const updatedTag = await ghostServiceImproved.updateTag(id, updateData);
|
|
246
|
+
const updatedTag = await ghostService.updateTag(id, updateData);
|
|
245
247
|
console.error(`Tag updated successfully. Tag ID: ${updatedTag.id}`);
|
|
246
248
|
|
|
247
249
|
return {
|
|
@@ -284,8 +286,7 @@ server.tool(
|
|
|
284
286
|
|
|
285
287
|
await loadServices();
|
|
286
288
|
|
|
287
|
-
|
|
288
|
-
await ghostServiceImproved.deleteTag(id);
|
|
289
|
+
await ghostService.deleteTag(id);
|
|
289
290
|
console.error(`Tag deleted successfully. Tag ID: ${id}`);
|
|
290
291
|
|
|
291
292
|
return {
|
|
@@ -591,9 +592,7 @@ server.tool(
|
|
|
591
592
|
if (input.status !== undefined) options.status = input.status;
|
|
592
593
|
if (input.limit !== undefined) options.limit = input.limit;
|
|
593
594
|
|
|
594
|
-
|
|
595
|
-
const ghostServiceImproved = await import('./services/ghostServiceImproved.js');
|
|
596
|
-
const posts = await ghostServiceImproved.searchPosts(input.query, options);
|
|
595
|
+
const posts = await ghostService.searchPosts(input.query, options);
|
|
597
596
|
console.error(`Found ${posts.length} posts matching "${input.query}".`);
|
|
598
597
|
|
|
599
598
|
return {
|
|
@@ -635,9 +634,7 @@ server.tool(
|
|
|
635
634
|
// Extract ID from input and build update data
|
|
636
635
|
const { id, ...updateData } = input;
|
|
637
636
|
|
|
638
|
-
|
|
639
|
-
const ghostServiceImproved = await import('./services/ghostServiceImproved.js');
|
|
640
|
-
const updatedPost = await ghostServiceImproved.updatePost(id, updateData);
|
|
637
|
+
const updatedPost = await ghostService.updatePost(id, updateData);
|
|
641
638
|
console.error(`Post updated successfully. Post ID: ${updatedPost.id}`);
|
|
642
639
|
|
|
643
640
|
return {
|
|
@@ -676,9 +673,7 @@ server.tool(
|
|
|
676
673
|
try {
|
|
677
674
|
await loadServices();
|
|
678
675
|
|
|
679
|
-
|
|
680
|
-
const ghostServiceImproved = await import('./services/ghostServiceImproved.js');
|
|
681
|
-
await ghostServiceImproved.deletePost(id);
|
|
676
|
+
await ghostService.deletePost(id);
|
|
682
677
|
console.error(`Post deleted successfully. Post ID: ${id}`);
|
|
683
678
|
|
|
684
679
|
return {
|
|
@@ -767,8 +762,7 @@ server.tool(
|
|
|
767
762
|
if (input.formats !== undefined) options.formats = input.formats;
|
|
768
763
|
if (input.order !== undefined) options.order = input.order;
|
|
769
764
|
|
|
770
|
-
const
|
|
771
|
-
const pages = await ghostServiceImproved.getPages(options);
|
|
765
|
+
const pages = await ghostService.getPages(options);
|
|
772
766
|
console.error(`Retrieved ${pages.length} pages from Ghost.`);
|
|
773
767
|
|
|
774
768
|
return {
|
|
@@ -812,8 +806,7 @@ server.tool(
|
|
|
812
806
|
|
|
813
807
|
const identifier = input.id || `slug/${input.slug}`;
|
|
814
808
|
|
|
815
|
-
const
|
|
816
|
-
const page = await ghostServiceImproved.getPage(identifier, options);
|
|
809
|
+
const page = await ghostService.getPage(identifier, options);
|
|
817
810
|
console.error(`Retrieved page: ${page.title} (ID: ${page.id})`);
|
|
818
811
|
|
|
819
812
|
return {
|
|
@@ -852,7 +845,6 @@ server.tool(
|
|
|
852
845
|
try {
|
|
853
846
|
await loadServices();
|
|
854
847
|
|
|
855
|
-
const pageService = await import('./services/pageService.js');
|
|
856
848
|
const createdPage = await pageService.createPageService(input);
|
|
857
849
|
console.error(`Page created successfully. Page ID: ${createdPage.id}`);
|
|
858
850
|
|
|
@@ -894,8 +886,7 @@ server.tool(
|
|
|
894
886
|
|
|
895
887
|
const { id, ...updateData } = input;
|
|
896
888
|
|
|
897
|
-
const
|
|
898
|
-
const updatedPage = await ghostServiceImproved.updatePage(id, updateData);
|
|
889
|
+
const updatedPage = await ghostService.updatePage(id, updateData);
|
|
899
890
|
console.error(`Page updated successfully. Page ID: ${updatedPage.id}`);
|
|
900
891
|
|
|
901
892
|
return {
|
|
@@ -934,8 +925,7 @@ server.tool(
|
|
|
934
925
|
try {
|
|
935
926
|
await loadServices();
|
|
936
927
|
|
|
937
|
-
|
|
938
|
-
await ghostServiceImproved.deletePage(id);
|
|
928
|
+
await ghostService.deletePage(id);
|
|
939
929
|
console.error(`Page deleted successfully. Page ID: ${id}`);
|
|
940
930
|
|
|
941
931
|
return {
|
|
@@ -978,8 +968,7 @@ server.tool(
|
|
|
978
968
|
if (input.status !== undefined) options.status = input.status;
|
|
979
969
|
if (input.limit !== undefined) options.limit = input.limit;
|
|
980
970
|
|
|
981
|
-
const
|
|
982
|
-
const pages = await ghostServiceImproved.searchPages(input.query, options);
|
|
971
|
+
const pages = await ghostService.searchPages(input.query, options);
|
|
983
972
|
console.error(`Found ${pages.length} pages matching "${input.query}".`);
|
|
984
973
|
|
|
985
974
|
return {
|
|
@@ -1046,8 +1035,7 @@ server.tool(
|
|
|
1046
1035
|
try {
|
|
1047
1036
|
await loadServices();
|
|
1048
1037
|
|
|
1049
|
-
const
|
|
1050
|
-
const createdMember = await ghostServiceImproved.createMember(input);
|
|
1038
|
+
const createdMember = await ghostService.createMember(input);
|
|
1051
1039
|
console.error(`Member created successfully. Member ID: ${createdMember.id}`);
|
|
1052
1040
|
|
|
1053
1041
|
return {
|
|
@@ -1088,8 +1076,7 @@ server.tool(
|
|
|
1088
1076
|
|
|
1089
1077
|
const { id, ...updateData } = input;
|
|
1090
1078
|
|
|
1091
|
-
const
|
|
1092
|
-
const updatedMember = await ghostServiceImproved.updateMember(id, updateData);
|
|
1079
|
+
const updatedMember = await ghostService.updateMember(id, updateData);
|
|
1093
1080
|
console.error(`Member updated successfully. Member ID: ${updatedMember.id}`);
|
|
1094
1081
|
|
|
1095
1082
|
return {
|
|
@@ -1128,8 +1115,7 @@ server.tool(
|
|
|
1128
1115
|
try {
|
|
1129
1116
|
await loadServices();
|
|
1130
1117
|
|
|
1131
|
-
|
|
1132
|
-
await ghostServiceImproved.deleteMember(id);
|
|
1118
|
+
await ghostService.deleteMember(id);
|
|
1133
1119
|
console.error(`Member deleted successfully. Member ID: ${id}`);
|
|
1134
1120
|
|
|
1135
1121
|
return {
|
|
@@ -1175,8 +1161,7 @@ server.tool(
|
|
|
1175
1161
|
if (input.order !== undefined) options.order = input.order;
|
|
1176
1162
|
if (input.include !== undefined) options.include = input.include;
|
|
1177
1163
|
|
|
1178
|
-
const
|
|
1179
|
-
const members = await ghostServiceImproved.getMembers(options);
|
|
1164
|
+
const members = await ghostService.getMembers(options);
|
|
1180
1165
|
console.error(`Retrieved ${members.length} members from Ghost.`);
|
|
1181
1166
|
|
|
1182
1167
|
return {
|
|
@@ -1215,8 +1200,7 @@ server.tool(
|
|
|
1215
1200
|
try {
|
|
1216
1201
|
await loadServices();
|
|
1217
1202
|
|
|
1218
|
-
const
|
|
1219
|
-
const member = await ghostServiceImproved.getMember({ id, email });
|
|
1203
|
+
const member = await ghostService.getMember({ id, email });
|
|
1220
1204
|
console.error(`Retrieved member: ${member.email} (ID: ${member.id})`);
|
|
1221
1205
|
|
|
1222
1206
|
return {
|
|
@@ -1258,8 +1242,7 @@ server.tool(
|
|
|
1258
1242
|
const options = {};
|
|
1259
1243
|
if (limit !== undefined) options.limit = limit;
|
|
1260
1244
|
|
|
1261
|
-
const
|
|
1262
|
-
const members = await ghostServiceImproved.searchMembers(query, options);
|
|
1245
|
+
const members = await ghostService.searchMembers(query, options);
|
|
1263
1246
|
console.error(`Found ${members.length} members matching "${query}".`);
|
|
1264
1247
|
|
|
1265
1248
|
return {
|
|
@@ -1313,8 +1296,7 @@ server.tool(
|
|
|
1313
1296
|
if (input.filter !== undefined) options.filter = input.filter;
|
|
1314
1297
|
if (input.order !== undefined) options.order = input.order;
|
|
1315
1298
|
|
|
1316
|
-
const
|
|
1317
|
-
const newsletters = await ghostServiceImproved.getNewsletters(options);
|
|
1299
|
+
const newsletters = await ghostService.getNewsletters(options);
|
|
1318
1300
|
console.error(`Retrieved ${newsletters.length} newsletters from Ghost.`);
|
|
1319
1301
|
|
|
1320
1302
|
return {
|
|
@@ -1353,8 +1335,7 @@ server.tool(
|
|
|
1353
1335
|
try {
|
|
1354
1336
|
await loadServices();
|
|
1355
1337
|
|
|
1356
|
-
const
|
|
1357
|
-
const newsletter = await ghostServiceImproved.getNewsletter(id);
|
|
1338
|
+
const newsletter = await ghostService.getNewsletter(id);
|
|
1358
1339
|
console.error(`Retrieved newsletter: ${newsletter.name} (ID: ${newsletter.id})`);
|
|
1359
1340
|
|
|
1360
1341
|
return {
|
|
@@ -1397,7 +1378,6 @@ server.tool(
|
|
|
1397
1378
|
try {
|
|
1398
1379
|
await loadServices();
|
|
1399
1380
|
|
|
1400
|
-
const newsletterService = await import('./services/newsletterService.js');
|
|
1401
1381
|
const createdNewsletter = await newsletterService.createNewsletterService(input);
|
|
1402
1382
|
console.error(`Newsletter created successfully. Newsletter ID: ${createdNewsletter.id}`);
|
|
1403
1383
|
|
|
@@ -1443,8 +1423,7 @@ server.tool(
|
|
|
1443
1423
|
|
|
1444
1424
|
const { id, ...updateData } = input;
|
|
1445
1425
|
|
|
1446
|
-
const
|
|
1447
|
-
const updatedNewsletter = await ghostServiceImproved.updateNewsletter(id, updateData);
|
|
1426
|
+
const updatedNewsletter = await ghostService.updateNewsletter(id, updateData);
|
|
1448
1427
|
console.error(`Newsletter updated successfully. Newsletter ID: ${updatedNewsletter.id}`);
|
|
1449
1428
|
|
|
1450
1429
|
return {
|
|
@@ -1487,8 +1466,7 @@ server.tool(
|
|
|
1487
1466
|
try {
|
|
1488
1467
|
await loadServices();
|
|
1489
1468
|
|
|
1490
|
-
|
|
1491
|
-
await ghostServiceImproved.deleteNewsletter(id);
|
|
1469
|
+
await ghostService.deleteNewsletter(id);
|
|
1492
1470
|
console.error(`Newsletter deleted successfully. Newsletter ID: ${id}`);
|
|
1493
1471
|
|
|
1494
1472
|
return {
|
|
@@ -1534,8 +1512,7 @@ server.tool(
|
|
|
1534
1512
|
try {
|
|
1535
1513
|
await loadServices();
|
|
1536
1514
|
|
|
1537
|
-
const
|
|
1538
|
-
const tiers = await ghostServiceImproved.getTiers(input);
|
|
1515
|
+
const tiers = await ghostService.getTiers(input);
|
|
1539
1516
|
console.error(`Retrieved ${tiers.length} tiers`);
|
|
1540
1517
|
|
|
1541
1518
|
return {
|
|
@@ -1574,8 +1551,7 @@ server.tool(
|
|
|
1574
1551
|
try {
|
|
1575
1552
|
await loadServices();
|
|
1576
1553
|
|
|
1577
|
-
const
|
|
1578
|
-
const tier = await ghostServiceImproved.getTier(id);
|
|
1554
|
+
const tier = await ghostService.getTier(id);
|
|
1579
1555
|
console.error(`Tier retrieved successfully. Tier ID: ${tier.id}`);
|
|
1580
1556
|
|
|
1581
1557
|
return {
|
|
@@ -1614,8 +1590,7 @@ server.tool(
|
|
|
1614
1590
|
try {
|
|
1615
1591
|
await loadServices();
|
|
1616
1592
|
|
|
1617
|
-
const
|
|
1618
|
-
const tier = await ghostServiceImproved.createTier(input);
|
|
1593
|
+
const tier = await ghostService.createTier(input);
|
|
1619
1594
|
console.error(`Tier created successfully. Tier ID: ${tier.id}`);
|
|
1620
1595
|
|
|
1621
1596
|
return {
|
|
@@ -1656,8 +1631,7 @@ server.tool(
|
|
|
1656
1631
|
|
|
1657
1632
|
const { id, ...updateData } = input;
|
|
1658
1633
|
|
|
1659
|
-
const
|
|
1660
|
-
const updatedTier = await ghostServiceImproved.updateTier(id, updateData);
|
|
1634
|
+
const updatedTier = await ghostService.updateTier(id, updateData);
|
|
1661
1635
|
console.error(`Tier updated successfully. Tier ID: ${updatedTier.id}`);
|
|
1662
1636
|
|
|
1663
1637
|
return {
|
|
@@ -1696,8 +1670,7 @@ server.tool(
|
|
|
1696
1670
|
try {
|
|
1697
1671
|
await loadServices();
|
|
1698
1672
|
|
|
1699
|
-
|
|
1700
|
-
await ghostServiceImproved.deleteTier(id);
|
|
1673
|
+
await ghostService.deleteTier(id);
|
|
1701
1674
|
console.error(`Tier deleted successfully. Tier ID: ${id}`);
|
|
1702
1675
|
|
|
1703
1676
|
return {
|