@contentful/mcp-tools 0.7.0 → 0.8.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.
package/dist/index.d.ts CHANGED
@@ -63,6 +63,8 @@ interface ContentfulConfig {
63
63
  hostDelivery?: string;
64
64
  /** Environment IDs that are protected from write/delete operations */
65
65
  protectedEnvironments?: string[];
66
+ /** Maximum number of IDs allowed in a single bulk-operation tool call. Defaults to 10 when unset. */
67
+ maxBulkSize?: number;
66
68
  }
67
69
 
68
70
  /**
@@ -994,6 +996,7 @@ declare class ContentfulMcpTools {
994
996
  environmentId: zod.ZodString;
995
997
  } & {
996
998
  assetId: zod.ZodUnion<[zod.ZodString, zod.ZodArray<zod.ZodString, "many">]>;
999
+ dryRun: zod.ZodOptional<zod.ZodBoolean>;
997
1000
  };
998
1001
  annotations: {
999
1002
  readOnlyHint: boolean;
@@ -1005,6 +1008,7 @@ declare class ContentfulMcpTools {
1005
1008
  spaceId: string;
1006
1009
  environmentId: string;
1007
1010
  assetId: string | string[];
1011
+ dryRun?: boolean | undefined;
1008
1012
  }, extra?: _modelcontextprotocol_sdk_shared_protocol_js.RequestHandlerExtra<_modelcontextprotocol_sdk_types_js.ServerRequest, _modelcontextprotocol_sdk_types_js.ServerNotification>) => Promise<ToolResponse>;
1009
1013
  };
1010
1014
  unpublishAsset: {
@@ -1015,6 +1019,7 @@ declare class ContentfulMcpTools {
1015
1019
  environmentId: zod.ZodString;
1016
1020
  } & {
1017
1021
  assetId: zod.ZodUnion<[zod.ZodString, zod.ZodArray<zod.ZodString, "many">]>;
1022
+ dryRun: zod.ZodOptional<zod.ZodBoolean>;
1018
1023
  };
1019
1024
  annotations: {
1020
1025
  readOnlyHint: boolean;
@@ -1026,6 +1031,7 @@ declare class ContentfulMcpTools {
1026
1031
  spaceId: string;
1027
1032
  environmentId: string;
1028
1033
  assetId: string | string[];
1034
+ dryRun?: boolean | undefined;
1029
1035
  }, extra?: _modelcontextprotocol_sdk_shared_protocol_js.RequestHandlerExtra<_modelcontextprotocol_sdk_types_js.ServerRequest, _modelcontextprotocol_sdk_types_js.ServerNotification>) => Promise<ToolResponse>;
1030
1036
  };
1031
1037
  archiveAsset: {
@@ -1036,6 +1042,7 @@ declare class ContentfulMcpTools {
1036
1042
  environmentId: zod.ZodString;
1037
1043
  } & {
1038
1044
  assetId: zod.ZodUnion<[zod.ZodString, zod.ZodArray<zod.ZodString, "many">]>;
1045
+ dryRun: zod.ZodOptional<zod.ZodBoolean>;
1039
1046
  };
1040
1047
  annotations: {
1041
1048
  readOnlyHint: boolean;
@@ -1047,6 +1054,7 @@ declare class ContentfulMcpTools {
1047
1054
  spaceId: string;
1048
1055
  environmentId: string;
1049
1056
  assetId: string | string[];
1057
+ dryRun?: boolean | undefined;
1050
1058
  }, extra?: _modelcontextprotocol_sdk_shared_protocol_js.RequestHandlerExtra<_modelcontextprotocol_sdk_types_js.ServerRequest, _modelcontextprotocol_sdk_types_js.ServerNotification>) => Promise<ToolResponse>;
1051
1059
  };
1052
1060
  unarchiveAsset: {
@@ -1057,6 +1065,7 @@ declare class ContentfulMcpTools {
1057
1065
  environmentId: zod.ZodString;
1058
1066
  } & {
1059
1067
  assetId: zod.ZodUnion<[zod.ZodString, zod.ZodArray<zod.ZodString, "many">]>;
1068
+ dryRun: zod.ZodOptional<zod.ZodBoolean>;
1060
1069
  };
1061
1070
  annotations: {
1062
1071
  readOnlyHint: boolean;
@@ -1068,6 +1077,7 @@ declare class ContentfulMcpTools {
1068
1077
  spaceId: string;
1069
1078
  environmentId: string;
1070
1079
  assetId: string | string[];
1080
+ dryRun?: boolean | undefined;
1071
1081
  }, extra?: _modelcontextprotocol_sdk_shared_protocol_js.RequestHandlerExtra<_modelcontextprotocol_sdk_types_js.ServerRequest, _modelcontextprotocol_sdk_types_js.ServerNotification>) => Promise<ToolResponse>;
1072
1082
  };
1073
1083
  };
@@ -5003,6 +5013,7 @@ declare class ContentfulMcpTools {
5003
5013
  environmentId: zod.ZodString;
5004
5014
  } & {
5005
5015
  entryId: zod.ZodArray<zod.ZodString, "many">;
5016
+ dryRun: zod.ZodOptional<zod.ZodBoolean>;
5006
5017
  };
5007
5018
  annotations: {
5008
5019
  readOnlyHint: boolean;
@@ -5014,6 +5025,7 @@ declare class ContentfulMcpTools {
5014
5025
  spaceId: string;
5015
5026
  environmentId: string;
5016
5027
  entryId: string[];
5028
+ dryRun?: boolean | undefined;
5017
5029
  }, extra?: _modelcontextprotocol_sdk_shared_protocol_js.RequestHandlerExtra<_modelcontextprotocol_sdk_types_js.ServerRequest, _modelcontextprotocol_sdk_types_js.ServerNotification>) => Promise<ToolResponse>;
5018
5030
  };
5019
5031
  unpublishEntry: {
@@ -5024,6 +5036,7 @@ declare class ContentfulMcpTools {
5024
5036
  environmentId: zod.ZodString;
5025
5037
  } & {
5026
5038
  entryId: zod.ZodArray<zod.ZodString, "many">;
5039
+ dryRun: zod.ZodOptional<zod.ZodBoolean>;
5027
5040
  };
5028
5041
  annotations: {
5029
5042
  readOnlyHint: boolean;
@@ -5035,6 +5048,7 @@ declare class ContentfulMcpTools {
5035
5048
  spaceId: string;
5036
5049
  environmentId: string;
5037
5050
  entryId: string[];
5051
+ dryRun?: boolean | undefined;
5038
5052
  }, extra?: _modelcontextprotocol_sdk_shared_protocol_js.RequestHandlerExtra<_modelcontextprotocol_sdk_types_js.ServerRequest, _modelcontextprotocol_sdk_types_js.ServerNotification>) => Promise<ToolResponse>;
5039
5053
  };
5040
5054
  archiveEntry: {
@@ -5045,6 +5059,7 @@ declare class ContentfulMcpTools {
5045
5059
  environmentId: zod.ZodString;
5046
5060
  } & {
5047
5061
  entryId: zod.ZodArray<zod.ZodString, "many">;
5062
+ dryRun: zod.ZodOptional<zod.ZodBoolean>;
5048
5063
  };
5049
5064
  annotations: {
5050
5065
  readOnlyHint: boolean;
@@ -5056,6 +5071,7 @@ declare class ContentfulMcpTools {
5056
5071
  spaceId: string;
5057
5072
  environmentId: string;
5058
5073
  entryId: string[];
5074
+ dryRun?: boolean | undefined;
5059
5075
  }, extra?: _modelcontextprotocol_sdk_shared_protocol_js.RequestHandlerExtra<_modelcontextprotocol_sdk_types_js.ServerRequest, _modelcontextprotocol_sdk_types_js.ServerNotification>) => Promise<ToolResponse>;
5060
5076
  };
5061
5077
  unarchiveEntry: {
@@ -5066,6 +5082,7 @@ declare class ContentfulMcpTools {
5066
5082
  environmentId: zod.ZodString;
5067
5083
  } & {
5068
5084
  entryId: zod.ZodArray<zod.ZodString, "many">;
5085
+ dryRun: zod.ZodOptional<zod.ZodBoolean>;
5069
5086
  };
5070
5087
  annotations: {
5071
5088
  readOnlyHint: boolean;
@@ -5077,6 +5094,7 @@ declare class ContentfulMcpTools {
5077
5094
  spaceId: string;
5078
5095
  environmentId: string;
5079
5096
  entryId: string[];
5097
+ dryRun?: boolean | undefined;
5080
5098
  }, extra?: _modelcontextprotocol_sdk_shared_protocol_js.RequestHandlerExtra<_modelcontextprotocol_sdk_types_js.ServerRequest, _modelcontextprotocol_sdk_types_js.ServerNotification>) => Promise<ToolResponse>;
5081
5099
  };
5082
5100
  };
package/dist/index.js CHANGED
@@ -1180,10 +1180,47 @@ function createEntitiesCollection(entities) {
1180
1180
  };
1181
1181
  }
1182
1182
 
1183
+ // src/utils/bulkLimits.ts
1184
+ var DEFAULT_MAX_BULK_SIZE = 10;
1185
+ function resolveMaxBulkSize(configured) {
1186
+ if (configured === void 0 || !Number.isInteger(configured) || configured <= 0) {
1187
+ return DEFAULT_MAX_BULK_SIZE;
1188
+ }
1189
+ return configured;
1190
+ }
1191
+ function assertBulkSizeAllowed(count, configured) {
1192
+ const limit = resolveMaxBulkSize(configured);
1193
+ if (count > limit) {
1194
+ throw new Error(
1195
+ `Bulk operation rejected: ${count} IDs exceeds MAX_BULK_SIZE of ${limit}. Reduce batch size or increase the limit.`
1196
+ );
1197
+ }
1198
+ }
1199
+ var PLURAL_BY_ENTITY = {
1200
+ entry: "entries",
1201
+ asset: "assets"
1202
+ };
1203
+ function buildDryRunPreview(input) {
1204
+ const { operation, entityType, ids, spaceId, environmentId } = input;
1205
+ const noun = ids.length === 1 ? entityType : PLURAL_BY_ENTITY[entityType];
1206
+ return {
1207
+ dryRun: true,
1208
+ operation,
1209
+ entityType,
1210
+ count: ids.length,
1211
+ ids,
1212
+ target: { spaceId, environmentId },
1213
+ message: `Dry run: would ${operation} ${ids.length} ${noun} in ${spaceId}/${environmentId}. No changes were made. Re-run without dryRun to execute.`
1214
+ };
1215
+ }
1216
+
1183
1217
  // src/tools/assets/publishAsset.ts
1184
1218
  var PublishAssetToolParams = BaseToolSchema.extend({
1185
1219
  assetId: z19.union([z19.string(), z19.array(z19.string()).max(100)]).describe(
1186
- "The ID of the asset to publish (string) or an array of asset IDs (up to 100 assets)"
1220
+ "A single asset ID (string) or an array of asset IDs to publish (up to MAX_BULK_SIZE per call; default 10, max 100 \u2014 configurable via MAX_BULK_SIZE env var)."
1221
+ ),
1222
+ dryRun: z19.boolean().optional().describe(
1223
+ "When true, returns a preview of the operation without executing it. Still subject to MAX_BULK_SIZE \u2014 use this to confirm intent for within-limit calls."
1187
1224
  )
1188
1225
  });
1189
1226
  function publishAssetTool(config) {
@@ -1192,12 +1229,25 @@ function publishAssetTool(config) {
1192
1229
  args.environmentId,
1193
1230
  config.protectedEnvironments
1194
1231
  );
1232
+ const assetIds = Array.isArray(args.assetId) ? args.assetId : [args.assetId];
1233
+ assertBulkSizeAllowed(assetIds.length, config.maxBulkSize);
1234
+ if (args.dryRun) {
1235
+ return createSuccessResponse(
1236
+ "Dry run: no changes were made",
1237
+ buildDryRunPreview({
1238
+ operation: "publish",
1239
+ entityType: "asset",
1240
+ ids: assetIds,
1241
+ spaceId: args.spaceId,
1242
+ environmentId: args.environmentId
1243
+ })
1244
+ );
1245
+ }
1195
1246
  const baseParams = {
1196
1247
  spaceId: args.spaceId,
1197
1248
  environmentId: args.environmentId
1198
1249
  };
1199
1250
  const contentfulClient = createToolClient(config, args);
1200
- const assetIds = Array.isArray(args.assetId) ? args.assetId : [args.assetId];
1201
1251
  if (assetIds.length === 1) {
1202
1252
  try {
1203
1253
  const assetId = assetIds[0];
@@ -1247,7 +1297,10 @@ function publishAssetTool(config) {
1247
1297
  import { z as z20 } from "zod";
1248
1298
  var UnpublishAssetToolParams = BaseToolSchema.extend({
1249
1299
  assetId: z20.union([z20.string(), z20.array(z20.string()).max(100)]).describe(
1250
- "The ID of the asset to unpublish (string) or an array of asset IDs (up to 100 assets)"
1300
+ "A single asset ID (string) or an array of asset IDs to unpublish (up to MAX_BULK_SIZE per call; default 10, max 100 \u2014 configurable via MAX_BULK_SIZE env var)."
1301
+ ),
1302
+ dryRun: z20.boolean().optional().describe(
1303
+ "When true, returns a preview of the operation without executing it. Still subject to MAX_BULK_SIZE \u2014 use this to confirm intent for within-limit calls."
1251
1304
  )
1252
1305
  });
1253
1306
  function unpublishAssetTool(config) {
@@ -1256,12 +1309,25 @@ function unpublishAssetTool(config) {
1256
1309
  args.environmentId,
1257
1310
  config.protectedEnvironments
1258
1311
  );
1312
+ const assetIds = Array.isArray(args.assetId) ? args.assetId : [args.assetId];
1313
+ assertBulkSizeAllowed(assetIds.length, config.maxBulkSize);
1314
+ if (args.dryRun) {
1315
+ return createSuccessResponse(
1316
+ "Dry run: no changes were made",
1317
+ buildDryRunPreview({
1318
+ operation: "unpublish",
1319
+ entityType: "asset",
1320
+ ids: assetIds,
1321
+ spaceId: args.spaceId,
1322
+ environmentId: args.environmentId
1323
+ })
1324
+ );
1325
+ }
1259
1326
  const baseParams = {
1260
1327
  spaceId: args.spaceId,
1261
1328
  environmentId: args.environmentId
1262
1329
  };
1263
1330
  const contentfulClient = createToolClient(config, args);
1264
- const assetIds = Array.isArray(args.assetId) ? args.assetId : [args.assetId];
1265
1331
  if (assetIds.length === 1) {
1266
1332
  try {
1267
1333
  const assetId = assetIds[0];
@@ -1311,7 +1377,10 @@ function unpublishAssetTool(config) {
1311
1377
  import { z as z21 } from "zod";
1312
1378
  var ArchiveAssetToolParams = BaseToolSchema.extend({
1313
1379
  assetId: z21.union([z21.string(), z21.array(z21.string()).max(100)]).describe(
1314
- "The ID of the asset to archive (string) or an array of asset IDs (up to 100 assets)"
1380
+ "A single asset ID (string) or an array of asset IDs to archive (up to MAX_BULK_SIZE per call; default 10, max 100 \u2014 configurable via MAX_BULK_SIZE env var)."
1381
+ ),
1382
+ dryRun: z21.boolean().optional().describe(
1383
+ "When true, returns a preview of the operation without executing it. Still subject to MAX_BULK_SIZE \u2014 use this to confirm intent for within-limit calls."
1315
1384
  )
1316
1385
  });
1317
1386
  function archiveAssetTool(config) {
@@ -1320,12 +1389,25 @@ function archiveAssetTool(config) {
1320
1389
  args.environmentId,
1321
1390
  config.protectedEnvironments
1322
1391
  );
1392
+ const assetIds = Array.isArray(args.assetId) ? args.assetId : [args.assetId];
1393
+ assertBulkSizeAllowed(assetIds.length, config.maxBulkSize);
1394
+ if (args.dryRun) {
1395
+ return createSuccessResponse(
1396
+ "Dry run: no changes were made",
1397
+ buildDryRunPreview({
1398
+ operation: "archive",
1399
+ entityType: "asset",
1400
+ ids: assetIds,
1401
+ spaceId: args.spaceId,
1402
+ environmentId: args.environmentId
1403
+ })
1404
+ );
1405
+ }
1323
1406
  const baseParams = {
1324
1407
  spaceId: args.spaceId,
1325
1408
  environmentId: args.environmentId
1326
1409
  };
1327
1410
  const contentfulClient = createToolClient(config, args);
1328
- const assetIds = Array.isArray(args.assetId) ? args.assetId : [args.assetId];
1329
1411
  const successfullyArchived = [];
1330
1412
  for (const assetId of assetIds) {
1331
1413
  try {
@@ -1361,7 +1443,10 @@ function archiveAssetTool(config) {
1361
1443
  import { z as z22 } from "zod";
1362
1444
  var UnarchiveAssetToolParams = BaseToolSchema.extend({
1363
1445
  assetId: z22.union([z22.string(), z22.array(z22.string()).max(100)]).describe(
1364
- "The ID of the asset to unarchive (string) or an array of asset IDs (up to 100 assets)"
1446
+ "A single asset ID (string) or an array of asset IDs to unarchive (up to MAX_BULK_SIZE per call; default 10, max 100 \u2014 configurable via MAX_BULK_SIZE env var)."
1447
+ ),
1448
+ dryRun: z22.boolean().optional().describe(
1449
+ "When true, returns a preview of the operation without executing it. Still subject to MAX_BULK_SIZE \u2014 use this to confirm intent for within-limit calls."
1365
1450
  )
1366
1451
  });
1367
1452
  function unarchiveAssetTool(config) {
@@ -1370,12 +1455,25 @@ function unarchiveAssetTool(config) {
1370
1455
  args.environmentId,
1371
1456
  config.protectedEnvironments
1372
1457
  );
1458
+ const assetIds = Array.isArray(args.assetId) ? args.assetId : [args.assetId];
1459
+ assertBulkSizeAllowed(assetIds.length, config.maxBulkSize);
1460
+ if (args.dryRun) {
1461
+ return createSuccessResponse(
1462
+ "Dry run: no changes were made",
1463
+ buildDryRunPreview({
1464
+ operation: "unarchive",
1465
+ entityType: "asset",
1466
+ ids: assetIds,
1467
+ spaceId: args.spaceId,
1468
+ environmentId: args.environmentId
1469
+ })
1470
+ );
1471
+ }
1373
1472
  const baseParams = {
1374
1473
  spaceId: args.spaceId,
1375
1474
  environmentId: args.environmentId
1376
1475
  };
1377
1476
  const contentfulClient = createToolClient(config, args);
1378
- const assetIds = Array.isArray(args.assetId) ? args.assetId : [args.assetId];
1379
1477
  const successfullyUnarchived = [];
1380
1478
  for (const assetId of assetIds) {
1381
1479
  try {
@@ -3033,7 +3131,10 @@ function getEntryTool(config) {
3033
3131
  import { z as z45 } from "zod";
3034
3132
  var PublishEntryToolParams = BaseToolSchema.extend({
3035
3133
  entryId: z45.array(z45.string()).min(1).max(100).describe(
3036
- "Array of entry IDs to publish. Pass a single-element array for one entry, or up to 100 IDs for bulk operations."
3134
+ "Array of entry IDs to publish. Single-element array for one entry, or up to MAX_BULK_SIZE per call (default 10, max 100 \u2014 configurable via MAX_BULK_SIZE env var)."
3135
+ ),
3136
+ dryRun: z45.boolean().optional().describe(
3137
+ "When true, returns a preview of the operation without executing it. Still subject to MAX_BULK_SIZE \u2014 use this to confirm intent for within-limit calls."
3037
3138
  )
3038
3139
  });
3039
3140
  function publishEntryTool(config) {
@@ -3042,12 +3143,25 @@ function publishEntryTool(config) {
3042
3143
  args.environmentId,
3043
3144
  config.protectedEnvironments
3044
3145
  );
3146
+ const entryIds = args.entryId;
3147
+ assertBulkSizeAllowed(entryIds.length, config.maxBulkSize);
3148
+ if (args.dryRun) {
3149
+ return createSuccessResponse(
3150
+ "Dry run: no changes were made",
3151
+ buildDryRunPreview({
3152
+ operation: "publish",
3153
+ entityType: "entry",
3154
+ ids: entryIds,
3155
+ spaceId: args.spaceId,
3156
+ environmentId: args.environmentId
3157
+ })
3158
+ );
3159
+ }
3045
3160
  const baseParams = {
3046
3161
  spaceId: args.spaceId,
3047
3162
  environmentId: args.environmentId
3048
3163
  };
3049
3164
  const contentfulClient = createToolClient(config, args);
3050
- const entryIds = args.entryId;
3051
3165
  if (entryIds.length === 1) {
3052
3166
  const entryId = entryIds[0];
3053
3167
  const params = {
@@ -3090,7 +3204,10 @@ function publishEntryTool(config) {
3090
3204
  import { z as z46 } from "zod";
3091
3205
  var UnpublishEntryToolParams = BaseToolSchema.extend({
3092
3206
  entryId: z46.array(z46.string()).min(1).max(100).describe(
3093
- "Array of entry IDs to unpublish. Pass a single-element array for one entry, or up to 100 IDs for bulk operations."
3207
+ "Array of entry IDs to unpublish. Single-element array for one entry, or up to MAX_BULK_SIZE per call (default 10, max 100 \u2014 configurable via MAX_BULK_SIZE env var)."
3208
+ ),
3209
+ dryRun: z46.boolean().optional().describe(
3210
+ "When true, returns a preview of the operation without executing it. Still subject to MAX_BULK_SIZE \u2014 use this to confirm intent for within-limit calls."
3094
3211
  )
3095
3212
  });
3096
3213
  function unpublishEntryTool(config) {
@@ -3099,12 +3216,25 @@ function unpublishEntryTool(config) {
3099
3216
  args.environmentId,
3100
3217
  config.protectedEnvironments
3101
3218
  );
3219
+ const entryIds = args.entryId;
3220
+ assertBulkSizeAllowed(entryIds.length, config.maxBulkSize);
3221
+ if (args.dryRun) {
3222
+ return createSuccessResponse(
3223
+ "Dry run: no changes were made",
3224
+ buildDryRunPreview({
3225
+ operation: "unpublish",
3226
+ entityType: "entry",
3227
+ ids: entryIds,
3228
+ spaceId: args.spaceId,
3229
+ environmentId: args.environmentId
3230
+ })
3231
+ );
3232
+ }
3102
3233
  const baseParams = {
3103
3234
  spaceId: args.spaceId,
3104
3235
  environmentId: args.environmentId
3105
3236
  };
3106
3237
  const contentfulClient = createToolClient(config, args);
3107
- const entryIds = args.entryId;
3108
3238
  if (entryIds.length === 1) {
3109
3239
  const entryId = entryIds[0];
3110
3240
  const params = {
@@ -3147,7 +3277,10 @@ function unpublishEntryTool(config) {
3147
3277
  import { z as z47 } from "zod";
3148
3278
  var ArchiveEntryToolParams = BaseToolSchema.extend({
3149
3279
  entryId: z47.array(z47.string()).min(1).max(100).describe(
3150
- "Array of entry IDs to archive. Pass a single-element array for one entry, or up to 100 IDs for batch operations."
3280
+ "Array of entry IDs to archive. Single-element array for one entry, or up to MAX_BULK_SIZE per call (default 10, max 100 \u2014 configurable via MAX_BULK_SIZE env var)."
3281
+ ),
3282
+ dryRun: z47.boolean().optional().describe(
3283
+ "When true, returns a preview of the operation without executing it. Still subject to MAX_BULK_SIZE \u2014 use this to confirm intent for within-limit calls."
3151
3284
  )
3152
3285
  });
3153
3286
  function archiveEntryTool(config) {
@@ -3156,12 +3289,25 @@ function archiveEntryTool(config) {
3156
3289
  args.environmentId,
3157
3290
  config.protectedEnvironments
3158
3291
  );
3292
+ const entryIds = args.entryId;
3293
+ assertBulkSizeAllowed(entryIds.length, config.maxBulkSize);
3294
+ if (args.dryRun) {
3295
+ return createSuccessResponse(
3296
+ "Dry run: no changes were made",
3297
+ buildDryRunPreview({
3298
+ operation: "archive",
3299
+ entityType: "entry",
3300
+ ids: entryIds,
3301
+ spaceId: args.spaceId,
3302
+ environmentId: args.environmentId
3303
+ })
3304
+ );
3305
+ }
3159
3306
  const baseParams = {
3160
3307
  spaceId: args.spaceId,
3161
3308
  environmentId: args.environmentId
3162
3309
  };
3163
3310
  const contentfulClient = createToolClient(config, args);
3164
- const entryIds = args.entryId;
3165
3311
  const successfullyArchived = [];
3166
3312
  for (const entryId of entryIds) {
3167
3313
  try {
@@ -3197,7 +3343,10 @@ function archiveEntryTool(config) {
3197
3343
  import { z as z48 } from "zod";
3198
3344
  var UnarchiveEntryToolParams = BaseToolSchema.extend({
3199
3345
  entryId: z48.array(z48.string()).min(1).max(100).describe(
3200
- "Array of entry IDs to unarchive. Pass a single-element array for one entry, or up to 100 IDs for batch operations."
3346
+ "Array of entry IDs to unarchive. Single-element array for one entry, or up to MAX_BULK_SIZE per call (default 10, max 100 \u2014 configurable via MAX_BULK_SIZE env var)."
3347
+ ),
3348
+ dryRun: z48.boolean().optional().describe(
3349
+ "When true, returns a preview of the operation without executing it. Still subject to MAX_BULK_SIZE \u2014 use this to confirm intent for within-limit calls."
3201
3350
  )
3202
3351
  });
3203
3352
  function unarchiveEntryTool(config) {
@@ -3206,12 +3355,25 @@ function unarchiveEntryTool(config) {
3206
3355
  args.environmentId,
3207
3356
  config.protectedEnvironments
3208
3357
  );
3358
+ const entryIds = args.entryId;
3359
+ assertBulkSizeAllowed(entryIds.length, config.maxBulkSize);
3360
+ if (args.dryRun) {
3361
+ return createSuccessResponse(
3362
+ "Dry run: no changes were made",
3363
+ buildDryRunPreview({
3364
+ operation: "unarchive",
3365
+ entityType: "entry",
3366
+ ids: entryIds,
3367
+ spaceId: args.spaceId,
3368
+ environmentId: args.environmentId
3369
+ })
3370
+ );
3371
+ }
3209
3372
  const baseParams = {
3210
3373
  spaceId: args.spaceId,
3211
3374
  environmentId: args.environmentId
3212
3375
  };
3213
3376
  const contentfulClient = createToolClient(config, args);
3214
- const entryIds = args.entryId;
3215
3377
  const successfullyUnarchived = [];
3216
3378
  for (const entryId of entryIds) {
3217
3379
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/mcp-tools",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",