huozi-mcp-server 0.3.0 → 0.4.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 (2) hide show
  1. package/dist/index.js +101 -3
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ import { z } from "zod";
5
5
  import { apiCall, getApiKey } from "./api.js";
6
6
  const server = new McpServer({
7
7
  name: "huozi",
8
- version: "0.3.0",
8
+ version: "0.4.0",
9
9
  });
10
10
  // --- Auth tools ---
11
11
  server.tool("huozi_signup", "Sign in or register a Huozi account. Sends a verification code to the email. No password needed.", {
@@ -109,7 +109,12 @@ server.tool("huozi_publish", "Publish or update a page on Huozi. Supports Markdo
109
109
  .enum(["markdown", "html"])
110
110
  .optional()
111
111
  .describe("Content type: 'markdown' (default) or 'html'. HTML accepts full documents or body fragments. CSS is preserved, JS is stripped."),
112
- }, async ({ title, content, slug, description, content_type }) => {
112
+ access_token: z
113
+ .string()
114
+ .nullable()
115
+ .optional()
116
+ .describe('Page access protection. "random" = generate 6-char code, custom string = your password, null = remove protection (public).'),
117
+ }, async ({ title, content, slug, description, content_type, access_token }) => {
113
118
  const apiKey = getApiKey();
114
119
  if (!apiKey) {
115
120
  return {
@@ -128,6 +133,8 @@ server.tool("huozi_publish", "Publish or update a page on Huozi. Supports Markdo
128
133
  body.description = description;
129
134
  if (content_type)
130
135
  body.content_type = content_type;
136
+ if (access_token !== undefined)
137
+ body.access_token = access_token;
131
138
  const res = await apiCall("/api/v1/pages", {
132
139
  method: "POST",
133
140
  body,
@@ -147,7 +154,7 @@ server.tool("huozi_publish", "Publish or update a page on Huozi. Supports Markdo
147
154
  content: [
148
155
  {
149
156
  type: "text",
150
- text: `Published! URL: ${res.data.url}`,
157
+ text: `Published! URL: ${res.data.url}${res.data.version ? ` (v${res.data.version})` : ""}${res.data.access_token ? `\nAccess code: ${res.data.access_token}` : ""}`,
151
158
  },
152
159
  ],
153
160
  };
@@ -250,6 +257,97 @@ server.tool("huozi_delete", "Delete a page.", {
250
257
  ],
251
258
  };
252
259
  });
260
+ server.tool("huozi_versions", "List all versions of a page.", {
261
+ slug: z.string().describe("Page slug"),
262
+ }, async ({ slug }) => {
263
+ const apiKey = getApiKey();
264
+ if (!apiKey) {
265
+ return {
266
+ content: [
267
+ { type: "text", text: "HUOZI_API_KEY is not set." },
268
+ ],
269
+ };
270
+ }
271
+ const res = await apiCall(`/api/v1/pages/${slug}/versions`, { apiKey });
272
+ if (!res.ok) {
273
+ return {
274
+ content: [
275
+ {
276
+ type: "text",
277
+ text: `Failed: ${res.data.error || "Unknown error"}`,
278
+ },
279
+ ],
280
+ };
281
+ }
282
+ const versions = res.data.versions;
283
+ if (!versions || versions.length === 0) {
284
+ return {
285
+ content: [{ type: "text", text: "No versions found." }],
286
+ };
287
+ }
288
+ const list = versions
289
+ .map((v) => `v${v.version} (${v.content_type}) — ${v.created_at}`)
290
+ .join("\n");
291
+ return {
292
+ content: [{ type: "text", text: `Versions of /${slug}:\n${list}` }],
293
+ };
294
+ });
295
+ server.tool("huozi_token", 'Manage access token (password protection) for a page. Set "random" to generate a 6-char code, a custom string for your own password, or null to remove protection.', {
296
+ slug: z.string().describe("Page slug"),
297
+ access_token: z
298
+ .string()
299
+ .nullable()
300
+ .describe('"random" = generate code, custom string = your password, null = remove (make public)'),
301
+ }, async ({ slug, access_token }) => {
302
+ const apiKey = getApiKey();
303
+ if (!apiKey) {
304
+ return {
305
+ content: [
306
+ { type: "text", text: "HUOZI_API_KEY is not set." },
307
+ ],
308
+ };
309
+ }
310
+ const res = await apiCall(`/api/v1/pages/${slug}/token`, {
311
+ method: "PUT",
312
+ body: { access_token },
313
+ apiKey,
314
+ });
315
+ if (!res.ok) {
316
+ return {
317
+ content: [
318
+ {
319
+ type: "text",
320
+ text: `Failed: ${res.data.error || "Unknown error"}`,
321
+ },
322
+ ],
323
+ };
324
+ }
325
+ if (res.data.access_token) {
326
+ return {
327
+ content: [
328
+ {
329
+ type: "text",
330
+ text: `Access code set for /${slug}: ${res.data.access_token}\nTell the user to share this code with people who need access.`,
331
+ },
332
+ ],
333
+ };
334
+ }
335
+ if (res.data.has_access_token) {
336
+ return {
337
+ content: [
338
+ { type: "text", text: `Access code updated for /${slug}.` },
339
+ ],
340
+ };
341
+ }
342
+ return {
343
+ content: [
344
+ {
345
+ type: "text",
346
+ text: `Protection removed. /${slug} is now public.`,
347
+ },
348
+ ],
349
+ };
350
+ });
253
351
  // --- Start server ---
254
352
  async function main() {
255
353
  const transport = new StdioServerTransport();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "huozi-mcp-server",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "MCP server for Huozi — publish Markdown and HTML as shareable web pages",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",