@contentful/mcp-server 1.1.0 → 1.2.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.
@@ -0,0 +1,159 @@
1
+ import { vi } from 'vitest';
2
+ import { createToolClient } from '../../utils/tools.js';
3
+ /**
4
+ * Shared mock objects for asset tests
5
+ * Provides standardized mock client and asset objects used across all asset tests
6
+ */
7
+ // Create mock functions for the client
8
+ export const mockAssetGet = vi.fn();
9
+ export const mockAssetCreate = vi.fn();
10
+ export const mockAssetUpdate = vi.fn();
11
+ export const mockAssetDelete = vi.fn();
12
+ export const mockAssetPublish = vi.fn();
13
+ export const mockAssetUnpublish = vi.fn();
14
+ export const mockAssetGetMany = vi.fn();
15
+ export const mockAssetProcessForAllLocales = vi.fn();
16
+ // Mock bulk operations
17
+ export const mockBulkActionPublish = vi.fn();
18
+ export const mockBulkActionUnpublish = vi.fn();
19
+ export const mockBulkActionGet = vi.fn();
20
+ /**
21
+ * Standard mock Contentful client with all asset operations
22
+ */
23
+ export const mockClient = {
24
+ asset: {
25
+ get: mockAssetGet,
26
+ create: mockAssetCreate,
27
+ update: mockAssetUpdate,
28
+ delete: mockAssetDelete,
29
+ publish: mockAssetPublish,
30
+ unpublish: mockAssetUnpublish,
31
+ getMany: mockAssetGetMany,
32
+ processForAllLocales: mockAssetProcessForAllLocales,
33
+ },
34
+ bulkAction: {
35
+ publish: mockBulkActionPublish,
36
+ unpublish: mockBulkActionUnpublish,
37
+ get: mockBulkActionGet,
38
+ },
39
+ };
40
+ /**
41
+ * Sets up the mock client for tests
42
+ * Call this in beforeEach to ensure the mock is properly configured
43
+ */
44
+ export function setupMockClient() {
45
+ vi.mocked(createToolClient).mockReturnValue(mockClient);
46
+ }
47
+ /**
48
+ * Standard mock asset object used across tests
49
+ */
50
+ export const mockAsset = {
51
+ sys: {
52
+ id: 'test-asset-id',
53
+ type: 'Asset',
54
+ version: 1,
55
+ space: {
56
+ sys: {
57
+ type: 'Link',
58
+ linkType: 'Space',
59
+ id: 'test-space-id',
60
+ },
61
+ },
62
+ environment: {
63
+ sys: {
64
+ type: 'Link',
65
+ linkType: 'Environment',
66
+ id: 'test-environment',
67
+ },
68
+ },
69
+ createdAt: '2023-01-01T00:00:00Z',
70
+ updatedAt: '2023-01-01T00:00:00Z',
71
+ publishedVersion: 1,
72
+ },
73
+ fields: {
74
+ title: {
75
+ 'en-US': 'Test Asset',
76
+ },
77
+ description: {
78
+ 'en-US': 'A test asset for unit tests',
79
+ },
80
+ file: {
81
+ 'en-US': {
82
+ fileName: 'test-image.jpg',
83
+ contentType: 'image/jpeg',
84
+ url: 'https://images.ctfassets.net/test/test-image.jpg',
85
+ details: {
86
+ size: 12345,
87
+ image: {
88
+ width: 800,
89
+ height: 600,
90
+ },
91
+ },
92
+ },
93
+ },
94
+ },
95
+ };
96
+ /**
97
+ * Standard test arguments for asset operations
98
+ */
99
+ export const mockArgs = {
100
+ spaceId: 'test-space-id',
101
+ environmentId: 'test-environment',
102
+ assetId: 'test-asset-id',
103
+ };
104
+ /**
105
+ * Mock file object for upload tests
106
+ */
107
+ export const mockFile = {
108
+ fileName: 'test-image.jpg',
109
+ contentType: 'image/jpeg',
110
+ upload: 'https://upload.example.com/test-upload-url',
111
+ };
112
+ /**
113
+ * Mock assets list response
114
+ */
115
+ export const mockAssetsResponse = {
116
+ total: 2,
117
+ skip: 0,
118
+ limit: 3,
119
+ items: [
120
+ mockAsset,
121
+ {
122
+ ...mockAsset,
123
+ sys: { ...mockAsset.sys, id: 'another-asset-id' },
124
+ fields: {
125
+ ...mockAsset.fields,
126
+ title: { 'en-US': 'Another Test Asset' },
127
+ },
128
+ },
129
+ ],
130
+ };
131
+ /**
132
+ * Mock bulk action response
133
+ */
134
+ export const mockBulkAction = {
135
+ sys: {
136
+ id: 'bulk-action-id',
137
+ type: 'BulkAction',
138
+ status: 'succeeded',
139
+ createdAt: '2023-01-01T00:00:00Z',
140
+ updatedAt: '2023-01-01T00:00:00Z',
141
+ },
142
+ action: 'publish',
143
+ payload: {},
144
+ };
145
+ /**
146
+ * Mock processed asset for upload
147
+ */
148
+ export const mockProcessedAsset = {
149
+ ...mockAsset,
150
+ fields: {
151
+ ...mockAsset.fields,
152
+ file: {
153
+ 'en-US': {
154
+ ...mockAsset.fields.file['en-US'],
155
+ url: 'https://images.ctfassets.net/processed/test-image.jpg',
156
+ },
157
+ },
158
+ },
159
+ };
@@ -9,6 +9,10 @@ export const CreateContentTypeToolParams = BaseToolSchema.extend({
9
9
  .string()
10
10
  .optional()
11
11
  .describe('Description of the content type'),
12
+ contentTypeId: z
13
+ .string()
14
+ .optional()
15
+ .describe('Optional ID for the content type. If provided, will use createWithId method'),
12
16
  fields: z
13
17
  .array(FieldSchema)
14
18
  .describe('Array of field definitions for the content type'),
@@ -19,13 +23,16 @@ async function tool(args) {
19
23
  environmentId: args.environmentId,
20
24
  };
21
25
  const contentfulClient = createToolClient(args);
22
- // Create the content type
23
- const contentType = await contentfulClient.contentType.create(params, {
26
+ const contentTypeData = {
24
27
  name: args.name,
25
28
  displayField: args.displayField,
26
29
  description: args.description,
27
30
  fields: args.fields,
28
- });
31
+ };
32
+ // Create the content type with or without ID
33
+ const contentType = args.contentTypeId
34
+ ? await contentfulClient.contentType.createWithId({ ...params, contentTypeId: args.contentTypeId }, contentTypeData)
35
+ : await contentfulClient.contentType.create(params, contentTypeData);
29
36
  return createSuccessResponse('Content type created successfully', {
30
37
  contentType,
31
38
  });
@@ -1,38 +1,42 @@
1
1
  import { vi } from 'vitest';
2
- import { createToolClient } from '../../utils/tools.js';
3
2
  /**
4
3
  * Shared mock objects for content type tests
5
4
  * Provides standardized mock client and content type objects used across all content type tests
6
5
  */
7
- // Create mock functions for the client
8
- export const mockContentTypeGet = vi.fn();
9
- export const mockContentTypeCreate = vi.fn();
10
- export const mockContentTypeUpdate = vi.fn();
11
- export const mockContentTypeDelete = vi.fn();
12
- export const mockContentTypePublish = vi.fn();
13
- export const mockContentTypeUnpublish = vi.fn();
14
- export const mockContentTypeGetMany = vi.fn();
15
- /**
16
- * Standard mock Contentful client with all content type operations
17
- */
18
- export const mockClient = {
19
- contentType: {
20
- get: mockContentTypeGet,
21
- create: mockContentTypeCreate,
22
- update: mockContentTypeUpdate,
23
- delete: mockContentTypeDelete,
24
- publish: mockContentTypePublish,
25
- unpublish: mockContentTypeUnpublish,
26
- getMany: mockContentTypeGetMany,
27
- },
28
- };
29
- /**
30
- * Sets up the mock client for tests
31
- * Call this in beforeEach to ensure the mock is properly configured
32
- */
33
- export function setupMockClient() {
34
- vi.mocked(createToolClient).mockReturnValue(mockClient);
35
- }
6
+ const { mockContentTypeGet, mockContentTypeCreate, mockContentTypeCreateWithId, mockContentTypeUpdate, mockContentTypeDelete, mockContentTypePublish, mockContentTypeUnpublish, mockContentTypeGetMany, mockCreateToolClient, } = vi.hoisted(() => {
7
+ return {
8
+ mockContentTypeGet: vi.fn(),
9
+ mockContentTypeCreate: vi.fn(),
10
+ mockContentTypeCreateWithId: vi.fn(),
11
+ mockContentTypeUpdate: vi.fn(),
12
+ mockContentTypeDelete: vi.fn(),
13
+ mockContentTypePublish: vi.fn(),
14
+ mockContentTypeUnpublish: vi.fn(),
15
+ mockContentTypeGetMany: vi.fn(),
16
+ mockCreateToolClient: vi.fn(() => {
17
+ return {
18
+ contentType: {
19
+ get: mockContentTypeGet,
20
+ create: mockContentTypeCreate,
21
+ createWithId: mockContentTypeCreateWithId,
22
+ update: mockContentTypeUpdate,
23
+ delete: mockContentTypeDelete,
24
+ publish: mockContentTypePublish,
25
+ unpublish: mockContentTypeUnpublish,
26
+ getMany: mockContentTypeGetMany,
27
+ },
28
+ };
29
+ }),
30
+ };
31
+ });
32
+ vi.mock('../../utils/tools.js', async (importOriginal) => {
33
+ const org = await importOriginal();
34
+ return {
35
+ ...org,
36
+ createToolClient: mockCreateToolClient,
37
+ };
38
+ });
39
+ export { mockContentTypeGet, mockContentTypeCreate, mockContentTypeCreateWithId, mockContentTypeUpdate, mockContentTypeDelete, mockContentTypePublish, mockContentTypeUnpublish, mockContentTypeGetMany, mockCreateToolClient, };
36
40
  /**
37
41
  * Standard mock content type object used across tests
38
42
  */
@@ -0,0 +1,54 @@
1
+ import { vi } from 'vitest';
2
+ const { mockLocaleCreate, mockLocaleGet, mockLocaleDelete, mockLocaleGetMany, mockLocaleUpdate, mockCreateToolClient, } = vi.hoisted(() => {
3
+ return {
4
+ mockLocaleCreate: vi.fn(),
5
+ mockLocaleGet: vi.fn(),
6
+ mockLocaleDelete: vi.fn(),
7
+ mockLocaleGetMany: vi.fn(),
8
+ mockLocaleUpdate: vi.fn(),
9
+ mockCreateToolClient: vi.fn(() => {
10
+ return {
11
+ locale: {
12
+ create: mockLocaleCreate,
13
+ get: mockLocaleGet,
14
+ delete: mockLocaleDelete,
15
+ getMany: mockLocaleGetMany,
16
+ update: mockLocaleUpdate,
17
+ },
18
+ };
19
+ }),
20
+ };
21
+ });
22
+ vi.mock('../../utils/tools.js', async (importOriginal) => {
23
+ const org = await importOriginal();
24
+ return {
25
+ ...org,
26
+ createToolClient: mockCreateToolClient,
27
+ };
28
+ });
29
+ export { mockLocaleCreate, mockLocaleGet, mockLocaleDelete, mockLocaleGetMany, mockLocaleUpdate, mockCreateToolClient, };
30
+ export const testLocale = {
31
+ name: 'Test Locale',
32
+ code: 'en-US',
33
+ fallbackCode: null,
34
+ contentDeliveryApi: true,
35
+ contentManagementApi: true,
36
+ default: true,
37
+ optional: false,
38
+ sys: {
39
+ id: 'test-locale-id',
40
+ type: 'Locale',
41
+ space: { sys: { type: 'Link', linkType: 'Space', id: 'test-space-id' } },
42
+ environment: {
43
+ sys: { type: 'Link', linkType: 'Environment', id: 'test-environment-id' },
44
+ },
45
+ createdAt: '2025-08-25T10:00:00Z',
46
+ updatedAt: '2025-08-25T10:00:00Z',
47
+ version: 1,
48
+ },
49
+ };
50
+ export const mockArgs = {
51
+ spaceId: 'test-space-id',
52
+ environmentId: 'test-environment-id',
53
+ cmaToken: 'test-cma-token',
54
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/mcp-server",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/contentful/contentful-mcp-server"