@antoinefamibelle/ghost-mcp 1.0.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.
Files changed (106) hide show
  1. package/README.md +286 -0
  2. package/build/client.d.ts +8 -0
  3. package/build/client.d.ts.map +1 -0
  4. package/build/client.js +28 -0
  5. package/build/client.js.map +1 -0
  6. package/build/config.d.ts +6 -0
  7. package/build/config.d.ts.map +1 -0
  8. package/build/config.js +17 -0
  9. package/build/config.js.map +1 -0
  10. package/build/errors.d.ts +14 -0
  11. package/build/errors.d.ts.map +1 -0
  12. package/build/errors.js +34 -0
  13. package/build/errors.js.map +1 -0
  14. package/build/prompts/content-audit.d.ts +3 -0
  15. package/build/prompts/content-audit.d.ts.map +1 -0
  16. package/build/prompts/content-audit.js +74 -0
  17. package/build/prompts/content-audit.js.map +1 -0
  18. package/build/prompts/index.d.ts +3 -0
  19. package/build/prompts/index.d.ts.map +1 -0
  20. package/build/prompts/index.js +10 -0
  21. package/build/prompts/index.js.map +1 -0
  22. package/build/prompts/summarize-post.d.ts +3 -0
  23. package/build/prompts/summarize-post.d.ts.map +1 -0
  24. package/build/prompts/summarize-post.js +33 -0
  25. package/build/prompts/summarize-post.js.map +1 -0
  26. package/build/resources/blog.d.ts +3 -0
  27. package/build/resources/blog.d.ts.map +1 -0
  28. package/build/resources/blog.js +18 -0
  29. package/build/resources/blog.js.map +1 -0
  30. package/build/resources/index.d.ts +8 -0
  31. package/build/resources/index.d.ts.map +1 -0
  32. package/build/resources/index.js +18 -0
  33. package/build/resources/index.js.map +1 -0
  34. package/build/resources/members.d.ts +3 -0
  35. package/build/resources/members.d.ts.map +1 -0
  36. package/build/resources/members.js +23 -0
  37. package/build/resources/members.js.map +1 -0
  38. package/build/resources/newsletters.d.ts +3 -0
  39. package/build/resources/newsletters.d.ts.map +1 -0
  40. package/build/resources/newsletters.js +23 -0
  41. package/build/resources/newsletters.js.map +1 -0
  42. package/build/resources/offers.d.ts +3 -0
  43. package/build/resources/offers.d.ts.map +1 -0
  44. package/build/resources/offers.js +23 -0
  45. package/build/resources/offers.js.map +1 -0
  46. package/build/resources/posts.d.ts +3 -0
  47. package/build/resources/posts.d.ts.map +1 -0
  48. package/build/resources/posts.js +23 -0
  49. package/build/resources/posts.js.map +1 -0
  50. package/build/resources/tiers.d.ts +3 -0
  51. package/build/resources/tiers.d.ts.map +1 -0
  52. package/build/resources/tiers.js +26 -0
  53. package/build/resources/tiers.js.map +1 -0
  54. package/build/resources/users.d.ts +3 -0
  55. package/build/resources/users.d.ts.map +1 -0
  56. package/build/resources/users.js +23 -0
  57. package/build/resources/users.js.map +1 -0
  58. package/build/server.d.ts +3 -0
  59. package/build/server.d.ts.map +1 -0
  60. package/build/server.js +54 -0
  61. package/build/server.js.map +1 -0
  62. package/build/tools/invites.d.ts +3 -0
  63. package/build/tools/invites.d.ts.map +1 -0
  64. package/build/tools/invites.js +46 -0
  65. package/build/tools/invites.js.map +1 -0
  66. package/build/tools/members.d.ts +3 -0
  67. package/build/tools/members.d.ts.map +1 -0
  68. package/build/tools/members.js +93 -0
  69. package/build/tools/members.js.map +1 -0
  70. package/build/tools/newsletters.d.ts +3 -0
  71. package/build/tools/newsletters.d.ts.map +1 -0
  72. package/build/tools/newsletters.js +108 -0
  73. package/build/tools/newsletters.js.map +1 -0
  74. package/build/tools/offers.d.ts +3 -0
  75. package/build/tools/offers.d.ts.map +1 -0
  76. package/build/tools/offers.js +95 -0
  77. package/build/tools/offers.js.map +1 -0
  78. package/build/tools/posts.d.ts +3 -0
  79. package/build/tools/posts.d.ts.map +1 -0
  80. package/build/tools/posts.js +120 -0
  81. package/build/tools/posts.js.map +1 -0
  82. package/build/tools/roles.d.ts +3 -0
  83. package/build/tools/roles.d.ts.map +1 -0
  84. package/build/tools/roles.js +35 -0
  85. package/build/tools/roles.js.map +1 -0
  86. package/build/tools/tags.d.ts +3 -0
  87. package/build/tools/tags.d.ts.map +1 -0
  88. package/build/tools/tags.js +88 -0
  89. package/build/tools/tags.js.map +1 -0
  90. package/build/tools/tiers.d.ts +3 -0
  91. package/build/tools/tiers.d.ts.map +1 -0
  92. package/build/tools/tiers.js +96 -0
  93. package/build/tools/tiers.js.map +1 -0
  94. package/build/tools/users.d.ts +3 -0
  95. package/build/tools/users.d.ts.map +1 -0
  96. package/build/tools/users.js +72 -0
  97. package/build/tools/users.js.map +1 -0
  98. package/build/tools/webhooks.d.ts +3 -0
  99. package/build/tools/webhooks.d.ts.map +1 -0
  100. package/build/tools/webhooks.js +85 -0
  101. package/build/tools/webhooks.js.map +1 -0
  102. package/build/types/entities.d.ts +265 -0
  103. package/build/types/entities.d.ts.map +1 -0
  104. package/build/types/entities.js +4 -0
  105. package/build/types/entities.js.map +1 -0
  106. package/package.json +54 -0
package/README.md ADDED
@@ -0,0 +1,286 @@
1
+ # Ghost MCP
2
+
3
+ A [Model Context Protocol](https://modelcontextprotocol.io) server that gives Claude, Gemini, and any other MCP-compatible AI full access to your [Ghost CMS](https://ghost.org) via the Ghost Admin API.
4
+
5
+ **Documentation languages:** [English](docs/en/) · [Français](docs/fr/) · [Español](docs/es/)
6
+
7
+ ---
8
+
9
+ ## Features
10
+
11
+ - **47 tools** across 10 resource types — posts, members, users, tags, tiers, offers, newsletters, invites, roles, and webhooks
12
+ - **7 MCP resources** — fetch any Ghost entity by URI (e.g. `post://abc123`)
13
+ - **2 built-in prompts** — `summarize-post` and `content-audit`
14
+ - **Typed error handling** — Ghost API errors are caught and surfaced as clean messages, not raw stack traces
15
+ - **Full tool descriptions** — every tool includes a plain-English description and per-parameter hints so the LLM understands exactly what to pass
16
+ - **Zero `any` types** — proper TypeScript interfaces throughout
17
+
18
+ ---
19
+
20
+ ## Quick start
21
+
22
+ ### 1. Prerequisites
23
+
24
+ - Node.js >= 18
25
+ - A Ghost site with Admin API access (Ghost Pro or self-hosted)
26
+
27
+ ### 2. Get your Ghost credentials
28
+
29
+ 1. In your Ghost Admin dashboard, go to **Settings → Integrations**
30
+ 2. Click **Add custom integration**, give it a name (e.g. "MCP")
31
+ 3. Copy the **Admin API Key** — it looks like `id:secret`
32
+
33
+ ### 3. Pick your AI client
34
+
35
+ No cloning or building required. Every integration below uses `npx ghost-mcp` to run the server on demand.
36
+
37
+ ---
38
+
39
+ ## Client integrations
40
+
41
+ ### Claude Desktop
42
+
43
+ The recommended integration. MCP is a native feature of Claude Desktop.
44
+
45
+ **Config file location:**
46
+ - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
47
+ - Windows: `%APPDATA%\Claude\claude_desktop_config.json`
48
+
49
+ ```json
50
+ {
51
+ "mcpServers": {
52
+ "ghost": {
53
+ "command": "npx",
54
+ "args": ["-y", "ghost-mcp"],
55
+ "env": {
56
+ "GHOST_API_URL": "https://yourblog.com",
57
+ "GHOST_ADMIN_API_KEY": "your_id:your_secret",
58
+ "GHOST_API_VERSION": "v5.0"
59
+ }
60
+ }
61
+ }
62
+ }
63
+ ```
64
+
65
+ Restart Claude Desktop. A hammer icon will appear in the chat input indicating all 47 tools are available.
66
+
67
+ ---
68
+
69
+ ### Claude Code (CLI)
70
+
71
+ Run this once in your terminal — Claude Code will persist the server across sessions:
72
+
73
+ ```bash
74
+ claude mcp add ghost \
75
+ --command npx \
76
+ --args "-y,ghost-mcp" \
77
+ -e GHOST_API_URL=https://yourblog.com \
78
+ -e GHOST_ADMIN_API_KEY=your_id:your_secret
79
+ ```
80
+
81
+ Or add it manually to `.claude/mcp.json` in your project using the same JSON shape as Claude Desktop above.
82
+
83
+ ---
84
+
85
+ ### Gemini CLI
86
+
87
+ Google's [Gemini CLI](https://github.com/google-gemini/gemini-cli) supports MCP servers natively.
88
+
89
+ **Config file:** `~/.gemini/settings.json`
90
+
91
+ ```json
92
+ {
93
+ "mcpServers": {
94
+ "ghost": {
95
+ "command": "npx",
96
+ "args": ["-y", "ghost-mcp"],
97
+ "env": {
98
+ "GHOST_API_URL": "https://yourblog.com",
99
+ "GHOST_ADMIN_API_KEY": "your_id:your_secret",
100
+ "GHOST_API_VERSION": "v5.0"
101
+ }
102
+ }
103
+ }
104
+ }
105
+ ```
106
+
107
+ Start a session with `gemini` and the Ghost tools will be available automatically.
108
+
109
+ ---
110
+
111
+ ### ChatGPT
112
+
113
+ ChatGPT does not support MCP. OpenAI uses a separate plugin/GPT Actions system based on OpenAPI specs. There is no direct integration path — you would need to wrap this server in an HTTP REST layer to use it with ChatGPT.
114
+
115
+ ---
116
+
117
+ ### Other MCP-compatible clients
118
+
119
+ Any client that speaks the MCP stdio transport can run this server. The command is always:
120
+
121
+ ```bash
122
+ npx -y ghost-mcp
123
+ ```
124
+
125
+ with `GHOST_API_URL` and `GHOST_ADMIN_API_KEY` set in the environment.
126
+
127
+ ---
128
+
129
+ ## Tools reference
130
+
131
+ ### Posts (5 tools)
132
+
133
+ | Tool | Description |
134
+ |---|---|
135
+ | `posts_browse` | List posts with filters, pagination, and sorting |
136
+ | `posts_read` | Fetch a single post by ID or slug |
137
+ | `posts_add` | Create a new post (draft or published) |
138
+ | `posts_edit` | Update an existing post |
139
+ | `posts_delete` | Permanently delete a post |
140
+
141
+ ### Members (5 tools)
142
+
143
+ | Tool | Description |
144
+ |---|---|
145
+ | `members_browse` | List members with filters |
146
+ | `members_read` | Fetch a single member by ID or email |
147
+ | `members_add` | Add a new member |
148
+ | `members_edit` | Update a member's details or subscriptions |
149
+ | `members_delete` | Remove a member |
150
+
151
+ ### Users (4 tools)
152
+
153
+ | Tool | Description |
154
+ |---|---|
155
+ | `users_browse` | List staff users |
156
+ | `users_read` | Fetch a single user by ID, email, or slug |
157
+ | `users_edit` | Update a user's profile |
158
+ | `users_delete` | Delete a staff user |
159
+
160
+ ### Tags (5 tools)
161
+
162
+ | Tool | Description |
163
+ |---|---|
164
+ | `tags_browse` | List all tags |
165
+ | `tags_read` | Fetch a single tag by ID or slug |
166
+ | `tags_add` | Create a new tag |
167
+ | `tags_edit` | Update a tag |
168
+ | `tags_delete` | Delete a tag |
169
+
170
+ ### Tiers (5 tools)
171
+
172
+ | Tool | Description |
173
+ |---|---|
174
+ | `tiers_browse` | List membership tiers |
175
+ | `tiers_read` | Fetch a single tier |
176
+ | `tiers_add` | Create a paid tier |
177
+ | `tiers_edit` | Update a tier |
178
+ | `tiers_delete` | Delete a tier |
179
+
180
+ ### Offers (5 tools)
181
+
182
+ | Tool | Description |
183
+ |---|---|
184
+ | `offers_browse` | List promotional offers |
185
+ | `offers_read` | Fetch an offer by ID or code |
186
+ | `offers_add` | Create a discount or trial offer |
187
+ | `offers_edit` | Update an offer's display text |
188
+ | `offers_delete` | Delete an offer |
189
+
190
+ ### Newsletters (5 tools)
191
+
192
+ | Tool | Description |
193
+ |---|---|
194
+ | `newsletters_browse` | List newsletters |
195
+ | `newsletters_read` | Fetch a single newsletter |
196
+ | `newsletters_add` | Create a new newsletter |
197
+ | `newsletters_edit` | Update newsletter settings |
198
+ | `newsletters_delete` | Delete a newsletter |
199
+
200
+ ### Invites (3 tools)
201
+
202
+ | Tool | Description |
203
+ |---|---|
204
+ | `invites_browse` | List pending staff invitations |
205
+ | `invites_add` | Send a staff invitation |
206
+ | `invites_delete` | Cancel an invitation |
207
+
208
+ ### Roles (2 tools)
209
+
210
+ | Tool | Description |
211
+ |---|---|
212
+ | `roles_browse` | List available roles |
213
+ | `roles_read` | Fetch a single role by ID or name |
214
+
215
+ ### Webhooks (5 tools)
216
+
217
+ | Tool | Description |
218
+ |---|---|
219
+ | `webhooks_browse` | List configured webhooks |
220
+ | `webhooks_read` | Fetch a single webhook |
221
+ | `webhooks_add` | Create a new webhook |
222
+ | `webhooks_edit` | Update a webhook |
223
+ | `webhooks_delete` | Delete a webhook |
224
+
225
+ ---
226
+
227
+ ## MCP Resources
228
+
229
+ Access Ghost entities directly by URI:
230
+
231
+ | URI pattern | Returns |
232
+ |---|---|
233
+ | `post://{post_id}` | Full post object including tags and authors |
234
+ | `user://{user_id}` | Staff user with roles |
235
+ | `member://{member_id}` | Member with labels and subscriptions |
236
+ | `tier://{tier_id}` | Tier with pricing details |
237
+ | `offer://{offer_id}` | Promotional offer details |
238
+ | `newsletter://{newsletter_id}` | Newsletter configuration |
239
+ | `blog://info` | Site settings and metadata |
240
+
241
+ ---
242
+
243
+ ## Built-in prompts
244
+
245
+ ### `summarize-post`
246
+
247
+ Fetches a Ghost post and asks the LLM to write a concise 2-3 sentence summary.
248
+
249
+ **Parameter:** `postId` — the Ghost post ID
250
+
251
+ ### `content-audit`
252
+
253
+ Fetches recent posts and asks the LLM to audit them for title quality, tagging consistency, publishing cadence, author diversity, and content strategy.
254
+
255
+ **Parameters:**
256
+ - `limit` — number of posts to include (default: 10)
257
+ - `status` — post status to filter by: `published` | `draft` | `scheduled` (default: `published`)
258
+
259
+ ---
260
+
261
+ ## Environment variables
262
+
263
+ | Variable | Required | Default | Description |
264
+ |---|---|---|---|
265
+ | `GHOST_API_URL` | Yes | — | Your Ghost site URL, e.g. `https://yourblog.com` |
266
+ | `GHOST_ADMIN_API_KEY` | Yes | — | Admin API key in `id:secret` format |
267
+ | `GHOST_API_VERSION` | No | `v5.0` | Ghost API version |
268
+
269
+ See [docs/en/configuration.md](docs/en/configuration.md) for full details.
270
+
271
+ ---
272
+
273
+ ## Documentation
274
+
275
+ | Document | Contents |
276
+ |---|---|
277
+ | [docs/en/configuration.md](docs/en/configuration.md) | Environment variables, Claude Desktop setup, troubleshooting |
278
+ | [docs/en/tools.md](docs/en/tools.md) | Complete tool reference with all parameters |
279
+ | [docs/en/resources.md](docs/en/resources.md) | MCP resource URI reference |
280
+ | [docs/en/development.md](docs/en/development.md) | Build, test, and extend the server |
281
+
282
+ ---
283
+
284
+ ## License
285
+
286
+ MIT
@@ -0,0 +1,8 @@
1
+ import GhostAdminAPI from "@tryghost/admin-api";
2
+ export declare const ghost: GhostAdminAPI;
3
+ /**
4
+ * Wraps a Ghost Admin API call, converting any error into a GhostMcpError.
5
+ * Usage: const result = await callGhost(() => ghost.posts.browse());
6
+ */
7
+ export declare function callGhost<T>(fn: () => Promise<T>): Promise<T>;
8
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,qBAAqB,CAAC;AAIhD,eAAO,MAAM,KAAK,eAIhB,CAAC;AAEH;;;GAGG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAMnE"}
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ghost = void 0;
7
+ exports.callGhost = callGhost;
8
+ const admin_api_1 = __importDefault(require("@tryghost/admin-api"));
9
+ const config_js_1 = require("./config.js");
10
+ const errors_js_1 = require("./errors.js");
11
+ exports.ghost = new admin_api_1.default({
12
+ url: config_js_1.config.apiUrl,
13
+ key: config_js_1.config.adminApiKey,
14
+ version: config_js_1.config.apiVersion,
15
+ });
16
+ /**
17
+ * Wraps a Ghost Admin API call, converting any error into a GhostMcpError.
18
+ * Usage: const result = await callGhost(() => ghost.posts.browse());
19
+ */
20
+ async function callGhost(fn) {
21
+ try {
22
+ return await fn();
23
+ }
24
+ catch (err) {
25
+ (0, errors_js_1.toMcpError)(err);
26
+ }
27
+ }
28
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":";;;;;;AAcA,8BAMC;AApBD,oEAAgD;AAChD,2CAAqC;AACrC,2CAAyC;AAE5B,QAAA,KAAK,GAAG,IAAI,mBAAa,CAAC;IACrC,GAAG,EAAE,kBAAM,CAAC,MAAM;IAClB,GAAG,EAAE,kBAAM,CAAC,WAAW;IACvB,OAAO,EAAE,kBAAM,CAAC,UAAU;CAC3B,CAAC,CAAC;AAEH;;;GAGG;AACI,KAAK,UAAU,SAAS,CAAI,EAAoB;IACrD,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,EAAE,CAAC;IACpB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAA,sBAAU,EAAC,GAAG,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,6 @@
1
+ export declare const config: {
2
+ readonly apiUrl: string;
3
+ readonly adminApiKey: string;
4
+ readonly apiVersion: string;
5
+ };
6
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,MAAM;;;;CAIT,CAAC"}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.config = void 0;
4
+ function requireEnv(name) {
5
+ const value = process.env[name];
6
+ if (!value) {
7
+ throw new Error(`Missing required environment variable: ${name}\n` +
8
+ `Set it before starting the server. See docs/configuration.md for details.`);
9
+ }
10
+ return value;
11
+ }
12
+ exports.config = {
13
+ apiUrl: requireEnv("GHOST_API_URL"),
14
+ adminApiKey: requireEnv("GHOST_ADMIN_API_KEY"),
15
+ apiVersion: process.env["GHOST_API_VERSION"] ?? "v5.0",
16
+ };
17
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;AAAA,SAAS,UAAU,CAAC,IAAY;IAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACb,0CAA0C,IAAI,IAAI;YAClD,2EAA2E,CAC5E,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAEY,QAAA,MAAM,GAAG;IACpB,MAAM,EAAE,UAAU,CAAC,eAAe,CAAC;IACnC,WAAW,EAAE,UAAU,CAAC,qBAAqB,CAAC;IAC9C,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,MAAM;CAC9C,CAAC"}
@@ -0,0 +1,14 @@
1
+ export declare class GhostMcpError extends Error {
2
+ readonly code: string;
3
+ readonly cause?: unknown | undefined;
4
+ constructor(code: string, message: string, cause?: unknown | undefined);
5
+ }
6
+ /** Converts any caught value into a thrown GhostMcpError. Never returns. */
7
+ export declare function toMcpError(err: unknown): never;
8
+ export declare function formatErrorContent(err: unknown): {
9
+ content: [{
10
+ type: "text";
11
+ text: string;
12
+ }];
13
+ };
14
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,aAAc,SAAQ,KAAK;aAEpB,IAAI,EAAE,MAAM;aAEZ,KAAK,CAAC,EAAE,OAAO;gBAFf,IAAI,EAAE,MAAM,EAC5B,OAAO,EAAE,MAAM,EACC,KAAK,CAAC,EAAE,OAAO,YAAA;CAKlC;AAED,4EAA4E;AAC5E,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,KAAK,CAY9C;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG;IAAE,OAAO,EAAE,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAG9F"}
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GhostMcpError = void 0;
4
+ exports.toMcpError = toMcpError;
5
+ exports.formatErrorContent = formatErrorContent;
6
+ class GhostMcpError extends Error {
7
+ code;
8
+ cause;
9
+ constructor(code, message, cause) {
10
+ super(message);
11
+ this.code = code;
12
+ this.cause = cause;
13
+ this.name = "GhostMcpError";
14
+ }
15
+ }
16
+ exports.GhostMcpError = GhostMcpError;
17
+ /** Converts any caught value into a thrown GhostMcpError. Never returns. */
18
+ function toMcpError(err) {
19
+ if (err instanceof GhostMcpError)
20
+ throw err;
21
+ if (err instanceof Error) {
22
+ // Ghost Admin API surfaces errors with a `context` field
23
+ const ghostErr = err;
24
+ const detail = ghostErr.context ?? ghostErr.message;
25
+ const code = ghostErr.statusCode != null ? `GHOST_${ghostErr.statusCode}` : "GHOST_ERROR";
26
+ throw new GhostMcpError(code, detail, err);
27
+ }
28
+ throw new GhostMcpError("UNKNOWN_ERROR", String(err), err);
29
+ }
30
+ function formatErrorContent(err) {
31
+ const message = err instanceof Error ? err.message : String(err);
32
+ return { content: [{ type: "text", text: `Error: ${message}` }] };
33
+ }
34
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":";;;AAYA,gCAYC;AAED,gDAGC;AA7BD,MAAa,aAAc,SAAQ,KAAK;IAEpB;IAEA;IAHlB,YACkB,IAAY,EAC5B,OAAe,EACC,KAAe;QAE/B,KAAK,CAAC,OAAO,CAAC,CAAC;QAJC,SAAI,GAAJ,IAAI,CAAQ;QAEZ,UAAK,GAAL,KAAK,CAAU;QAG/B,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AATD,sCASC;AAED,4EAA4E;AAC5E,SAAgB,UAAU,CAAC,GAAY;IACrC,IAAI,GAAG,YAAY,aAAa;QAAE,MAAM,GAAG,CAAC;IAE5C,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACzB,yDAAyD;QACzD,MAAM,QAAQ,GAAG,GAAwD,CAAC;QAC1E,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO,CAAC;QACpD,MAAM,IAAI,GAAG,QAAQ,CAAC,UAAU,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC;QAC1F,MAAM,IAAI,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7C,CAAC;IAED,MAAM,IAAI,aAAa,CAAC,eAAe,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;AAC7D,CAAC;AAED,SAAgB,kBAAkB,CAAC,GAAY;IAC7C,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACjE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAU,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC;AAC7E,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerContentAuditPrompt(server: McpServer): void;
3
+ //# sourceMappingURL=content-audit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-audit.d.ts","sourceRoot":"","sources":["../../src/prompts/content-audit.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGpE,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA+ElE"}
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerContentAuditPrompt = registerContentAuditPrompt;
4
+ const zod_1 = require("zod");
5
+ const client_js_1 = require("../client.js");
6
+ function registerContentAuditPrompt(server) {
7
+ server.prompt("content-audit", "Fetch recent Ghost posts and ask the LLM to audit them for quality, consistency, and publishing cadence.", {
8
+ limit: zod_1.z
9
+ .string()
10
+ .optional()
11
+ .describe("Number of recent posts to audit (default: 10)"),
12
+ status: zod_1.z
13
+ .string()
14
+ .optional()
15
+ .describe("Filter by post status: published | draft | scheduled (default: published)"),
16
+ }, async ({ limit, status }) => {
17
+ const resolvedLimit = limit ? parseInt(limit, 10) : 10;
18
+ const resolvedStatus = status ?? "published";
19
+ const posts = await (0, client_js_1.callGhost)(() => client_js_1.ghost.posts.browse({
20
+ limit: resolvedLimit,
21
+ filter: `status:${resolvedStatus}`,
22
+ order: "published_at desc",
23
+ include: "tags,authors",
24
+ formats: "plaintext",
25
+ }));
26
+ const postList = posts.map((p, i) => {
27
+ const title = p["title"] ?? "Untitled";
28
+ const slug = p["slug"] ?? "";
29
+ const publishedAt = p["published_at"] ?? "unpublished";
30
+ const excerpt = p["excerpt"] ?? "";
31
+ const tags = (p["tags"] ?? [])
32
+ .map((t) => t.name)
33
+ .filter(Boolean)
34
+ .join(", ");
35
+ const authors = (p["authors"] ?? [])
36
+ .map((a) => a.name)
37
+ .filter(Boolean)
38
+ .join(", ");
39
+ return [
40
+ `## ${i + 1}. ${title}`,
41
+ ` Slug: /${slug}`,
42
+ ` Published: ${publishedAt}`,
43
+ authors ? ` Author(s): ${authors}` : null,
44
+ tags ? ` Tags: ${tags}` : null,
45
+ excerpt ? ` Excerpt: ${excerpt.slice(0, 150)}${excerpt.length > 150 ? "…" : ""}` : null,
46
+ ]
47
+ .filter(Boolean)
48
+ .join("\n");
49
+ });
50
+ const postSummary = postList.join("\n\n");
51
+ return {
52
+ messages: [
53
+ {
54
+ role: "user",
55
+ content: {
56
+ type: "text",
57
+ text: `You are a content strategist reviewing a Ghost blog. Please audit the following ${resolvedLimit} most recent ${resolvedStatus} posts and provide:
58
+
59
+ 1. **Title quality** — Are titles clear, compelling, and SEO-friendly?
60
+ 2. **Tagging consistency** — Are tags being used consistently? Any missing or redundant tags?
61
+ 3. **Publishing cadence** — How frequently are posts published? Any noticeable gaps?
62
+ 4. **Author diversity** — Are posts distributed across authors, or dominated by one?
63
+ 5. **Recommendations** — 3–5 actionable improvements for the content strategy.
64
+
65
+ Here are the posts:
66
+
67
+ ${postSummary}`,
68
+ },
69
+ },
70
+ ],
71
+ };
72
+ });
73
+ }
74
+ //# sourceMappingURL=content-audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-audit.js","sourceRoot":"","sources":["../../src/prompts/content-audit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerPrompts(server: McpServer): void;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIpE,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAGvD"}
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerPrompts = registerPrompts;
4
+ const summarize_post_js_1 = require("./summarize-post.js");
5
+ const content_audit_js_1 = require("./content-audit.js");
6
+ function registerPrompts(server) {
7
+ (0, summarize_post_js_1.registerSummarizePostPrompt)(server);
8
+ (0, content_audit_js_1.registerContentAuditPrompt)(server);
9
+ }
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":";;AAIA,0CAGC;AAND,2DAAkE;AAClE,yDAAgE;AAEhE,SAAgB,eAAe,CAAC,MAAiB;IAC/C,IAAA,+CAA2B,EAAC,MAAM,CAAC,CAAC;IACpC,IAAA,6CAA0B,EAAC,MAAM,CAAC,CAAC;AACrC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerSummarizePostPrompt(server: McpServer): void;
3
+ //# sourceMappingURL=summarize-post.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summarize-post.d.ts","sourceRoot":"","sources":["../../src/prompts/summarize-post.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGpE,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAoCnE"}
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerSummarizePostPrompt = registerSummarizePostPrompt;
4
+ const zod_1 = require("zod");
5
+ const client_js_1 = require("../client.js");
6
+ function registerSummarizePostPrompt(server) {
7
+ server.prompt("summarize-post", "Fetch a Ghost post and ask the LLM to write a concise summary of it.", { postId: zod_1.z.string().describe("Ghost post ID to summarize") }, async ({ postId }) => {
8
+ const post = await (0, client_js_1.callGhost)(() => client_js_1.ghost.posts.read({ id: postId }));
9
+ const title = post["title"] ?? "";
10
+ const excerpt = post["excerpt"] ?? "";
11
+ const html = post["html"] ?? "";
12
+ const preview = html.replace(/<[^>]+>/g, "").slice(0, 500);
13
+ const context = [
14
+ `Title: ${title}`,
15
+ excerpt ? `Excerpt: ${excerpt}` : null,
16
+ `Content preview:\n${preview}${html.length > 500 ? "…" : ""}`,
17
+ ]
18
+ .filter(Boolean)
19
+ .join("\n\n");
20
+ return {
21
+ messages: [
22
+ {
23
+ role: "user",
24
+ content: {
25
+ type: "text",
26
+ text: `Please write a concise 2–3 sentence summary of this Ghost blog post:\n\n${context}`,
27
+ },
28
+ },
29
+ ],
30
+ };
31
+ });
32
+ }
33
+ //# sourceMappingURL=summarize-post.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summarize-post.js","sourceRoot":"","sources":["../../src/prompts/summarize-post.ts"],"names":[],"mappings":";;AAIA,kEAoCC;AAxCD,6BAAwB;AAExB,4CAAgD;AAEhD,SAAgB,2BAA2B,CAAC,MAAiB;IAC3D,MAAM,CAAC,MAAM,CACX,gBAAgB,EAChB,sEAAsE,EACtE,EAAE,MAAM,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC,EAAE,EAC7D,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QACnB,MAAM,IAAI,GAAG,MAAM,IAAA,qBAAS,EAAC,GAAG,EAAE,CAChC,iBAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAA4C,CAAC,CAC3E,CAAC;QAEF,MAAM,KAAK,GAAI,IAAgC,CAAC,OAAO,CAAW,IAAI,EAAE,CAAC;QACzE,MAAM,OAAO,GAAI,IAAgC,CAAC,SAAS,CAAW,IAAI,EAAE,CAAC;QAC7E,MAAM,IAAI,GAAI,IAAgC,CAAC,MAAM,CAAW,IAAI,EAAE,CAAC;QAEvE,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAC3D,MAAM,OAAO,GAAG;YACd,UAAU,KAAK,EAAE;YACjB,OAAO,CAAC,CAAC,CAAC,YAAY,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI;YACtC,qBAAqB,OAAO,GAAG,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;SAC9D;aACE,MAAM,CAAC,OAAO,CAAC;aACf,IAAI,CAAC,MAAM,CAAC,CAAC;QAEhB,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAM;oBACZ,OAAO,EAAE;wBACP,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,2EAA2E,OAAO,EAAE;qBAC3F;iBACF;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ReadResourceCallback } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare const handleBlogInfoResource: ReadResourceCallback;
3
+ //# sourceMappingURL=blog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blog.d.ts","sourceRoot":"","sources":["../../src/resources/blog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AAGpF,eAAO,MAAM,sBAAsB,EAAE,oBAYpC,CAAC"}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleBlogInfoResource = void 0;
4
+ const client_js_1 = require("../client.js");
5
+ const handleBlogInfoResource = async (uri) => {
6
+ const site = await (0, client_js_1.callGhost)(() => client_js_1.ghost.site.read());
7
+ return {
8
+ contents: [
9
+ {
10
+ uri: uri.href,
11
+ mimeType: "application/json",
12
+ text: JSON.stringify(site, null, 2),
13
+ },
14
+ ],
15
+ };
16
+ };
17
+ exports.handleBlogInfoResource = handleBlogInfoResource;
18
+ //# sourceMappingURL=blog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blog.js","sourceRoot":"","sources":["../../src/resources/blog.ts"],"names":[],"mappings":";;;AACA,4CAAgD;AAEzC,MAAM,sBAAsB,GAAyB,KAAK,EAAE,GAAG,EAAE,EAAE;IACxE,MAAM,IAAI,GAAG,MAAM,IAAA,qBAAS,EAAC,GAAG,EAAE,CAAC,iBAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAEtD,OAAO;QACL,QAAQ,EAAE;YACR;gBACE,GAAG,EAAE,GAAG,CAAC,IAAI;gBACb,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;aACpC;SACF;KACF,CAAC;AACJ,CAAC,CAAC;AAZW,QAAA,sBAAsB,0BAYjC"}
@@ -0,0 +1,8 @@
1
+ export { handlePostResource } from "./posts.js";
2
+ export { handleUserResource } from "./users.js";
3
+ export { handleMemberResource } from "./members.js";
4
+ export { handleTierResource } from "./tiers.js";
5
+ export { handleOfferResource } from "./offers.js";
6
+ export { handleNewsletterResource } from "./newsletters.js";
7
+ export { handleBlogInfoResource } from "./blog.js";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleBlogInfoResource = exports.handleNewsletterResource = exports.handleOfferResource = exports.handleTierResource = exports.handleMemberResource = exports.handleUserResource = exports.handlePostResource = void 0;
4
+ var posts_js_1 = require("./posts.js");
5
+ Object.defineProperty(exports, "handlePostResource", { enumerable: true, get: function () { return posts_js_1.handlePostResource; } });
6
+ var users_js_1 = require("./users.js");
7
+ Object.defineProperty(exports, "handleUserResource", { enumerable: true, get: function () { return users_js_1.handleUserResource; } });
8
+ var members_js_1 = require("./members.js");
9
+ Object.defineProperty(exports, "handleMemberResource", { enumerable: true, get: function () { return members_js_1.handleMemberResource; } });
10
+ var tiers_js_1 = require("./tiers.js");
11
+ Object.defineProperty(exports, "handleTierResource", { enumerable: true, get: function () { return tiers_js_1.handleTierResource; } });
12
+ var offers_js_1 = require("./offers.js");
13
+ Object.defineProperty(exports, "handleOfferResource", { enumerable: true, get: function () { return offers_js_1.handleOfferResource; } });
14
+ var newsletters_js_1 = require("./newsletters.js");
15
+ Object.defineProperty(exports, "handleNewsletterResource", { enumerable: true, get: function () { return newsletters_js_1.handleNewsletterResource; } });
16
+ var blog_js_1 = require("./blog.js");
17
+ Object.defineProperty(exports, "handleBlogInfoResource", { enumerable: true, get: function () { return blog_js_1.handleBlogInfoResource; } });
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":";;;AAAA,uCAAgD;AAAvC,8GAAA,kBAAkB,OAAA;AAC3B,uCAAgD;AAAvC,8GAAA,kBAAkB,OAAA;AAC3B,2CAAoD;AAA3C,kHAAA,oBAAoB,OAAA;AAC7B,uCAAgD;AAAvC,8GAAA,kBAAkB,OAAA;AAC3B,yCAAkD;AAAzC,gHAAA,mBAAmB,OAAA;AAC5B,mDAA4D;AAAnD,0HAAA,wBAAwB,OAAA;AACjC,qCAAmD;AAA1C,iHAAA,sBAAsB,OAAA"}