@xiedada/nodemw-mcp-server 0.0.6 → 0.0.9

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 +218 -130
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -37,7 +37,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
37
37
  // package.json
38
38
  var package_default = {
39
39
  name: "@xiedada/nodemw-mcp-server",
40
- version: "0.0.6",
40
+ version: "0.0.9",
41
41
  description: "MCP server for nodemw - MediaWiki API client",
42
42
  type: "module",
43
43
  main: "dist/index.js",
@@ -255,6 +255,13 @@ async function recordReadState(title) {
255
255
  } catch {
256
256
  }
257
257
  }
258
+ function getFirstItem(obj) {
259
+ if (!obj) return null;
260
+ for (const key in obj) {
261
+ return obj[key];
262
+ }
263
+ return null;
264
+ }
258
265
  function getArticleTool(server) {
259
266
  return server.tool(
260
267
  "get-article",
@@ -262,19 +269,57 @@ function getArticleTool(server) {
262
269
  {
263
270
  title: z.string().describe("Article title"),
264
271
  followRedirect: z.boolean().optional().default(true).describe("Follow redirects"),
265
- redirectInfo: z.boolean().optional().default(false).describe("Include information about redirects")
272
+ redirectInfo: z.boolean().optional().default(false).describe("Include information about redirects"),
273
+ revision: z.number().optional().describe("Specific revision ID to fetch. If omitted, returns the latest version.")
266
274
  },
267
275
  {
268
276
  title: "Get article",
269
277
  readOnlyHint: true,
270
278
  destructiveHint: false
271
279
  },
272
- async ({ title, followRedirect, redirectInfo }) => handleGetArticleTool(title, followRedirect, redirectInfo)
280
+ async ({ title, followRedirect, redirectInfo, revision }) => handleGetArticleTool(title, followRedirect, redirectInfo, revision)
273
281
  );
274
282
  }
275
- async function handleGetArticleTool(title, followRedirect, redirectInfo) {
283
+ async function handleGetArticleTool(title, followRedirect, redirectInfo, revision) {
276
284
  try {
277
285
  const bot = await getBot();
286
+ if (revision !== void 0) {
287
+ const params = {
288
+ action: "query",
289
+ prop: "revisions",
290
+ rvprop: "content",
291
+ rvstartid: revision,
292
+ rvlimit: 1,
293
+ titles: title,
294
+ ...followRedirect && { redirects: "" }
295
+ };
296
+ const info = await new Promise((resolve, reject) => {
297
+ bot.api.call(params, (err, info2) => {
298
+ if (err) reject(err);
299
+ else resolve(info2);
300
+ }, "GET");
301
+ });
302
+ const pages = info.pages;
303
+ const page = getFirstItem(pages);
304
+ if (!page || page.missing) {
305
+ return {
306
+ content: [{ type: "text", text: `Page "${title}" not found.` }],
307
+ isError: true
308
+ };
309
+ }
310
+ const revisions = page.revisions;
311
+ const rev = revisions?.[0];
312
+ if (!rev || rev["*"] == null) {
313
+ return {
314
+ content: [{ type: "text", text: `Revision ${revision} not found for page "${title}".` }],
315
+ isError: true
316
+ };
317
+ }
318
+ await recordReadState(title);
319
+ return {
320
+ content: [{ type: "text", text: rev["*"] }]
321
+ };
322
+ }
278
323
  if (redirectInfo) {
279
324
  const result = await new Promise((resolve, reject) => {
280
325
  const callback = (err, content2, redirectInfo2) => {
@@ -554,7 +599,7 @@ function getPagesInNamespaceTool(server) {
554
599
  "get-pages-in-namespace",
555
600
  "Get all non-redirect pages in a specific namespace",
556
601
  {
557
- namespace: z7.number().describe("Namespace number to filter pages")
602
+ namespace: z7.number().describe("Namespace number (0=Main, 2=User, 6=File, 10=Template, 14=Category)")
558
603
  },
559
604
  {
560
605
  title: "Get pages in namespace",
@@ -687,7 +732,7 @@ async function handleGetArticleRevisionsTool(title) {
687
732
  "getArticleRevisions",
688
733
  title
689
734
  );
690
- const revisions = allRevisions.flat();
735
+ const revisions = allRevisions.flat().filter((rev) => rev != null);
691
736
  return jsonResult({
692
737
  title,
693
738
  revisions,
@@ -740,7 +785,7 @@ import { z as z12 } from "zod";
740
785
  function getArticlePropertiesTool(server) {
741
786
  const tool = server.tool(
742
787
  "get-article-properties",
743
- "Get page properties for a wiki article",
788
+ "Get page properties (page_props table data) for a wiki article",
744
789
  {
745
790
  title: z12.string().describe("Article title")
746
791
  },
@@ -783,7 +828,7 @@ function getArticleInfoTool(server) {
783
828
  z13.number(),
784
829
  z13.array(z13.union([z13.string(), z13.number()]))
785
830
  ]).describe("Article title, page ID, or array of titles/IDs"),
786
- properties: z13.array(z13.string()).optional().describe("Specific properties to retrieve")
831
+ properties: z13.array(z13.string()).optional().describe("Specific properties to retrieve (e.g. protection, talkid, url)")
787
832
  },
788
833
  {
789
834
  title: "Get article info",
@@ -834,7 +879,7 @@ function getUserContribsTool(server) {
834
879
  },
835
880
  async ({ username, namespace, limit }) => handleGetUserContribsTool(username, namespace, limit)
836
881
  );
837
- tool.update({ outputSchema: { username: z14.string(), namespace: z14.number(), limit: z14.number(), total: z14.number(), displayed: z14.number(), contributions: z14.array(z14.record(z14.unknown())) } });
882
+ tool.update({ outputSchema: { username: z14.string(), namespace: z14.number().optional(), limit: z14.number(), total: z14.number(), displayed: z14.number(), contributions: z14.array(z14.record(z14.unknown())) } });
838
883
  return tool;
839
884
  }
840
885
  async function handleGetUserContribsTool(username, namespace, limit = 50) {
@@ -865,6 +910,7 @@ async function handleGetUserContribsTool(username, namespace, limit = 50) {
865
910
  }
866
911
 
867
912
  // src/tools/ro/whoami.ts
913
+ import { z as z15 } from "zod";
868
914
  function whoamiTool(server) {
869
915
  const tool = server.tool(
870
916
  "whoami",
@@ -877,7 +923,17 @@ function whoamiTool(server) {
877
923
  },
878
924
  async () => handleWhoamiTool()
879
925
  );
880
- tool.update({ outputSchema: {} });
926
+ tool.update({ outputSchema: { user: z15.object({
927
+ name: z15.string(),
928
+ id: z15.number(),
929
+ groups: z15.array(z15.string()),
930
+ rights: z15.array(z15.string()),
931
+ ratelimits: z15.union([z15.record(z15.unknown()), z15.array(z15.unknown())]),
932
+ editcount: z15.number(),
933
+ realname: z15.string(),
934
+ email: z15.string(),
935
+ emailauthenticated: z15.string()
936
+ }) } });
881
937
  return tool;
882
938
  }
883
939
  async function handleWhoamiTool() {
@@ -887,20 +943,20 @@ async function handleWhoamiTool() {
887
943
  bot,
888
944
  "whoami"
889
945
  );
890
- return jsonResult(userInfo);
946
+ return jsonResult({ user: userInfo });
891
947
  } catch (error) {
892
948
  return errorResult("Failed to get current user info", error);
893
949
  }
894
950
  }
895
951
 
896
952
  // src/tools/ro/whois.ts
897
- import { z as z15 } from "zod";
953
+ import { z as z16 } from "zod";
898
954
  function whoisTool(server) {
899
955
  const tool = server.tool(
900
956
  "whois",
901
957
  "Get information about a specific user",
902
958
  {
903
- username: z15.string().describe("Username to look up")
959
+ username: z16.string().describe("Username to look up")
904
960
  },
905
961
  {
906
962
  title: "Whois",
@@ -909,7 +965,18 @@ function whoisTool(server) {
909
965
  },
910
966
  async ({ username }) => handleWhoisTool(username)
911
967
  );
912
- tool.update({ outputSchema: {} });
968
+ tool.update({ outputSchema: { user: z16.object({
969
+ userid: z16.number(),
970
+ name: z16.string(),
971
+ groups: z16.array(z16.string()),
972
+ implicitgroups: z16.array(z16.string()),
973
+ rights: z16.array(z16.string()),
974
+ editcount: z16.number(),
975
+ registration: z16.string(),
976
+ emailable: z16.string(),
977
+ gender: z16.string(),
978
+ blockinfo: z16.record(z16.unknown()).optional()
979
+ }) } });
913
980
  return tool;
914
981
  }
915
982
  async function handleWhoisTool(username) {
@@ -923,20 +990,20 @@ async function handleWhoisTool(username) {
923
990
  if (userInfo.missing) {
924
991
  return errorResult(`User "${username}" not found.`);
925
992
  }
926
- return jsonResult(userInfo);
993
+ return jsonResult({ user: userInfo });
927
994
  } catch (error) {
928
995
  return errorResult("Failed to get user info", error);
929
996
  }
930
997
  }
931
998
 
932
999
  // src/tools/ro/whoare.ts
933
- import { z as z16 } from "zod";
1000
+ import { z as z17 } from "zod";
934
1001
  function whoareTool(server) {
935
1002
  const tool = server.tool(
936
1003
  "whoare",
937
1004
  "Get information about multiple wiki users",
938
1005
  {
939
- usernames: z16.array(z16.string()).describe("Array of usernames to query")
1006
+ usernames: z17.array(z17.string()).describe("Array of usernames to query")
940
1007
  },
941
1008
  {
942
1009
  title: "Who are",
@@ -945,7 +1012,18 @@ function whoareTool(server) {
945
1012
  },
946
1013
  async (params) => handleWhoareTool(params)
947
1014
  );
948
- tool.update({ outputSchema: {} });
1015
+ tool.update({ outputSchema: { users: z17.array(z17.object({
1016
+ userid: z17.number(),
1017
+ name: z17.string(),
1018
+ groups: z17.array(z17.string()),
1019
+ implicitgroups: z17.array(z17.string()),
1020
+ rights: z17.array(z17.string()),
1021
+ editcount: z17.number(),
1022
+ registration: z17.string(),
1023
+ emailable: z17.string(),
1024
+ gender: z17.string(),
1025
+ blockinfo: z17.record(z17.unknown()).optional()
1026
+ })), count: z17.number() } });
949
1027
  return tool;
950
1028
  }
951
1029
  async function handleWhoareTool(params) {
@@ -956,21 +1034,21 @@ async function handleWhoareTool(params) {
956
1034
  "whoare",
957
1035
  params.usernames
958
1036
  );
959
- return jsonResult(users);
1037
+ return jsonResult({ users, count: users.length });
960
1038
  } catch (error) {
961
1039
  return errorResult("Failed to get user information", error);
962
1040
  }
963
1041
  }
964
1042
 
965
1043
  // src/tools/ro/get-images.ts
966
- import { z as z17 } from "zod";
1044
+ import { z as z18 } from "zod";
967
1045
  function getImagesTool(server) {
968
1046
  const tool = server.tool(
969
1047
  "get-images",
970
1048
  "Get list of images starting from a specific name",
971
1049
  {
972
- startFrom: z17.string().optional().default("").describe("Start from this image name"),
973
- limit: z17.number().optional().default(50).describe("Maximum number of images to return")
1050
+ startFrom: z18.string().optional().default("").describe("Start from this image name"),
1051
+ limit: z18.number().optional().default(50).describe("Maximum number of images to return")
974
1052
  },
975
1053
  {
976
1054
  title: "Get images",
@@ -979,7 +1057,7 @@ function getImagesTool(server) {
979
1057
  },
980
1058
  async ({ startFrom, limit }) => handleGetImagesTool(startFrom, limit)
981
1059
  );
982
- tool.update({ outputSchema: { total: z17.number(), limit: z17.number(), startFrom: z17.string(), images: z17.array(z17.record(z17.unknown())) } });
1060
+ tool.update({ outputSchema: { total: z18.number(), limit: z18.number(), startFrom: z18.string(), images: z18.array(z18.record(z18.unknown())) } });
983
1061
  return tool;
984
1062
  }
985
1063
  async function handleGetImagesTool(startFrom, limit) {
@@ -1008,13 +1086,13 @@ async function handleGetImagesTool(startFrom, limit) {
1008
1086
  }
1009
1087
 
1010
1088
  // src/tools/ro/get-images-from-article.ts
1011
- import { z as z18 } from "zod";
1089
+ import { z as z19 } from "zod";
1012
1090
  function getImagesFromArticleTool(server) {
1013
1091
  const tool = server.tool(
1014
1092
  "get-images-from-article",
1015
1093
  "Get all images embedded in a specific article",
1016
1094
  {
1017
- title: z18.union([z18.string(), z18.number()]).describe("Article title or page ID")
1095
+ title: z19.union([z19.string(), z19.number()]).describe("Article title or page ID")
1018
1096
  },
1019
1097
  {
1020
1098
  title: "Get images from article",
@@ -1023,7 +1101,7 @@ function getImagesFromArticleTool(server) {
1023
1101
  },
1024
1102
  async ({ title }) => handleGetImagesFromArticleTool(title)
1025
1103
  );
1026
- tool.update({ outputSchema: { title: z18.string(), images: z18.array(z18.record(z18.unknown())), count: z18.number() } });
1104
+ tool.update({ outputSchema: { title: z19.string(), images: z19.array(z19.record(z19.unknown())), count: z19.number() } });
1027
1105
  return tool;
1028
1106
  }
1029
1107
  async function handleGetImagesFromArticleTool(title) {
@@ -1045,13 +1123,13 @@ async function handleGetImagesFromArticleTool(title) {
1045
1123
  }
1046
1124
 
1047
1125
  // src/tools/ro/get-image-usage.ts
1048
- import { z as z19 } from "zod";
1126
+ import { z as z20 } from "zod";
1049
1127
  function getImageUsageTool(server) {
1050
1128
  const tool = server.tool(
1051
1129
  "get-image-usage",
1052
1130
  "Get all pages that use a specific image",
1053
1131
  {
1054
- filename: z19.string().describe("Image filename with File: prefix")
1132
+ filename: z20.string().describe("Image filename with File: prefix")
1055
1133
  },
1056
1134
  {
1057
1135
  title: "Get image usage",
@@ -1060,7 +1138,7 @@ function getImageUsageTool(server) {
1060
1138
  },
1061
1139
  async ({ filename }) => handleGetImageUsageTool(filename)
1062
1140
  );
1063
- tool.update({ outputSchema: { filename: z19.string(), pages: z19.array(z19.record(z19.unknown())), count: z19.number() } });
1141
+ tool.update({ outputSchema: { filename: z20.string(), pages: z20.array(z20.record(z20.unknown())), count: z20.number() } });
1064
1142
  return tool;
1065
1143
  }
1066
1144
  async function handleGetImageUsageTool(filename) {
@@ -1082,13 +1160,13 @@ async function handleGetImageUsageTool(filename) {
1082
1160
  }
1083
1161
 
1084
1162
  // src/tools/ro/get-image-info.ts
1085
- import { z as z20 } from "zod";
1163
+ import { z as z21 } from "zod";
1086
1164
  function getImageInfoTool(server) {
1087
1165
  const tool = server.tool(
1088
1166
  "get-image-info",
1089
1167
  "Get detailed information about an image file",
1090
1168
  {
1091
- filename: z20.string().describe("Image filename with File: prefix")
1169
+ filename: z21.string().describe("Image filename with File: prefix")
1092
1170
  },
1093
1171
  {
1094
1172
  title: "Get image info",
@@ -1097,7 +1175,7 @@ function getImageInfoTool(server) {
1097
1175
  },
1098
1176
  async ({ filename }) => handleGetImageInfoTool(filename)
1099
1177
  );
1100
- tool.update({ outputSchema: { filename: z20.string(), info: z20.record(z20.unknown()) } });
1178
+ tool.update({ outputSchema: { filename: z21.string(), info: z21.record(z21.unknown()) } });
1101
1179
  return tool;
1102
1180
  }
1103
1181
  async function handleGetImageInfoTool(filename) {
@@ -1121,15 +1199,15 @@ async function handleGetImageInfoTool(filename) {
1121
1199
  }
1122
1200
 
1123
1201
  // src/tools/ro/get-log.ts
1124
- import { z as z21 } from "zod";
1202
+ import { z as z22 } from "zod";
1125
1203
  function getLogTool(server) {
1126
1204
  const tool = server.tool(
1127
1205
  "get-log",
1128
1206
  "Get log entries of a specific type",
1129
1207
  {
1130
- type: z21.string().describe("Log type (e.g. delete, block, move)"),
1131
- start: z21.string().optional().default("").describe("Start timestamp (YYYYMMDDHHMMSS format)"),
1132
- limit: z21.number().optional().default(50).describe("Maximum number of entries to return")
1208
+ type: z22.string().describe("Log type (e.g. delete, block, move)"),
1209
+ start: z22.string().optional().default("").describe("Start timestamp (YYYYMMDDHHMMSS format)"),
1210
+ limit: z22.number().optional().default(50).describe("Maximum number of entries to return")
1133
1211
  },
1134
1212
  {
1135
1213
  title: "Get log entries",
@@ -1138,7 +1216,7 @@ function getLogTool(server) {
1138
1216
  },
1139
1217
  async ({ type, start, limit }) => handleGetLogTool(type, start, limit)
1140
1218
  );
1141
- tool.update({ outputSchema: { type: z21.string(), start: z21.string(), limit: z21.number(), total: z21.number(), displayed: z21.number(), entries: z21.array(z21.record(z21.unknown())) } });
1219
+ tool.update({ outputSchema: { type: z22.string(), start: z22.string(), limit: z22.number(), total: z22.number(), displayed: z22.number(), entries: z22.array(z22.record(z22.unknown())) } });
1142
1220
  return tool;
1143
1221
  }
1144
1222
  async function handleGetLogTool(type, start, limit) {
@@ -1169,14 +1247,14 @@ async function handleGetLogTool(type, start, limit) {
1169
1247
  }
1170
1248
 
1171
1249
  // src/tools/ro/expand-templates.ts
1172
- import { z as z22 } from "zod";
1250
+ import { z as z23 } from "zod";
1173
1251
  function expandTemplatesTool(server) {
1174
1252
  return server.tool(
1175
1253
  "expand-templates",
1176
1254
  "Expand templates in wikitext",
1177
1255
  {
1178
- text: z22.string().describe("Wikitext with templates to expand"),
1179
- title: z22.string().optional().describe("Context page title")
1256
+ text: z23.string().describe("Wikitext with templates to expand"),
1257
+ title: z23.string().optional().describe("Context page title (for resolving {{PAGENAME}} and similar magic words)")
1180
1258
  },
1181
1259
  {
1182
1260
  title: "Expand templates",
@@ -1213,14 +1291,14 @@ async function handleExpandTemplatesTool(text, title) {
1213
1291
  }
1214
1292
 
1215
1293
  // src/tools/ro/parse.ts
1216
- import { z as z23 } from "zod";
1294
+ import { z as z24 } from "zod";
1217
1295
  function parseTool(server) {
1218
1296
  return server.tool(
1219
1297
  "parse",
1220
1298
  "Parse wikitext to HTML",
1221
1299
  {
1222
- text: z23.string().describe("Wikitext to parse"),
1223
- title: z23.string().optional().describe("Context page title")
1300
+ text: z24.string().describe("Wikitext to parse"),
1301
+ title: z24.string().optional().describe("Context page title (for resolving {{PAGENAME}} and similar magic words)")
1224
1302
  },
1225
1303
  {
1226
1304
  title: "Parse wikitext",
@@ -1260,14 +1338,14 @@ async function handleParseTool(text, title) {
1260
1338
  }
1261
1339
 
1262
1340
  // src/tools/ro/get-recent-changes.ts
1263
- import { z as z24 } from "zod";
1341
+ import { z as z25 } from "zod";
1264
1342
  function getRecentChangesTool(server) {
1265
1343
  const tool = server.tool(
1266
1344
  "get-recent-changes",
1267
1345
  "Get recent changes on the wiki",
1268
1346
  {
1269
- start: z24.string().optional().describe("Start timestamp"),
1270
- limit: z24.number().optional().default(50).describe("Maximum number of changes to return")
1347
+ start: z25.string().optional().describe("Start timestamp (YYYYMMDDHHMMSS format)"),
1348
+ limit: z25.number().optional().default(50).describe("Maximum number of changes to return")
1271
1349
  },
1272
1350
  {
1273
1351
  title: "Get recent changes",
@@ -1276,7 +1354,7 @@ function getRecentChangesTool(server) {
1276
1354
  },
1277
1355
  async ({ start, limit }) => handleGetRecentChangesTool(start, limit)
1278
1356
  );
1279
- tool.update({ outputSchema: { total: z24.number(), limit: z24.number(), start: z24.string(), changes: z24.array(z24.record(z24.unknown())) } });
1357
+ tool.update({ outputSchema: { total: z25.number(), limit: z25.number(), start: z25.string().optional(), changes: z25.array(z25.record(z25.unknown())) } });
1280
1358
  return tool;
1281
1359
  }
1282
1360
  async function handleGetRecentChangesTool(start, limit = 50) {
@@ -1305,13 +1383,13 @@ async function handleGetRecentChangesTool(start, limit = 50) {
1305
1383
  }
1306
1384
 
1307
1385
  // src/tools/ro/get-site-info.ts
1308
- import { z as z25 } from "zod";
1386
+ import { z as z26 } from "zod";
1309
1387
  function getSiteInfoTool(server) {
1310
1388
  const tool = server.tool(
1311
1389
  "get-site-info",
1312
1390
  "Get site information from MediaWiki",
1313
1391
  {
1314
- properties: z25.array(z25.string()).describe("List of site information properties to retrieve")
1392
+ properties: z26.array(z26.string()).describe("List of site information properties to retrieve")
1315
1393
  },
1316
1394
  {
1317
1395
  title: "Get site info",
@@ -1320,7 +1398,7 @@ function getSiteInfoTool(server) {
1320
1398
  },
1321
1399
  async ({ properties }) => handleGetSiteInfoTool(properties)
1322
1400
  );
1323
- tool.update({ outputSchema: {} });
1401
+ tool.update({ outputSchema: { siteinfo: z26.record(z26.unknown()) } });
1324
1402
  return tool;
1325
1403
  }
1326
1404
  async function handleGetSiteInfoTool(properties) {
@@ -1331,13 +1409,14 @@ async function handleGetSiteInfoTool(properties) {
1331
1409
  "getSiteInfo",
1332
1410
  properties
1333
1411
  );
1334
- return jsonResult(info || {});
1412
+ return jsonResult({ siteinfo: info || {} });
1335
1413
  } catch (error) {
1336
1414
  return errorResult("Failed to get site info", error);
1337
1415
  }
1338
1416
  }
1339
1417
 
1340
1418
  // src/tools/ro/get-site-stats.ts
1419
+ import { z as z27 } from "zod";
1341
1420
  function getSiteStatsTool(server) {
1342
1421
  const tool = server.tool(
1343
1422
  "get-site-stats",
@@ -1350,7 +1429,16 @@ function getSiteStatsTool(server) {
1350
1429
  },
1351
1430
  async () => handleGetSiteStatsTool()
1352
1431
  );
1353
- tool.update({ outputSchema: {} });
1432
+ tool.update({ outputSchema: { statistics: z27.object({
1433
+ pages: z27.number(),
1434
+ articles: z27.number(),
1435
+ edits: z27.number(),
1436
+ images: z27.number(),
1437
+ users: z27.number(),
1438
+ activeusers: z27.number(),
1439
+ admins: z27.number(),
1440
+ jobs: z27.number()
1441
+ }) } });
1354
1442
  return tool;
1355
1443
  }
1356
1444
  async function handleGetSiteStatsTool() {
@@ -1360,14 +1448,14 @@ async function handleGetSiteStatsTool() {
1360
1448
  bot,
1361
1449
  "getSiteStats"
1362
1450
  );
1363
- return jsonResult(stats);
1451
+ return jsonResult({ statistics: stats });
1364
1452
  } catch (error) {
1365
1453
  return errorResult("Failed to get site stats", error);
1366
1454
  }
1367
1455
  }
1368
1456
 
1369
1457
  // src/tools/ro/get-mediawiki-version.ts
1370
- import { z as z26 } from "zod";
1458
+ import { z as z28 } from "zod";
1371
1459
  function getMediaWikiVersionTool(server) {
1372
1460
  const tool = server.tool(
1373
1461
  "get-mediawiki-version",
@@ -1380,7 +1468,7 @@ function getMediaWikiVersionTool(server) {
1380
1468
  },
1381
1469
  async () => handleGetMediaWikiVersionTool()
1382
1470
  );
1383
- tool.update({ outputSchema: { version: z26.string() } });
1471
+ tool.update({ outputSchema: { version: z28.string() } });
1384
1472
  return tool;
1385
1473
  }
1386
1474
  async function handleGetMediaWikiVersionTool() {
@@ -1397,13 +1485,13 @@ async function handleGetMediaWikiVersionTool() {
1397
1485
  }
1398
1486
 
1399
1487
  // src/tools/ro/get-query-page.ts
1400
- import { z as z27 } from "zod";
1488
+ import { z as z29 } from "zod";
1401
1489
  function getQueryPageTool(server) {
1402
1490
  const tool = server.tool(
1403
1491
  "get-query-page",
1404
- "Get results from a query page (special page)",
1492
+ "Get results from a query page (e.g. Ancientpages, Lonelypages, Wantedpages)",
1405
1493
  {
1406
- name: z27.string().describe("Name of the query page")
1494
+ name: z29.string().describe("Name of the query page")
1407
1495
  },
1408
1496
  {
1409
1497
  title: "Get query page results",
@@ -1412,7 +1500,7 @@ function getQueryPageTool(server) {
1412
1500
  },
1413
1501
  async ({ name }) => handleGetQueryPageTool(name)
1414
1502
  );
1415
- tool.update({ outputSchema: { name: z27.string(), results: z27.array(z27.record(z27.unknown())), count: z27.number() } });
1503
+ tool.update({ outputSchema: { name: z29.string(), results: z29.array(z29.record(z29.unknown())), count: z29.number() } });
1416
1504
  return tool;
1417
1505
  }
1418
1506
  async function handleGetQueryPageTool(name) {
@@ -1434,13 +1522,13 @@ async function handleGetQueryPageTool(name) {
1434
1522
  }
1435
1523
 
1436
1524
  // src/tools/ro/get-external-links.ts
1437
- import { z as z28 } from "zod";
1525
+ import { z as z30 } from "zod";
1438
1526
  function getExternalLinksTool(server) {
1439
1527
  const tool = server.tool(
1440
1528
  "get-external-links",
1441
1529
  "Get all external links from an article",
1442
1530
  {
1443
- title: z28.union([z28.string(), z28.number()]).describe("Article title or page ID")
1531
+ title: z30.union([z30.string(), z30.number()]).describe("Article title or page ID")
1444
1532
  },
1445
1533
  {
1446
1534
  title: "Get external links",
@@ -1449,7 +1537,7 @@ function getExternalLinksTool(server) {
1449
1537
  },
1450
1538
  async ({ title }) => handleGetExternalLinksTool(title)
1451
1539
  );
1452
- tool.update({ outputSchema: { title: z28.string(), links: z28.array(z28.record(z28.unknown())), count: z28.number() } });
1540
+ tool.update({ outputSchema: { title: z30.string(), links: z30.array(z30.record(z30.unknown())), count: z30.number() } });
1453
1541
  return tool;
1454
1542
  }
1455
1543
  async function handleGetExternalLinksTool(title) {
@@ -1471,13 +1559,13 @@ async function handleGetExternalLinksTool(title) {
1471
1559
  }
1472
1560
 
1473
1561
  // src/tools/ro/get-backlinks.ts
1474
- import { z as z29 } from "zod";
1562
+ import { z as z31 } from "zod";
1475
1563
  function getBacklinksTool(server) {
1476
1564
  const tool = server.tool(
1477
1565
  "get-backlinks",
1478
1566
  "Get all backlinks to a specific page",
1479
1567
  {
1480
- title: z29.string().describe("Target page title to find backlinks for")
1568
+ title: z31.string().describe("Target page title to find backlinks for")
1481
1569
  },
1482
1570
  {
1483
1571
  title: "Get backlinks",
@@ -1486,7 +1574,7 @@ function getBacklinksTool(server) {
1486
1574
  },
1487
1575
  async ({ title }) => handleGetBacklinksTool(title)
1488
1576
  );
1489
- tool.update({ outputSchema: { target: z29.string(), backlinks: z29.array(z29.record(z29.unknown())), count: z29.number() } });
1577
+ tool.update({ outputSchema: { target: z31.string(), backlinks: z31.array(z31.record(z31.unknown())), count: z31.number() } });
1490
1578
  return tool;
1491
1579
  }
1492
1580
  async function handleGetBacklinksTool(title) {
@@ -1508,19 +1596,19 @@ async function handleGetBacklinksTool(title) {
1508
1596
  }
1509
1597
 
1510
1598
  // src/tools/editing/edit.ts
1511
- import { z as z30 } from "zod";
1599
+ import { z as z32 } from "zod";
1512
1600
  function editTool(server) {
1513
1601
  const tool = server.tool(
1514
1602
  "edit",
1515
1603
  "Replace the ENTIRE content of a wiki page (requires authentication). CRITICAL: This is a FULL replacement \u2014 content you provide becomes the complete page, not an addition. There is NO undelete/undo tool \u2014 any damage you cause must be manually reverted by a human. To add a category or make a small change, you MUST first call get-article to retrieve the current content, modify it as needed, then pass the FULL modified content here. For appending or prepending without fetching the full page first, use the append/prepend tools instead.",
1516
1604
  {
1517
- title: z30.string().describe("Page title to edit"),
1518
- content: z30.string().describe("COMPLETE new wikitext for the ENTIRE page \u2014 not a snippet, not a prefix, not an appendage. This replaces everything. Always fetch the current content with get-article first, then modify and resubmit the full text."),
1519
- intent: z30.enum(["add", "revise", "delete"]).describe(
1605
+ title: z32.string().describe("Page title to edit"),
1606
+ content: z32.string().describe("COMPLETE new wikitext for the ENTIRE page \u2014 not a snippet, not a prefix, not an appendage. This replaces everything. Always fetch the current content with get-article first, then modify and resubmit the full text."),
1607
+ intent: z32.enum(["add", "revise", "delete"]).describe(
1520
1608
  'Your editing intent: "add" = adding content (page should grow), "revise" = modifying content (small net change, must keep \u22653/4 of existing bytes), "delete" = removing significant content (page should shrink significantly)'
1521
1609
  ),
1522
- summary: z30.string().describe("Edit summary describing what was changed and why"),
1523
- minor: z30.boolean().optional().default(false).describe("Mark as minor edit")
1610
+ summary: z32.string().describe("Edit summary describing what was changed and why"),
1611
+ minor: z32.boolean().optional().default(false).describe("Mark as minor edit")
1524
1612
  },
1525
1613
  {
1526
1614
  title: "Edit page",
@@ -1529,7 +1617,7 @@ function editTool(server) {
1529
1617
  },
1530
1618
  async (params) => handleEditTool(params)
1531
1619
  );
1532
- tool.update({ outputSchema: {} });
1620
+ tool.update({ outputSchema: { result: z32.string(), pageid: z32.number(), title: z32.string(), contentmodel: z32.string(), newrevid: z32.number(), newtimestamp: z32.string(), oldrevid: z32.number().optional() } });
1533
1621
  return tool;
1534
1622
  }
1535
1623
  async function handleEditTool(params) {
@@ -1583,15 +1671,15 @@ async function handleEditTool(params) {
1583
1671
  }
1584
1672
 
1585
1673
  // src/tools/editing/append.ts
1586
- import { z as z31 } from "zod";
1674
+ import { z as z33 } from "zod";
1587
1675
  function appendTool(server) {
1588
1676
  const tool = server.tool(
1589
1677
  "append",
1590
1678
  "Append content to the END of a wiki page without changing existing content (requires authentication). Safe for adding categories, interwiki links, or any content that belongs at the bottom of a page.",
1591
1679
  {
1592
- title: z31.string().describe("Page title"),
1593
- content: z31.string().describe('Content to append to the end of the page (e.g., "\\n[[Category:MyCategory]]")'),
1594
- summary: z31.string().describe("Edit summary")
1680
+ title: z33.string().describe("Page title"),
1681
+ content: z33.string().describe('Content to append to the end of the page (e.g., "\\n[[Category:MyCategory]]")'),
1682
+ summary: z33.string().describe("Edit summary")
1595
1683
  },
1596
1684
  {
1597
1685
  title: "Append to page",
@@ -1600,7 +1688,7 @@ function appendTool(server) {
1600
1688
  },
1601
1689
  async (params) => handleAppendTool(params)
1602
1690
  );
1603
- tool.update({ outputSchema: { success: z31.boolean(), title: z31.string() } });
1691
+ tool.update({ outputSchema: { success: z33.boolean(), title: z33.string() } });
1604
1692
  return tool;
1605
1693
  }
1606
1694
  async function handleAppendTool(params) {
@@ -1622,15 +1710,15 @@ async function handleAppendTool(params) {
1622
1710
  }
1623
1711
 
1624
1712
  // src/tools/editing/prepend.ts
1625
- import { z as z32 } from "zod";
1713
+ import { z as z34 } from "zod";
1626
1714
  function prependTool(server) {
1627
1715
  const tool = server.tool(
1628
1716
  "prepend",
1629
1717
  "Prepend content to the TOP of a wiki page without changing existing content (requires authentication). Useful for adding notices, templates, or cleanup tags that belong at the top of a page.",
1630
1718
  {
1631
- title: z32.string().describe("Page title to prepend to"),
1632
- content: z32.string().describe('Content to prepend to the top of the page (e.g., "{{Cleanup}}\\n")'),
1633
- summary: z32.string().describe("Edit summary")
1719
+ title: z34.string().describe("Page title to prepend to"),
1720
+ content: z34.string().describe('Content to prepend to the top of the page (e.g., "{{Cleanup}}\\n")'),
1721
+ summary: z34.string().describe("Edit summary")
1634
1722
  },
1635
1723
  {
1636
1724
  title: "Prepend to page",
@@ -1639,7 +1727,7 @@ function prependTool(server) {
1639
1727
  },
1640
1728
  async (params) => handlePrependTool(params)
1641
1729
  );
1642
- tool.update({ outputSchema: {} });
1730
+ tool.update({ outputSchema: { result: z34.string(), pageid: z34.number(), title: z34.string(), contentmodel: z34.string(), newrevid: z34.number(), newtimestamp: z34.string(), oldrevid: z34.number().optional() } });
1643
1731
  return tool;
1644
1732
  }
1645
1733
  async function handlePrependTool(params) {
@@ -1661,15 +1749,15 @@ async function handlePrependTool(params) {
1661
1749
  }
1662
1750
 
1663
1751
  // src/tools/editing/move.ts
1664
- import { z as z33 } from "zod";
1752
+ import { z as z35 } from "zod";
1665
1753
  function moveTool(server) {
1666
1754
  const tool = server.tool(
1667
1755
  "move",
1668
1756
  "Move (rename) a wiki page \u2014 changes the page title and creates a redirect from the old name (requires authentication). The old page title becomes a redirect to the new title. All page history moves with the page.",
1669
1757
  {
1670
- from: z33.string().describe("Current/existing page title to rename"),
1671
- to: z33.string().describe("New target page title \u2014 must not already exist (unless moving to overwrite)"),
1672
- summary: z33.string().describe("Reason for the move (visible in move log)")
1758
+ from: z35.string().describe("Current/existing page title to rename"),
1759
+ to: z35.string().describe("New target page title \u2014 must not already exist (unless moving to overwrite)"),
1760
+ summary: z35.string().describe("Reason for the move (visible in move log)")
1673
1761
  },
1674
1762
  {
1675
1763
  title: "Move page",
@@ -1678,7 +1766,7 @@ function moveTool(server) {
1678
1766
  },
1679
1767
  async (params) => handleMoveTool(params)
1680
1768
  );
1681
- tool.update({ outputSchema: {} });
1769
+ tool.update({ outputSchema: { from: z35.string(), to: z35.string(), reason: z35.string(), redirectcreated: z35.boolean().optional() } });
1682
1770
  return tool;
1683
1771
  }
1684
1772
  async function handleMoveTool(params) {
@@ -1700,14 +1788,14 @@ async function handleMoveTool(params) {
1700
1788
  }
1701
1789
 
1702
1790
  // src/tools/editing/delete.ts
1703
- import { z as z34 } from "zod";
1791
+ import { z as z36 } from "zod";
1704
1792
  function deleteTool(server) {
1705
1793
  const tool = server.tool(
1706
1794
  "delete",
1707
1795
  "PERMANENTLY delete a wiki page (requires authentication). CRITICAL: This action is IRREVERSIBLE \u2014 there is NO undelete/undo tool available. Any deletion must be manually restored by a human administrator. Only delete a page when the user explicitly asks for it. Always verify the title is correct before proceeding.",
1708
1796
  {
1709
- title: z34.string().describe("Exact page title to permanently delete \u2014 double-check this is correct"),
1710
- reason: z34.string().describe("Detailed reason for deletion (visible in deletion log)")
1797
+ title: z36.string().describe("Exact page title to permanently delete \u2014 double-check this is correct"),
1798
+ reason: z36.string().describe("Detailed reason for deletion (visible in deletion log)")
1711
1799
  },
1712
1800
  {
1713
1801
  title: "Delete page",
@@ -1716,7 +1804,7 @@ function deleteTool(server) {
1716
1804
  },
1717
1805
  async (params) => handleDeleteTool(params)
1718
1806
  );
1719
- tool.update({ outputSchema: {} });
1807
+ tool.update({ outputSchema: { title: z36.string(), reason: z36.string(), logid: z36.number() } });
1720
1808
  return tool;
1721
1809
  }
1722
1810
  async function handleDeleteTool(params) {
@@ -1737,24 +1825,24 @@ async function handleDeleteTool(params) {
1737
1825
  }
1738
1826
 
1739
1827
  // src/tools/editing/protect.ts
1740
- import { z as z35 } from "zod";
1828
+ import { z as z37 } from "zod";
1741
1829
  function protectTool(server) {
1742
1830
  const tool = server.tool(
1743
1831
  "protect",
1744
1832
  'Protect or unprotect a wiki page to restrict editing/moving (requires authentication). CRITICAL: Protection can lock out legitimate editors \u2014 only protect pages when there is a clear need (ongoing vandalism, edit war, high-risk template, policy page). To remove protection, set level to "all". Available levels: "all" (anyone), "autoconfirmed" (trusted users), "sysop" (admins only).',
1745
1833
  {
1746
- title: z35.string().describe("Page title to protect or unprotect"),
1747
- protections: z35.array(
1748
- z35.object({
1749
- type: z35.enum(["edit", "move"]).describe('Action to restrict: "edit" or "move"'),
1750
- level: z35.enum(["all", "autoconfirmed", "sysop"]).optional().default("all").describe(
1834
+ title: z37.string().describe("Page title to protect or unprotect"),
1835
+ protections: z37.array(
1836
+ z37.object({
1837
+ type: z37.enum(["edit", "move"]).describe('Action to restrict: "edit" or "move"'),
1838
+ level: z37.enum(["all", "autoconfirmed", "sysop"]).optional().default("all").describe(
1751
1839
  'Who can perform this action: "all" = no restriction, "autoconfirmed" = trusted users only, "sysop" = admins only'
1752
1840
  ),
1753
- expiry: z35.string().optional().describe('How long protection lasts (e.g. "1 day", "1 week", "infinite"). Default is indefinite.')
1841
+ expiry: z37.string().optional().describe('How long protection lasts (e.g. "1 day", "1 week", "infinite"). Default is indefinite.')
1754
1842
  })
1755
1843
  ).describe('Protection rules \u2014 typically one entry for "edit" and optionally one for "move". Example: [{type:"edit",level:"sysop",expiry:"1 week"}]'),
1756
- reason: z35.string().optional().describe("Reason for changing protection, visible in the page log"),
1757
- cascade: z35.boolean().optional().default(false).describe("If true, transcluded templates/pages inherit this protection. Only works with full sysop protection on edit. Use with caution.")
1844
+ reason: z37.string().optional().describe("Reason for changing protection, visible in the page log"),
1845
+ cascade: z37.boolean().optional().default(false).describe("If true, transcluded templates/pages inherit this protection. Only works with full sysop protection on edit. Use with caution.")
1758
1846
  },
1759
1847
  {
1760
1848
  title: "Protect page",
@@ -1763,7 +1851,7 @@ function protectTool(server) {
1763
1851
  },
1764
1852
  async (params) => handleProtectTool(params)
1765
1853
  );
1766
- tool.update({ outputSchema: {} });
1854
+ tool.update({ outputSchema: { title: z37.string(), reason: z37.string().optional(), protections: z37.array(z37.record(z37.unknown())), cascade: z37.boolean() } });
1767
1855
  return tool;
1768
1856
  }
1769
1857
  async function handleProtectTool(params) {
@@ -1791,13 +1879,13 @@ async function handleProtectTool(params) {
1791
1879
  }
1792
1880
 
1793
1881
  // src/tools/editing/purge.ts
1794
- import { z as z36 } from "zod";
1882
+ import { z as z38 } from "zod";
1795
1883
  function purgeTool(server) {
1796
1884
  const tool = server.tool(
1797
1885
  "purge",
1798
1886
  "Purge the server-side cache for one or more wiki pages (requires authentication). Forces MediaWiki to regenerate the page from current wikitext. This is a safe, non-destructive action.",
1799
1887
  {
1800
- titles: z36.union([z36.string(), z36.array(z36.string())]).describe("Page title(s) or category name to purge")
1888
+ titles: z38.union([z38.string(), z38.array(z38.string())]).describe("Page title(s) or category name to purge")
1801
1889
  },
1802
1890
  {
1803
1891
  title: "Purge pages",
@@ -1806,7 +1894,7 @@ function purgeTool(server) {
1806
1894
  },
1807
1895
  async (params) => handlePurgeTool(params)
1808
1896
  );
1809
- tool.update({ outputSchema: {} });
1897
+ tool.update({ outputSchema: { pages: z38.array(z38.record(z38.unknown())) } });
1810
1898
  return tool;
1811
1899
  }
1812
1900
  async function handlePurgeTool(params) {
@@ -1817,22 +1905,22 @@ async function handlePurgeTool(params) {
1817
1905
  "purge",
1818
1906
  params.titles
1819
1907
  );
1820
- return jsonResult(result);
1908
+ return jsonResult({ pages: result });
1821
1909
  } catch (error) {
1822
1910
  return errorResult("Failed to purge pages", error);
1823
1911
  }
1824
1912
  }
1825
1913
 
1826
1914
  // src/tools/editing/send-email.ts
1827
- import { z as z37 } from "zod";
1915
+ import { z as z39 } from "zod";
1828
1916
  function sendEmailTool(server) {
1829
1917
  const tool = server.tool(
1830
1918
  "send-email",
1831
1919
  "Send an ACTUAL email to a wiki user via the wiki's built-in email system (requires authentication). CRITICAL: This sends a real email to the user's registered address \u2014 it is NOT a simulation. The recipient will see it came from the authenticated bot operator's wiki account. Abuse (spam, harassment, unsolicited messages) WILL result in the bot account being blocked. ONLY use this when the human user has explicitly asked you to send an email.",
1832
1920
  {
1833
- username: z37.string().describe("Target wiki username \u2014 email goes to their registered email address"),
1834
- subject: z37.string().describe("Email subject line \u2014 be clear and professional, no misleading subjects"),
1835
- text: z37.string().describe("Plain text email body \u2014 will be delivered as-is to the recipient's inbox")
1921
+ username: z39.string().describe("Target wiki username \u2014 email goes to their registered email address"),
1922
+ subject: z39.string().describe("Email subject line \u2014 be clear and professional, no misleading subjects"),
1923
+ text: z39.string().describe("Plain text email body \u2014 will be delivered as-is to the recipient's inbox")
1836
1924
  },
1837
1925
  {
1838
1926
  title: "Send email",
@@ -1841,7 +1929,7 @@ function sendEmailTool(server) {
1841
1929
  },
1842
1930
  async (params) => handleSendEmailTool(params)
1843
1931
  );
1844
- tool.update({ outputSchema: {} });
1932
+ tool.update({ outputSchema: { result: z39.string(), message: z39.string().optional() } });
1845
1933
  return tool;
1846
1934
  }
1847
1935
  async function handleSendEmailTool(params) {
@@ -1861,15 +1949,15 @@ async function handleSendEmailTool(params) {
1861
1949
  }
1862
1950
 
1863
1951
  // src/tools/editing/upload.ts
1864
- import { z as z38 } from "zod";
1952
+ import { z as z40 } from "zod";
1865
1953
  function uploadTool(server) {
1866
1954
  const tool = server.tool(
1867
1955
  "upload",
1868
1956
  "Upload a file to the wiki (requires authentication). CRITICAL: If a file with the same name already exists, it WILL BE OVERWRITTEN. Ensure you have the right to upload the content. Use only when explicitly requested.",
1869
1957
  {
1870
- filename: z38.string().describe('Destination filename on wiki (e.g., "MyImage.png") \u2014 existing file will be overwritten!'),
1871
- content: z38.string().describe("File content encoded as base64 string"),
1872
- comment: z38.string().optional().describe("Upload comment describing the file")
1958
+ filename: z40.string().describe('Destination filename on wiki (e.g., "MyImage.png") \u2014 existing file will be overwritten!'),
1959
+ content: z40.string().describe("File content encoded as base64 string"),
1960
+ comment: z40.string().optional().describe("Upload comment describing the file")
1873
1961
  },
1874
1962
  {
1875
1963
  title: "Upload file",
@@ -1878,7 +1966,7 @@ function uploadTool(server) {
1878
1966
  },
1879
1967
  async (params) => handleUploadTool(params)
1880
1968
  );
1881
- tool.update({ outputSchema: {} });
1969
+ tool.update({ outputSchema: { result: z40.string(), filename: z40.string(), imageinfo: z40.record(z40.unknown()).optional() } });
1882
1970
  return tool;
1883
1971
  }
1884
1972
  async function handleUploadTool(params) {
@@ -1900,15 +1988,15 @@ async function handleUploadTool(params) {
1900
1988
  }
1901
1989
 
1902
1990
  // src/tools/editing/upload-by-url.ts
1903
- import { z as z39 } from "zod";
1991
+ import { z as z41 } from "zod";
1904
1992
  function uploadByUrlTool(server) {
1905
1993
  const tool = server.tool(
1906
1994
  "upload-by-url",
1907
1995
  "Upload a file to the wiki by downloading it from a URL (requires authentication). CRITICAL: If a file with the same name already exists, it WILL BE OVERWRITTEN. Ensure you have the right to upload the content from the source URL.",
1908
1996
  {
1909
- filename: z39.string().describe('Destination filename on wiki (e.g., "Diagram.png") \u2014 existing file will be overwritten!'),
1910
- url: z39.string().url().describe("Source URL to download the file from \u2014 must be publicly accessible"),
1911
- summary: z39.string().optional().describe("Upload summary")
1997
+ filename: z41.string().describe('Destination filename on wiki (e.g., "Diagram.png") \u2014 existing file will be overwritten!'),
1998
+ url: z41.string().url().describe("Source URL to download the file from \u2014 must be publicly accessible"),
1999
+ summary: z41.string().optional().describe("Upload summary")
1912
2000
  },
1913
2001
  {
1914
2002
  title: "Upload file by URL",
@@ -1917,7 +2005,7 @@ function uploadByUrlTool(server) {
1917
2005
  },
1918
2006
  async (params) => handleUploadByUrlTool(params)
1919
2007
  );
1920
- tool.update({ outputSchema: {} });
2008
+ tool.update({ outputSchema: { result: z41.string(), filename: z41.string(), imageinfo: z41.record(z41.unknown()).optional() } });
1921
2009
  return tool;
1922
2010
  }
1923
2011
  async function handleUploadByUrlTool(params) {
@@ -1938,15 +2026,15 @@ async function handleUploadByUrlTool(params) {
1938
2026
  }
1939
2027
 
1940
2028
  // src/tools/editing/add-flow-topic.ts
1941
- import { z as z40 } from "zod";
2029
+ import { z as z42 } from "zod";
1942
2030
  function addFlowTopicTool(server) {
1943
2031
  const tool = server.tool(
1944
2032
  "add-flow-topic",
1945
2033
  "Add a new Flow/Structured Discussions topic to a wiki talk page (requires authentication). Creates a publicly visible discussion thread on the wiki. Ensure the content is appropriate and relevant.",
1946
2034
  {
1947
- title: z40.string().describe('Talk page title to add the topic to (e.g., "Talk:Main Page")'),
1948
- subject: z40.string().describe("Topic title/heading \u2014 should summarize the discussion topic"),
1949
- content: z40.string().describe("Topic body content in wikitext format")
2035
+ title: z42.string().describe('Talk page title to add the topic to (e.g., "Talk:Main Page")'),
2036
+ subject: z42.string().describe("Topic title/heading \u2014 should summarize the discussion topic"),
2037
+ content: z42.string().describe("Topic body content in wikitext format")
1950
2038
  },
1951
2039
  {
1952
2040
  title: "Add Flow topic",
@@ -1955,7 +2043,7 @@ function addFlowTopicTool(server) {
1955
2043
  },
1956
2044
  async (params) => handleAddFlowTopicTool(params)
1957
2045
  );
1958
- tool.update({ outputSchema: {} });
2046
+ tool.update({ outputSchema: { "new-topic": z42.record(z42.unknown()) } });
1959
2047
  return tool;
1960
2048
  }
1961
2049
  async function handleAddFlowTopicTool(params) {
@@ -1975,14 +2063,14 @@ async function handleAddFlowTopicTool(params) {
1975
2063
  }
1976
2064
 
1977
2065
  // src/tools/editing/create-account.ts
1978
- import { z as z41 } from "zod";
2066
+ import { z as z43 } from "zod";
1979
2067
  function createAccountTool(server) {
1980
2068
  const tool = server.tool(
1981
2069
  "create-account",
1982
2070
  "Create a NEW user account on the wiki (requires authentication). CRITICAL: This creates a real user account. Do NOT create accounts for yourself or without explicit user request. The account will be permanently registered on the wiki.",
1983
2071
  {
1984
- username: z41.string().describe("Desired username for the new account \u2014 must follow wiki username rules"),
1985
- password: z41.string().describe("Password for the new account \u2014 use a strong, unique password")
2072
+ username: z43.string().describe("Desired username for the new account \u2014 must follow wiki username rules"),
2073
+ password: z43.string().describe("Password for the new account \u2014 use a strong, unique password")
1986
2074
  },
1987
2075
  {
1988
2076
  title: "Create user account",
@@ -1991,7 +2079,7 @@ function createAccountTool(server) {
1991
2079
  },
1992
2080
  async (params) => handleCreateAccountTool(params)
1993
2081
  );
1994
- tool.update({ outputSchema: {} });
2082
+ tool.update({ outputSchema: { account: z43.record(z43.unknown()) } });
1995
2083
  return tool;
1996
2084
  }
1997
2085
  async function handleCreateAccountTool(params) {
@@ -2003,7 +2091,7 @@ async function handleCreateAccountTool(params) {
2003
2091
  params.username,
2004
2092
  params.password
2005
2093
  );
2006
- return jsonResult(result);
2094
+ return jsonResult({ account: result });
2007
2095
  } catch (error) {
2008
2096
  return errorResult("Failed to create account", error);
2009
2097
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xiedada/nodemw-mcp-server",
3
- "version": "0.0.6",
3
+ "version": "0.0.9",
4
4
  "description": "MCP server for nodemw - MediaWiki API client",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",