@contentful/mcp-tools 0.3.1 → 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 +68 -40
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -54,7 +54,7 @@ function withErrorHandling(handler, errorPrefix = "Error") {
54
54
  }
55
55
 
56
56
  // src/utils/tools.ts
57
- import ctfl from "contentful-management";
57
+ import { createClient } from "contentful-management";
58
58
  import { z } from "zod";
59
59
  var BaseToolSchema = z.object({
60
60
  spaceId: z.string().describe("The ID of the Contentful space"),
@@ -69,7 +69,7 @@ function createToolClient(config, params) {
69
69
  "X-Contentful-User-Agent-Tool": `contentful-mcp/${config.mcpVersion}`
70
70
  }
71
71
  };
72
- return ctfl.createClient(clientConfig, { type: "plain" });
72
+ return createClient(clientConfig);
73
73
  }
74
74
  function createClientConfig(config) {
75
75
  const clientConfig = {
@@ -750,7 +750,9 @@ var AssetMetadataSchema = z13.object({
750
750
  var FileSchema = z14.object({
751
751
  fileName: z14.string().describe("The name of the file"),
752
752
  contentType: z14.string().describe("The MIME type of the file"),
753
- upload: z14.string().optional().describe("The upload URL or file data")
753
+ upload: z14.string().optional().describe(
754
+ "The file source. Accepts either a publicly accessible https:// URL, or a base64-encoded data URI (e.g. data:image/png;base64,...). Use the data URI format to upload local files \u2014 the MCP client should base64-encode the file before passing it here."
755
+ )
754
756
  });
755
757
  var UploadAssetToolParams = BaseToolSchema.extend({
756
758
  title: z14.string().describe("The title of the asset"),
@@ -769,11 +771,37 @@ function uploadAssetTool(config) {
769
771
  };
770
772
  const contentfulClient = createToolClient(config, args);
771
773
  const locale = args.locale || "en-US";
774
+ const fileField = {
775
+ fileName: args.file.fileName,
776
+ contentType: args.file.contentType
777
+ };
778
+ if (args.file.upload?.startsWith("data:")) {
779
+ const commaIndex = args.file.upload.indexOf(",");
780
+ if (commaIndex === -1) {
781
+ throw new Error(
782
+ "Invalid data URI format. Expected data:<mime>;base64,<data>"
783
+ );
784
+ }
785
+ const base64 = args.file.upload.slice(commaIndex + 1);
786
+ const decoded = Buffer.from(base64, "base64");
787
+ const buffer = decoded.buffer.slice(
788
+ decoded.byteOffset,
789
+ decoded.byteOffset + decoded.byteLength
790
+ );
791
+ const upload = await contentfulClient.upload.create(params, {
792
+ file: buffer
793
+ });
794
+ fileField.uploadFrom = {
795
+ sys: { type: "Link", linkType: "Upload", id: upload.sys.id }
796
+ };
797
+ } else if (args.file.upload) {
798
+ fileField.upload = args.file.upload;
799
+ }
772
800
  const assetProps = {
773
801
  fields: {
774
802
  title: { [locale]: args.title },
775
803
  description: args.description ? { [locale]: args.description } : void 0,
776
- file: { [locale]: args.file }
804
+ file: { [locale]: fileField }
777
805
  },
778
806
  metadata: args.metadata
779
807
  };
@@ -1260,7 +1288,7 @@ function createAssetTools(config) {
1260
1288
  return {
1261
1289
  uploadAsset: {
1262
1290
  title: "upload_asset",
1263
- description: "Upload a new asset",
1291
+ description: "Upload a new asset. When uploading local binary files as base64, always re-encode from the source file immediately before the tool call \u2014 never re-use base64 from a previous tool output or from context.",
1264
1292
  inputParams: UploadAssetToolParams.shape,
1265
1293
  annotations: {
1266
1294
  readOnlyHint: false,
@@ -3300,7 +3328,7 @@ function createLocaleTools(config) {
3300
3328
 
3301
3329
  // src/tools/orgs/listOrgs.ts
3302
3330
  import { z as z54 } from "zod";
3303
- import ctfl2 from "contentful-management";
3331
+ import { createClient as createClient2 } from "contentful-management";
3304
3332
  var ListOrgsToolParams = z54.object({
3305
3333
  limit: z54.number().optional().describe("Maximum number of organizations to return (max 10)"),
3306
3334
  skip: z54.number().optional().describe("Skip this many organizations for pagination"),
@@ -3311,7 +3339,7 @@ function listOrgsTool(config) {
3311
3339
  async function tool2(args) {
3312
3340
  const clientConfig = createClientConfig(config);
3313
3341
  delete clientConfig.space;
3314
- const contentfulClient = ctfl2.createClient(clientConfig, { type: "plain" });
3342
+ const contentfulClient = createClient2(clientConfig);
3315
3343
  const organizations = await contentfulClient.organization.getAll({
3316
3344
  query: {
3317
3345
  limit: Math.min(args.limit || 10, 10),
@@ -3348,7 +3376,7 @@ function listOrgsTool(config) {
3348
3376
 
3349
3377
  // src/tools/orgs/getOrg.ts
3350
3378
  import { z as z55 } from "zod";
3351
- import ctfl3 from "contentful-management";
3379
+ import { createClient as createClient3 } from "contentful-management";
3352
3380
  var GetOrgToolParams = z55.object({
3353
3381
  organizationId: z55.string().describe("The ID of the organization to retrieve")
3354
3382
  });
@@ -3356,7 +3384,7 @@ function getOrgTool(config) {
3356
3384
  async function tool2(args) {
3357
3385
  const clientConfig = createClientConfig(config);
3358
3386
  delete clientConfig.space;
3359
- const contentfulClient = ctfl3.createClient(clientConfig, { type: "plain" });
3387
+ const contentfulClient = createClient3(clientConfig);
3360
3388
  const organization = await contentfulClient.organization.get({
3361
3389
  organizationId: args.organizationId
3362
3390
  });
@@ -3397,7 +3425,7 @@ function createOrgTools(config) {
3397
3425
 
3398
3426
  // src/tools/spaces/listSpaces.ts
3399
3427
  import { z as z56 } from "zod";
3400
- import ctfl4 from "contentful-management";
3428
+ import { createClient as createClient4 } from "contentful-management";
3401
3429
  var ListSpacesToolParams = z56.object({
3402
3430
  limit: z56.number().optional().describe("Maximum number of spaces to return (max 10)"),
3403
3431
  skip: z56.number().optional().describe("Skip this many spaces for pagination"),
@@ -3408,7 +3436,7 @@ function listSpacesTool(config) {
3408
3436
  async function tool2(args) {
3409
3437
  const clientConfig = createClientConfig(config);
3410
3438
  delete clientConfig.space;
3411
- const contentfulClient = ctfl4.createClient(clientConfig, { type: "plain" });
3439
+ const contentfulClient = createClient4(clientConfig);
3412
3440
  const spaces = await contentfulClient.space.getMany({
3413
3441
  query: {
3414
3442
  limit: Math.min(args.limit || 10, 10),
@@ -3445,7 +3473,7 @@ function listSpacesTool(config) {
3445
3473
 
3446
3474
  // src/tools/spaces/getSpace.ts
3447
3475
  import { z as z57 } from "zod";
3448
- import ctfl5 from "contentful-management";
3476
+ import { createClient as createClient5 } from "contentful-management";
3449
3477
  var GetSpaceToolParams = z57.object({
3450
3478
  spaceId: z57.string().describe("The ID of the space to retrieve")
3451
3479
  });
@@ -3453,7 +3481,7 @@ function getSpaceTool(config) {
3453
3481
  async function tool2(args) {
3454
3482
  const clientConfig = createClientConfig(config);
3455
3483
  delete clientConfig.space;
3456
- const contentfulClient = ctfl5.createClient(clientConfig, { type: "plain" });
3484
+ const contentfulClient = createClient5(clientConfig);
3457
3485
  const space = await contentfulClient.space.get({
3458
3486
  spaceId: args.spaceId
3459
3487
  });
@@ -3597,7 +3625,7 @@ function createTagTools(config) {
3597
3625
 
3598
3626
  // src/tools/taxonomies/concept-schemes/createConceptScheme.ts
3599
3627
  import { z as z61 } from "zod";
3600
- import ctfl6 from "contentful-management";
3628
+ import { createClient as createClient6 } from "contentful-management";
3601
3629
 
3602
3630
  // src/types/conceptPayloadTypes.ts
3603
3631
  import { z as z60 } from "zod";
@@ -3629,7 +3657,7 @@ function createConceptSchemeTool(config) {
3629
3657
  async function tool2(args) {
3630
3658
  const clientConfig = createClientConfig(config);
3631
3659
  delete clientConfig.space;
3632
- const contentfulClient = ctfl6.createClient(clientConfig, { type: "plain" });
3660
+ const contentfulClient = createClient6(clientConfig);
3633
3661
  const conceptSchemePayload = {
3634
3662
  prefLabel: args.prefLabel,
3635
3663
  ...Object.fromEntries(
@@ -3664,7 +3692,7 @@ function createConceptSchemeTool(config) {
3664
3692
 
3665
3693
  // src/tools/taxonomies/concept-schemes/getConceptScheme.ts
3666
3694
  import { z as z62 } from "zod";
3667
- import ctfl7 from "contentful-management";
3695
+ import { createClient as createClient7 } from "contentful-management";
3668
3696
  var GetConceptSchemeToolParams = z62.object({
3669
3697
  organizationId: z62.string().describe("The ID of the Contentful organization"),
3670
3698
  conceptSchemeId: z62.string().describe("The ID of the concept scheme to retrieve")
@@ -3673,7 +3701,7 @@ function getConceptSchemeTool(config) {
3673
3701
  async function tool2(args) {
3674
3702
  const clientConfig = createClientConfig(config);
3675
3703
  delete clientConfig.space;
3676
- const contentfulClient = ctfl7.createClient(clientConfig, { type: "plain" });
3704
+ const contentfulClient = createClient7(clientConfig);
3677
3705
  const params = {
3678
3706
  organizationId: args.organizationId,
3679
3707
  conceptSchemeId: args.conceptSchemeId
@@ -3688,7 +3716,7 @@ function getConceptSchemeTool(config) {
3688
3716
 
3689
3717
  // src/tools/taxonomies/concept-schemes/listConceptSchemes.ts
3690
3718
  import { z as z63 } from "zod";
3691
- import ctfl8 from "contentful-management";
3719
+ import { createClient as createClient8 } from "contentful-management";
3692
3720
  import { cloneDeep } from "lodash-es";
3693
3721
  var ListConceptSchemesToolParams = z63.object({
3694
3722
  organizationId: z63.string(),
@@ -3717,7 +3745,7 @@ function listConceptSchemesTool(config) {
3717
3745
  async function tool2(args) {
3718
3746
  const clientConfig = createClientConfig(config);
3719
3747
  delete clientConfig.space;
3720
- const contentfulClient = ctfl8.createClient(clientConfig, { type: "plain" });
3748
+ const contentfulClient = createClient8(clientConfig);
3721
3749
  const query = {};
3722
3750
  if (args.query) {
3723
3751
  if ("pageUrl" in args.query && args.query.pageUrl) {
@@ -3776,7 +3804,7 @@ function listConceptSchemesTool(config) {
3776
3804
 
3777
3805
  // src/tools/taxonomies/concept-schemes/updateConceptScheme.ts
3778
3806
  import { z as z64 } from "zod";
3779
- import ctfl9 from "contentful-management";
3807
+ import { createClient as createClient9 } from "contentful-management";
3780
3808
  var UpdateConceptSchemeToolParams = z64.object({
3781
3809
  organizationId: z64.string().describe("The ID of the Contentful organization"),
3782
3810
  conceptSchemeId: z64.string().describe("The ID of the concept scheme to update"),
@@ -3798,7 +3826,7 @@ function updateConceptSchemeTool(config) {
3798
3826
  async function tool2(args) {
3799
3827
  const clientConfig = createClientConfig(config);
3800
3828
  delete clientConfig.space;
3801
- const contentfulClient = ctfl9.createClient(clientConfig, { type: "plain" });
3829
+ const contentfulClient = createClient9(clientConfig);
3802
3830
  const params = {
3803
3831
  organizationId: args.organizationId,
3804
3832
  conceptSchemeId: args.conceptSchemeId
@@ -3825,11 +3853,11 @@ function updateConceptSchemeTool(config) {
3825
3853
  }
3826
3854
  });
3827
3855
  if (args.uri !== void 0) {
3828
- patchOperations.push({
3829
- op: args.uri === null ? "remove" : "replace",
3830
- path: "/uri",
3831
- ...args.uri !== null && { value: args.uri }
3832
- });
3856
+ if (args.uri === null) {
3857
+ patchOperations.push({ op: "remove", path: "/uri" });
3858
+ } else {
3859
+ patchOperations.push({ op: "replace", path: "/uri", value: args.uri });
3860
+ }
3833
3861
  }
3834
3862
  if (args.addConcept) {
3835
3863
  const conceptLink = {
@@ -3850,7 +3878,7 @@ function updateConceptSchemeTool(config) {
3850
3878
  value: conceptLink
3851
3879
  });
3852
3880
  }
3853
- const updatedConceptScheme = await contentfulClient.conceptScheme.update(
3881
+ const updatedConceptScheme = await contentfulClient.conceptScheme.patch(
3854
3882
  {
3855
3883
  ...params,
3856
3884
  version: args.version
@@ -3866,7 +3894,7 @@ function updateConceptSchemeTool(config) {
3866
3894
 
3867
3895
  // src/tools/taxonomies/concept-schemes/deleteConceptScheme.ts
3868
3896
  import { z as z65 } from "zod";
3869
- import ctfl10 from "contentful-management";
3897
+ import { createClient as createClient10 } from "contentful-management";
3870
3898
  var DeleteConceptSchemeToolParams = z65.object({
3871
3899
  organizationId: z65.string().describe("The ID of the Contentful organization"),
3872
3900
  conceptSchemeId: z65.string().describe("The ID of the concept scheme to delete"),
@@ -3876,7 +3904,7 @@ function deleteConceptSchemeTool(config) {
3876
3904
  async function tool2(args) {
3877
3905
  const clientConfig = createClientConfig(config);
3878
3906
  delete clientConfig.space;
3879
- const contentfulClient = ctfl10.createClient(clientConfig, { type: "plain" });
3907
+ const contentfulClient = createClient10(clientConfig);
3880
3908
  await contentfulClient.conceptScheme.delete({
3881
3909
  organizationId: args.organizationId,
3882
3910
  conceptSchemeId: args.conceptSchemeId,
@@ -3958,7 +3986,7 @@ function createConceptSchemeTools(config) {
3958
3986
 
3959
3987
  // src/tools/taxonomies/concepts/createConcept.ts
3960
3988
  import { z as z66 } from "zod";
3961
- import ctfl11 from "contentful-management";
3989
+ import { createClient as createClient11 } from "contentful-management";
3962
3990
  var CreateConceptToolParams = z66.object({
3963
3991
  organizationId: z66.string().describe("The ID of the Contentful organization"),
3964
3992
  conceptId: z66.string().optional().describe(
@@ -3982,7 +4010,7 @@ function createConceptTool(config) {
3982
4010
  async function tool2(args) {
3983
4011
  const clientConfig = createClientConfig(config);
3984
4012
  delete clientConfig.space;
3985
- const contentfulClient = ctfl11.createClient(clientConfig, { type: "plain" });
4013
+ const contentfulClient = createClient11(clientConfig);
3986
4014
  const conceptPayload = {
3987
4015
  prefLabel: args.prefLabel,
3988
4016
  ...args.uri !== void 0 && { uri: args.uri },
@@ -4012,7 +4040,7 @@ function createConceptTool(config) {
4012
4040
 
4013
4041
  // src/tools/taxonomies/concepts/deleteConcept.ts
4014
4042
  import { z as z67 } from "zod";
4015
- import ctfl12 from "contentful-management";
4043
+ import { createClient as createClient12 } from "contentful-management";
4016
4044
  var DeleteConceptToolParams = z67.object({
4017
4045
  organizationId: z67.string().describe("The ID of the Contentful organization"),
4018
4046
  conceptId: z67.string().describe("The ID of the concept to delete"),
@@ -4022,7 +4050,7 @@ function deleteConceptTool(config) {
4022
4050
  async function tool2(args) {
4023
4051
  const clientConfig = createClientConfig(config);
4024
4052
  delete clientConfig.space;
4025
- const contentfulClient = ctfl12.createClient(clientConfig, { type: "plain" });
4053
+ const contentfulClient = createClient12(clientConfig);
4026
4054
  await contentfulClient.concept.delete({
4027
4055
  organizationId: args.organizationId,
4028
4056
  conceptId: args.conceptId,
@@ -4037,7 +4065,7 @@ function deleteConceptTool(config) {
4037
4065
 
4038
4066
  // src/tools/taxonomies/concepts/updateConcept.ts
4039
4067
  import { z as z68 } from "zod";
4040
- import ctfl13 from "contentful-management";
4068
+ import { createClient as createClient13 } from "contentful-management";
4041
4069
  var UpdateConceptToolParams = z68.object({
4042
4070
  organizationId: z68.string().describe("The ID of the Contentful organization"),
4043
4071
  conceptId: z68.string().describe("The ID of the concept to update"),
@@ -4060,7 +4088,7 @@ function updateConceptTool(config) {
4060
4088
  async function tool2(args) {
4061
4089
  const clientConfig = createClientConfig(config);
4062
4090
  delete clientConfig.space;
4063
- const contentfulClient = ctfl13.createClient(clientConfig, { type: "plain" });
4091
+ const contentfulClient = createClient13(clientConfig);
4064
4092
  const existingConcept = await contentfulClient.concept.get({
4065
4093
  organizationId: args.organizationId,
4066
4094
  conceptId: args.conceptId
@@ -4080,7 +4108,7 @@ function updateConceptTool(config) {
4080
4108
  broader: args.broader ?? existingConcept.broader,
4081
4109
  related: args.related ?? existingConcept.related
4082
4110
  };
4083
- const updatedConcept = await contentfulClient.concept.updatePut(
4111
+ const updatedConcept = await contentfulClient.concept.update(
4084
4112
  {
4085
4113
  organizationId: args.organizationId,
4086
4114
  conceptId: args.conceptId,
@@ -4097,7 +4125,7 @@ function updateConceptTool(config) {
4097
4125
 
4098
4126
  // src/tools/taxonomies/concepts/getConcept.ts
4099
4127
  import { z as z69 } from "zod";
4100
- import ctfl14 from "contentful-management";
4128
+ import { createClient as createClient14 } from "contentful-management";
4101
4129
  var GetConceptToolParams = z69.object({
4102
4130
  organizationId: z69.string().describe("The ID of the Contentful organization"),
4103
4131
  conceptId: z69.string().describe("The ID of the concept to retrieve")
@@ -4106,7 +4134,7 @@ function getConceptTool(config) {
4106
4134
  async function tool2(args) {
4107
4135
  const clientConfig = createClientConfig(config);
4108
4136
  delete clientConfig.space;
4109
- const contentfulClient = ctfl14.createClient(clientConfig, { type: "plain" });
4137
+ const contentfulClient = createClient14(clientConfig);
4110
4138
  const concept = await contentfulClient.concept.get({
4111
4139
  organizationId: args.organizationId,
4112
4140
  conceptId: args.conceptId
@@ -4118,7 +4146,7 @@ function getConceptTool(config) {
4118
4146
 
4119
4147
  // src/tools/taxonomies/concepts/listConcepts.ts
4120
4148
  import { z as z70 } from "zod";
4121
- import ctfl15 from "contentful-management";
4149
+ import { createClient as createClient15 } from "contentful-management";
4122
4150
  var ListConceptsToolParams = z70.object({
4123
4151
  organizationId: z70.string().describe("The ID of the Contentful organization"),
4124
4152
  conceptId: z70.string().optional().describe("The ID of the concept (required for descendants/ancestors)"),
@@ -4134,7 +4162,7 @@ function listConceptsTool(config) {
4134
4162
  async function tool2(args) {
4135
4163
  const clientConfig = createClientConfig(config);
4136
4164
  delete clientConfig.space;
4137
- const contentfulClient = ctfl15.createClient(clientConfig, { type: "plain" });
4165
+ const contentfulClient = createClient15(clientConfig);
4138
4166
  if ((args.getDescendants || args.getAncestors) && !args.conceptId) {
4139
4167
  throw new Error(
4140
4168
  "conceptId is required when getting descendants or ancestors"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/mcp-tools",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -45,7 +45,7 @@
45
45
  "@modelcontextprotocol/sdk": "^1.26.0",
46
46
  "contentful-export": "^7.21.78",
47
47
  "contentful-import": "^9.4.129",
48
- "contentful-management": "^11.54.3",
48
+ "contentful-management": "^12.2.0",
49
49
  "fast-xml-parser": "^5.3.8",
50
50
  "lodash-es": "^4.17.23",
51
51
  "outdent": "^0.8.0",