@mybe/contensa-mcp 1.0.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/README.md +765 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +35 -0
- package/dist/cli.js.map +1 -0
- package/dist/client.d.ts +150 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +480 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +9 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +173 -0
- package/dist/server.js.map +1 -0
- package/dist/tools.d.ts +409 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +626 -0
- package/dist/tools.js.map +1 -0
- package/dist/types.d.ts +136 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +39 -0
package/README.md
ADDED
|
@@ -0,0 +1,765 @@
|
|
|
1
|
+
# Contensa MCP Server
|
|
2
|
+
|
|
3
|
+
MCP (Model Context Protocol) server for Contensa CMS. This enables AI assistants like Claude (via Cursor, Claude Desktop, etc.) to interact directly with your CMS.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Content Type Management**: Create, read, update, delete content types
|
|
8
|
+
- **Field Management**: Add, modify, remove fields from content types
|
|
9
|
+
- **Content Entry Management**: Create, read, update, delete, publish content entries
|
|
10
|
+
- **Locale Management**: Create and manage multilingual content variants with AI translation
|
|
11
|
+
- **Environment Management**: Create, manage, and merge/sync environments
|
|
12
|
+
- **Media Management**: List and manage media assets
|
|
13
|
+
- **AI-Powered Features**: Generate schemas and field suggestions using AI
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @mybe/contensa-mcp
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Or if using the monorepo:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
cd packages/mcp-server
|
|
25
|
+
npm install
|
|
26
|
+
npm run build
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Configuration
|
|
30
|
+
|
|
31
|
+
### For Cursor
|
|
32
|
+
|
|
33
|
+
Add to your Cursor MCP settings (`~/.cursor/mcp.json` or workspace `.cursor/mcp.json`):
|
|
34
|
+
|
|
35
|
+
```json
|
|
36
|
+
{
|
|
37
|
+
"mcpServers": {
|
|
38
|
+
"contensa": {
|
|
39
|
+
"command": "npx",
|
|
40
|
+
"args": ["@mybe/contensa-mcp"],
|
|
41
|
+
"env": {
|
|
42
|
+
"CONTENSA_API_KEY": "your-api-key-here",
|
|
43
|
+
"CONTENSA_PROJECT_ID": "your-default-project-id"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Or if running from the monorepo:
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"mcpServers": {
|
|
55
|
+
"contensa": {
|
|
56
|
+
"command": "node",
|
|
57
|
+
"args": ["/path/to/mybe-cms/packages/mcp-server/dist/cli.js"],
|
|
58
|
+
"env": {
|
|
59
|
+
"CONTENSA_API_KEY": "your-api-key-here",
|
|
60
|
+
"CONTENSA_PROJECT_ID": "your-default-project-id"
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### For Claude Desktop
|
|
68
|
+
|
|
69
|
+
Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
{
|
|
73
|
+
"mcpServers": {
|
|
74
|
+
"contensa": {
|
|
75
|
+
"command": "npx",
|
|
76
|
+
"args": ["@mybe/contensa-mcp"],
|
|
77
|
+
"env": {
|
|
78
|
+
"CONTENSA_API_KEY": "your-api-key-here",
|
|
79
|
+
"CONTENSA_PROJECT_ID": "your-default-project-id"
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Environment Variables
|
|
87
|
+
|
|
88
|
+
| Variable | Required | Description |
|
|
89
|
+
|----------|----------|-------------|
|
|
90
|
+
| `CONTENSA_API_KEY` | Yes | Your Contensa API key |
|
|
91
|
+
| `CONTENSA_BASE_URL` | No | Custom API base URL (defaults to Contensa production API or localhost in dev) |
|
|
92
|
+
| `CONTENSA_PROJECT_ID` | No | Default project ID |
|
|
93
|
+
|
|
94
|
+
### API Base URL
|
|
95
|
+
|
|
96
|
+
The MCP server automatically determines the API base URL:
|
|
97
|
+
|
|
98
|
+
- **Development** (`NODE_ENV=development`): Uses `http://localhost:3001/api/v1`
|
|
99
|
+
- **Production**: Uses Contensa's production API endpoint
|
|
100
|
+
|
|
101
|
+
You can override the default by setting `CONTENSA_BASE_URL` for custom API endpoints or different environments:
|
|
102
|
+
|
|
103
|
+
```json
|
|
104
|
+
{
|
|
105
|
+
"mcpServers": {
|
|
106
|
+
"contensa": {
|
|
107
|
+
"command": "node",
|
|
108
|
+
"args": ["./packages/mcp-server/dist/cli.js"],
|
|
109
|
+
"env": {
|
|
110
|
+
"CONTENSA_API_KEY": "your-api-key",
|
|
111
|
+
"CONTENSA_BASE_URL": "https://your-custom-api.com/api/v1"
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Available Tools
|
|
119
|
+
|
|
120
|
+
### Project Management
|
|
121
|
+
|
|
122
|
+
| Tool | Description |
|
|
123
|
+
|------|-------------|
|
|
124
|
+
| `contensa_list_projects` | List all projects |
|
|
125
|
+
| `contensa_get_project` | Get project details |
|
|
126
|
+
| `contensa_set_active_project` | Set the active project |
|
|
127
|
+
|
|
128
|
+
### Content Type Management
|
|
129
|
+
|
|
130
|
+
| Tool | Description |
|
|
131
|
+
|------|-------------|
|
|
132
|
+
| `contensa_list_content_types` | List all content types in a project |
|
|
133
|
+
| `contensa_get_content_type` | Get content type details with fields |
|
|
134
|
+
| `contensa_create_content_type` | Create a new content type |
|
|
135
|
+
| `contensa_update_content_type` | Update a content type |
|
|
136
|
+
| `contensa_delete_content_type` | Delete a content type |
|
|
137
|
+
|
|
138
|
+
### Field Management
|
|
139
|
+
|
|
140
|
+
| Tool | Description |
|
|
141
|
+
|------|-------------|
|
|
142
|
+
| `contensa_list_fields` | List fields of a content type |
|
|
143
|
+
| `contensa_create_field` | Add a field to a content type |
|
|
144
|
+
| `contensa_update_field` | Update a field |
|
|
145
|
+
| `contensa_delete_field` | Delete a field |
|
|
146
|
+
|
|
147
|
+
### Content Entry Management
|
|
148
|
+
|
|
149
|
+
| Tool | Description |
|
|
150
|
+
|------|-------------|
|
|
151
|
+
| `contensa_list_content_entries` | List entries of a content type |
|
|
152
|
+
| `contensa_get_content_entry` | Get a content entry |
|
|
153
|
+
| `contensa_create_content_entry` | Create a new entry |
|
|
154
|
+
| `contensa_update_content_entry` | Update an entry |
|
|
155
|
+
| `contensa_delete_content_entry` | Delete an entry |
|
|
156
|
+
| `contensa_publish_content_entry` | Publish an entry |
|
|
157
|
+
| `contensa_unpublish_content_entry` | Unpublish an entry |
|
|
158
|
+
|
|
159
|
+
### Locale Management
|
|
160
|
+
|
|
161
|
+
| Tool | Description |
|
|
162
|
+
|------|-------------|
|
|
163
|
+
| `contensa_get_supported_locales` | Get all supported locales in the system |
|
|
164
|
+
| `contensa_list_locale_variants` | List all locale variants of an entry |
|
|
165
|
+
| `contensa_create_locale_variant` | Create a new locale variant with optional AI translation |
|
|
166
|
+
|
|
167
|
+
### Media Management
|
|
168
|
+
|
|
169
|
+
| Tool | Description |
|
|
170
|
+
|------|-------------|
|
|
171
|
+
| `contensa_list_media_assets` | List media assets |
|
|
172
|
+
| `contensa_get_media_asset` | Get media asset details |
|
|
173
|
+
| `contensa_delete_media_asset` | Delete a media asset |
|
|
174
|
+
|
|
175
|
+
### Environment Management
|
|
176
|
+
|
|
177
|
+
| Tool | Description |
|
|
178
|
+
|------|-------------|
|
|
179
|
+
| `contensa_list_environments` | List all environments for a project |
|
|
180
|
+
| `contensa_get_environment` | Get environment details |
|
|
181
|
+
| `contensa_create_environment` | Create a new environment (empty or cloned) |
|
|
182
|
+
| `contensa_update_environment` | Update environment details |
|
|
183
|
+
| `contensa_delete_environment` | Delete an environment |
|
|
184
|
+
| `contensa_set_active_environment` | Set the active environment for content operations |
|
|
185
|
+
| `contensa_merge_environment` | Merge content from one environment to another |
|
|
186
|
+
| `contensa_sync_environment` | Sync content between environments (in development) |
|
|
187
|
+
|
|
188
|
+
### AI Features
|
|
189
|
+
|
|
190
|
+
| Tool | Description |
|
|
191
|
+
|------|-------------|
|
|
192
|
+
| `contensa_suggest_fields` | AI-powered field suggestions |
|
|
193
|
+
| `contensa_generate_schema` | AI-powered schema generation |
|
|
194
|
+
|
|
195
|
+
## Usage Examples
|
|
196
|
+
|
|
197
|
+
Once configured, you can interact with your CMS through natural language:
|
|
198
|
+
|
|
199
|
+
### Example 1: Create a Blog Content Type
|
|
200
|
+
|
|
201
|
+
```
|
|
202
|
+
"Create a new content type called 'Blog Post' with fields for title, content, author, and published date"
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
The AI will use:
|
|
206
|
+
1. `contensa_create_content_type` to create "Blog Post"
|
|
207
|
+
2. `contensa_create_field` multiple times to add each field
|
|
208
|
+
|
|
209
|
+
### Example 2: Create Content
|
|
210
|
+
|
|
211
|
+
```
|
|
212
|
+
"Create a new blog post titled 'Hello World' with content 'This is my first post'"
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
The AI will use:
|
|
216
|
+
1. `contensa_list_content_types` to find the Blog Post type
|
|
217
|
+
2. `contensa_list_fields` to get the field API names
|
|
218
|
+
3. `contensa_create_content_entry` to create the entry with proper field names
|
|
219
|
+
|
|
220
|
+
### Example 3: Publish Content
|
|
221
|
+
|
|
222
|
+
```
|
|
223
|
+
"Publish all draft blog posts"
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
The AI will use:
|
|
227
|
+
1. `contensa_list_content_entries` with status filter
|
|
228
|
+
2. `contensa_publish_content_entry` for each draft
|
|
229
|
+
|
|
230
|
+
### Example 4: AI Schema Generation
|
|
231
|
+
|
|
232
|
+
```
|
|
233
|
+
"Generate a schema for an e-commerce product catalog"
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
The AI will use:
|
|
237
|
+
1. `contensa_generate_schema` to get AI suggestions
|
|
238
|
+
2. `contensa_create_content_type` to create the type
|
|
239
|
+
3. `contensa_create_field` to add each suggested field
|
|
240
|
+
|
|
241
|
+
### Example 5: Environment Merging
|
|
242
|
+
|
|
243
|
+
```
|
|
244
|
+
"Merge the dev environment to master"
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
The AI will use:
|
|
248
|
+
1. `contensa_list_environments` to find the dev and master environment IDs
|
|
249
|
+
2. `contensa_merge_environment` with dryRun=true to preview conflicts
|
|
250
|
+
3. `contensa_merge_environment` with dryRun=false to perform the merge
|
|
251
|
+
|
|
252
|
+
### Example 6: Preview Merge Conflicts
|
|
253
|
+
|
|
254
|
+
```
|
|
255
|
+
"Show me what conflicts would occur if I merge staging to production"
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
The AI will use:
|
|
259
|
+
1. `contensa_list_environments` to find environment IDs
|
|
260
|
+
2. `contensa_merge_environment` with dryRun=true to preview conflicts without making changes
|
|
261
|
+
|
|
262
|
+
### Example 7: Create Multilingual Content
|
|
263
|
+
|
|
264
|
+
```
|
|
265
|
+
"Create a French version of the blog post with ID 'post-123' and translate the content using AI"
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
The AI will use:
|
|
269
|
+
1. `contensa_get_content_entry` to get the original entry
|
|
270
|
+
2. `contensa_create_locale_variant` with translateContent=true to create and translate
|
|
271
|
+
|
|
272
|
+
### Example 8: Create Locale Variants for Referenced Content
|
|
273
|
+
|
|
274
|
+
```
|
|
275
|
+
"Create a Spanish version of the product 'prod-456' and also create Spanish versions of all referenced entries"
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
The AI will use:
|
|
279
|
+
1. `contensa_create_locale_variant` with translateReferences=true to recursively create variants
|
|
280
|
+
|
|
281
|
+
## Creating Content Entries
|
|
282
|
+
|
|
283
|
+
Creating content entries requires understanding the correct payload format and field structure.
|
|
284
|
+
|
|
285
|
+
### Required Configuration
|
|
286
|
+
|
|
287
|
+
Before creating content entries, ensure you have:
|
|
288
|
+
|
|
289
|
+
1. **API Key**: Set in `CONTENSA_API_KEY` environment variable
|
|
290
|
+
2. **User ID**: Set in `CONTENSA_USER_ID` environment variable (required for all write operations)
|
|
291
|
+
3. **Project ID**: Either set as active project or provided in each request
|
|
292
|
+
|
|
293
|
+
Example configuration:
|
|
294
|
+
|
|
295
|
+
```json
|
|
296
|
+
{
|
|
297
|
+
"mcpServers": {
|
|
298
|
+
"contensa": {
|
|
299
|
+
"command": "npx",
|
|
300
|
+
"args": ["@mybe/contensa-mcp"],
|
|
301
|
+
"env": {
|
|
302
|
+
"CONTENSA_API_KEY": "your-api-key-here",
|
|
303
|
+
"CONTENSA_USER_ID": "your-user-id-here",
|
|
304
|
+
"CONTENSA_PROJECT_ID": "your-default-project-id"
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### Payload Format
|
|
312
|
+
|
|
313
|
+
The `contensa_create_content_entry` tool requires:
|
|
314
|
+
|
|
315
|
+
| Parameter | Required | Description |
|
|
316
|
+
|-----------|----------|-------------|
|
|
317
|
+
| `contentTypeId` | Yes | The ID of the content type |
|
|
318
|
+
| `data` | Yes | Object with field values (keys must be field API names) |
|
|
319
|
+
| `projectId` | No* | Project ID (uses active project if not provided) |
|
|
320
|
+
| `userId` | No* | User ID (uses config userId if not provided) |
|
|
321
|
+
| `status` | No | Entry status: "draft" (default) or "published" |
|
|
322
|
+
| `locale` | No | Locale code (default: "en-US") |
|
|
323
|
+
|
|
324
|
+
*Required but can be set via configuration or active project/user
|
|
325
|
+
|
|
326
|
+
### Field API Names
|
|
327
|
+
|
|
328
|
+
**CRITICAL**: The `data` object keys must use **field API names**, NOT:
|
|
329
|
+
- ❌ Field IDs (UUIDs)
|
|
330
|
+
- ❌ Display names (e.g., "Title", "Description")
|
|
331
|
+
- ✅ API names (e.g., "title", "description", "author_name")
|
|
332
|
+
|
|
333
|
+
### Getting Field API Names
|
|
334
|
+
|
|
335
|
+
Always use `contensa_list_fields` to get the correct API names:
|
|
336
|
+
|
|
337
|
+
```javascript
|
|
338
|
+
// Example response from contensa_list_fields
|
|
339
|
+
{
|
|
340
|
+
"fields": [
|
|
341
|
+
{
|
|
342
|
+
"id": "field-uuid-123",
|
|
343
|
+
"api_name": "title", // ← Use this as the key
|
|
344
|
+
"kind": "short-text",
|
|
345
|
+
"is_required": true
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
"id": "field-uuid-456",
|
|
349
|
+
"api_name": "content", // ← Use this as the key
|
|
350
|
+
"kind": "long-text",
|
|
351
|
+
"is_required": true
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
"id": "field-uuid-789",
|
|
355
|
+
"api_name": "author_name", // ← Use this as the key
|
|
356
|
+
"kind": "short-text",
|
|
357
|
+
"is_required": false
|
|
358
|
+
}
|
|
359
|
+
]
|
|
360
|
+
}
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
### Example: Creating a Blog Post
|
|
364
|
+
|
|
365
|
+
**Step 1**: Get the content type and fields
|
|
366
|
+
|
|
367
|
+
```
|
|
368
|
+
"List all fields for the Blog Post content type"
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
Response shows:
|
|
372
|
+
- `title` (short-text, required)
|
|
373
|
+
- `content` (long-text, required)
|
|
374
|
+
- `author_name` (short-text, optional)
|
|
375
|
+
- `published_date` (date, optional)
|
|
376
|
+
|
|
377
|
+
**Step 2**: Create the entry with correct field API names
|
|
378
|
+
|
|
379
|
+
```javascript
|
|
380
|
+
{
|
|
381
|
+
"contentTypeId": "blog-post-id",
|
|
382
|
+
"data": {
|
|
383
|
+
"title": "Hello World", // ✅ Correct: using API name
|
|
384
|
+
"content": "This is my first post", // ✅ Correct: using API name
|
|
385
|
+
"author_name": "John Doe" // ✅ Correct: using API name
|
|
386
|
+
},
|
|
387
|
+
"status": "draft"
|
|
388
|
+
}
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
### Common Errors and Solutions
|
|
392
|
+
|
|
393
|
+
#### Error: "Missing required fields"
|
|
394
|
+
|
|
395
|
+
**Cause**: Required fields are not provided in the `data` object, or keys don't match field API names.
|
|
396
|
+
|
|
397
|
+
**Solution**:
|
|
398
|
+
1. Use `contensa_list_fields` to get all required fields
|
|
399
|
+
2. Ensure all required fields are in the `data` object
|
|
400
|
+
3. Verify keys match the `api_name` property exactly
|
|
401
|
+
|
|
402
|
+
Example error response:
|
|
403
|
+
```json
|
|
404
|
+
{
|
|
405
|
+
"message": "Missing required fields",
|
|
406
|
+
"missingFields": ["title", "content"]
|
|
407
|
+
}
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
#### Error: "Project ID is required"
|
|
411
|
+
|
|
412
|
+
**Cause**: No active project set and no `projectId` provided.
|
|
413
|
+
|
|
414
|
+
**Solution**:
|
|
415
|
+
1. Set active project: `contensa_set_active_project`
|
|
416
|
+
2. Or provide `projectId` in the request
|
|
417
|
+
3. Or set `CONTENSA_PROJECT_ID` in configuration
|
|
418
|
+
|
|
419
|
+
#### Error: "User ID is required"
|
|
420
|
+
|
|
421
|
+
**Cause**: No `CONTENSA_USER_ID` in configuration and no `userId` provided.
|
|
422
|
+
|
|
423
|
+
**Solution**:
|
|
424
|
+
1. Add `CONTENSA_USER_ID` to your MCP configuration
|
|
425
|
+
2. Or provide `userId` in each request
|
|
426
|
+
|
|
427
|
+
#### Error: "Invalid data format"
|
|
428
|
+
|
|
429
|
+
**Cause**: The `data` parameter is not an object or is a stringified JSON.
|
|
430
|
+
|
|
431
|
+
**Solution**:
|
|
432
|
+
Ensure `data` is a proper object:
|
|
433
|
+
```javascript
|
|
434
|
+
// ✅ Correct
|
|
435
|
+
{ "data": { "title": "Hello" } }
|
|
436
|
+
|
|
437
|
+
// ❌ Wrong
|
|
438
|
+
{ "data": "{\"title\": \"Hello\"}" }
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
### Handling Optional Fields
|
|
442
|
+
|
|
443
|
+
**IMPORTANT**: When creating content entries, handle optional fields correctly to avoid frontend errors:
|
|
444
|
+
|
|
445
|
+
- ✅ **Correct**: Omit optional fields entirely from the `data` object if you don't have values
|
|
446
|
+
- ❌ **Wrong**: Pass empty objects `{}` for optional fields (causes "Failed to construct 'URL'" errors)
|
|
447
|
+
- ❌ **Wrong**: Pass `null` or `undefined` for optional fields
|
|
448
|
+
|
|
449
|
+
**Example - Correct approach**:
|
|
450
|
+
```javascript
|
|
451
|
+
// User says "I'll add the image later"
|
|
452
|
+
{
|
|
453
|
+
"contentTypeId": "blog-post-id",
|
|
454
|
+
"data": {
|
|
455
|
+
"title": "Hello World",
|
|
456
|
+
"content": "This is my first post"
|
|
457
|
+
// ✅ image field is omitted entirely
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
**Example - Wrong approach**:
|
|
463
|
+
```javascript
|
|
464
|
+
// ❌ This causes frontend errors!
|
|
465
|
+
{
|
|
466
|
+
"contentTypeId": "blog-post-id",
|
|
467
|
+
"data": {
|
|
468
|
+
"title": "Hello World",
|
|
469
|
+
"content": "This is my first post",
|
|
470
|
+
"image": {} // ❌ Empty object causes "Invalid URL" errors
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
**Why this matters**: Empty objects for media fields cause the frontend to attempt constructing URLs from invalid data, resulting in errors. The MCP server now automatically removes empty objects, `null`, and `undefined` values before sending data to the API.
|
|
476
|
+
|
|
477
|
+
### Field Value Types
|
|
478
|
+
|
|
479
|
+
Different field types expect different value formats:
|
|
480
|
+
|
|
481
|
+
| Field Type | Value Format | Example | Notes |
|
|
482
|
+
|------------|--------------|---------|-------|
|
|
483
|
+
| `short-text` | String | `"Hello World"` | Omit if optional and no value |
|
|
484
|
+
| `long-text` | String | `"Long content..."` | Omit if optional and no value |
|
|
485
|
+
| `number` | Number | `42` | Omit if optional and no value |
|
|
486
|
+
| `date` | ISO 8601 string | `"2024-01-15T10:30:00Z"` | Omit if optional and no value |
|
|
487
|
+
| `boolean` | Boolean | `true` or `false` | Omit if optional and no value |
|
|
488
|
+
| `list` | Array of strings | `["tag1", "tag2"]` | Empty arrays `[]` are valid |
|
|
489
|
+
| `media` | Media asset ID (string) | `"media-uuid-123"` | **Never use `{}`** - omit if no value |
|
|
490
|
+
| `reference` | Entry ID (string) | `"entry-uuid-456"` | Omit if optional and no value |
|
|
491
|
+
| `references-many` | Array of entry IDs | `["entry-1", "entry-2"]` | Empty arrays `[]` are valid |
|
|
492
|
+
|
|
493
|
+
### Complete Example Workflow
|
|
494
|
+
|
|
495
|
+
```
|
|
496
|
+
User: "Create a blog post about AI with title 'The Future of AI' and content 'AI is transforming...'"
|
|
497
|
+
|
|
498
|
+
AI Assistant:
|
|
499
|
+
1. Lists content types to find "Blog Post" → gets contentTypeId
|
|
500
|
+
2. Lists fields for Blog Post → gets field API names and requirements
|
|
501
|
+
3. Creates entry:
|
|
502
|
+
{
|
|
503
|
+
"contentTypeId": "blog-post-id",
|
|
504
|
+
"data": {
|
|
505
|
+
"title": "The Future of AI",
|
|
506
|
+
"content": "AI is transforming..."
|
|
507
|
+
},
|
|
508
|
+
"status": "draft"
|
|
509
|
+
}
|
|
510
|
+
4. Returns success with entry ID
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
### Best Practices
|
|
514
|
+
|
|
515
|
+
1. **Always get field API names first**: Use `contensa_list_fields` before creating entries
|
|
516
|
+
2. **Validate required fields**: Check which fields are required before submitting
|
|
517
|
+
3. **Use correct data types**: Match the field type's expected value format
|
|
518
|
+
4. **Set active project**: Use `contensa_set_active_project` to avoid repeating projectId
|
|
519
|
+
5. **Handle errors gracefully**: Check error messages for missing fields and retry with corrections
|
|
520
|
+
|
|
521
|
+
## Field Types
|
|
522
|
+
|
|
523
|
+
Available field types for `contensa_create_field`:
|
|
524
|
+
|
|
525
|
+
| Type | Description |
|
|
526
|
+
|------|-------------|
|
|
527
|
+
| `short-text` | Single line text |
|
|
528
|
+
| `long-text` | Multi-line text / rich content |
|
|
529
|
+
| `number` | Numeric values |
|
|
530
|
+
| `date` | Date/datetime values |
|
|
531
|
+
| `boolean` | True/false values |
|
|
532
|
+
| `media` | Images and files |
|
|
533
|
+
| `list` | Array of values |
|
|
534
|
+
| `reference` | Link to another content entry |
|
|
535
|
+
| `references-many` | Multiple links to content entries |
|
|
536
|
+
|
|
537
|
+
## Environment Merging
|
|
538
|
+
|
|
539
|
+
The MCP server supports merging content between environments (e.g., dev → staging → master).
|
|
540
|
+
|
|
541
|
+
### Merge Strategies
|
|
542
|
+
|
|
543
|
+
When merging environments, you can specify how to handle conflicts:
|
|
544
|
+
|
|
545
|
+
| Strategy | Description |
|
|
546
|
+
|----------|-------------|
|
|
547
|
+
| `skip` | Skip conflicting items (default) |
|
|
548
|
+
| `replace` | Replace target with source content |
|
|
549
|
+
| `merge` | Attempt to merge changes |
|
|
550
|
+
| `create-new` | Create new entries for conflicts |
|
|
551
|
+
|
|
552
|
+
### Dry Run Mode
|
|
553
|
+
|
|
554
|
+
Always preview changes before merging to production:
|
|
555
|
+
|
|
556
|
+
```
|
|
557
|
+
"Do a dry run merge from dev to master"
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
This will show you:
|
|
561
|
+
- Number of content types to be merged
|
|
562
|
+
- Number of entries to be merged
|
|
563
|
+
- Any conflicts that would occur
|
|
564
|
+
- Errors that would prevent the merge
|
|
565
|
+
|
|
566
|
+
### Master Environment Protection
|
|
567
|
+
|
|
568
|
+
By default, merging into the master environment requires explicit approval (`requireMasterApproval: false`). This prevents accidental overwrites of production content.
|
|
569
|
+
|
|
570
|
+
### Merge Workflow Example
|
|
571
|
+
|
|
572
|
+
1. **Preview the merge**:
|
|
573
|
+
```
|
|
574
|
+
"Show me what would happen if I merge dev to master"
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
2. **Review conflicts** and decide on resolution strategies
|
|
578
|
+
|
|
579
|
+
3. **Execute the merge**:
|
|
580
|
+
```
|
|
581
|
+
"Merge dev to master, replacing conflicts and disabling master approval"
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
### Sync vs Merge
|
|
585
|
+
|
|
586
|
+
- **Merge** (`contensa_merge_environment`): Fully functional, supports dry-run, conflict resolution strategies
|
|
587
|
+
- **Sync** (`contensa_sync_environment`): Currently in development, will support three-way merge logic
|
|
588
|
+
|
|
589
|
+
## Locale Management
|
|
590
|
+
|
|
591
|
+
The MCP server provides comprehensive support for creating and managing multilingual content.
|
|
592
|
+
|
|
593
|
+
### Supported Locales
|
|
594
|
+
|
|
595
|
+
The system supports 31 locales across multiple regions:
|
|
596
|
+
|
|
597
|
+
**Default**: `en-US` (English - United States)
|
|
598
|
+
|
|
599
|
+
**Europe**: `fr-FR`, `es-ES`, `de-DE`, `it-IT`, `pt-PT`, `nl-NL`, `sv-SE`, `pl-PL`, `ru-RU`, `en-GB`
|
|
600
|
+
|
|
601
|
+
**Americas**: `pt-BR`, `es-MX`, `es-AR`, `en-CA`, `fr-CA`
|
|
602
|
+
|
|
603
|
+
**Asia-Pacific**: `ja-JP`, `ko-KR`, `zh-CN`, `zh-TW`, `hi-IN`, `th-TH`, `vi-VN`, `id-ID`, `ms-MY`, `fil-PH`, `bn-BD`, `en-AU`
|
|
604
|
+
|
|
605
|
+
**Middle East & Africa**: `ar-SA`, `tr-TR`, `he-IL`
|
|
606
|
+
|
|
607
|
+
Use `contensa_get_supported_locales` to get the full list with locale codes, names, and flags.
|
|
608
|
+
|
|
609
|
+
### Creating Locale Variants
|
|
610
|
+
|
|
611
|
+
Locale variants allow you to create multilingual versions of your content. Each variant:
|
|
612
|
+
- Shares the same content structure (fields) as the original
|
|
613
|
+
- Has its own data in the target language
|
|
614
|
+
- Can optionally be AI-translated from the source locale
|
|
615
|
+
- Can reference the same entries or have locale-specific references
|
|
616
|
+
|
|
617
|
+
### Translation Options
|
|
618
|
+
|
|
619
|
+
When creating a locale variant, you have two key options:
|
|
620
|
+
|
|
621
|
+
#### 1. `translateContent` (default: true)
|
|
622
|
+
|
|
623
|
+
- **true**: Uses AI to translate text fields (short-text, long-text, list) to the target locale
|
|
624
|
+
- **false**: Copies content as-is without translation
|
|
625
|
+
|
|
626
|
+
**Note**: Reference fields are never translated - they maintain the same entry IDs across locales.
|
|
627
|
+
|
|
628
|
+
#### 2. `translateReferences` (default: false)
|
|
629
|
+
|
|
630
|
+
- **true**: Recursively creates locale variants for all referenced entries
|
|
631
|
+
- **false**: Only creates a variant for the main entry
|
|
632
|
+
|
|
633
|
+
**Warning**: Setting `translateReferences=true` can create many entries if you have deeply nested references. Use with caution.
|
|
634
|
+
|
|
635
|
+
### How Translation Works
|
|
636
|
+
|
|
637
|
+
The locale system uses AI-powered translation with the following behavior:
|
|
638
|
+
|
|
639
|
+
1. **Translatable Fields**: Only text-based fields are translated (short-text, long-text, number, list)
|
|
640
|
+
2. **Reference Fields**: Reference and references-many fields are copied as-is (same entry IDs)
|
|
641
|
+
3. **Retry Logic**: Translation attempts up to 2 retries on failure
|
|
642
|
+
4. **Fallback**: If translation fails after retries, content is copied without translation
|
|
643
|
+
5. **Metadata**: Translated entries are marked with `is_translated: true` in metadata
|
|
644
|
+
|
|
645
|
+
### Edge Cases and Behavior
|
|
646
|
+
|
|
647
|
+
#### Existing Variants
|
|
648
|
+
|
|
649
|
+
If a locale variant already exists for an entry, the API returns a 409 Conflict error. You cannot create duplicate locale variants.
|
|
650
|
+
|
|
651
|
+
#### Circular References
|
|
652
|
+
|
|
653
|
+
The system prevents infinite loops from circular references by tracking visited entry IDs during recursive locale creation.
|
|
654
|
+
|
|
655
|
+
#### Partial Translation
|
|
656
|
+
|
|
657
|
+
If translation fails for some fields but succeeds for others, the variant is still created with whatever translation succeeded.
|
|
658
|
+
|
|
659
|
+
#### Referenced Entry Variants
|
|
660
|
+
|
|
661
|
+
When `translateReferences=true`:
|
|
662
|
+
- The system checks if a locale variant already exists for each referenced entry
|
|
663
|
+
- If it exists, it uses the existing variant
|
|
664
|
+
- If not, it creates a new variant (with or without translation based on settings)
|
|
665
|
+
- All created entries are returned in the response
|
|
666
|
+
|
|
667
|
+
### Locale Workflow Example
|
|
668
|
+
|
|
669
|
+
1. **Check supported locales**:
|
|
670
|
+
```
|
|
671
|
+
"What locales are supported?"
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
2. **Create a simple locale variant**:
|
|
675
|
+
```
|
|
676
|
+
"Create a French version of blog post 'post-123' with AI translation"
|
|
677
|
+
```
|
|
678
|
+
|
|
679
|
+
3. **Create variant without translation**:
|
|
680
|
+
```
|
|
681
|
+
"Create a German version of product 'prod-456' but don't translate the content"
|
|
682
|
+
```
|
|
683
|
+
|
|
684
|
+
4. **Create variant with referenced entries**:
|
|
685
|
+
```
|
|
686
|
+
"Create a Spanish version of the homepage entry and all its referenced content"
|
|
687
|
+
```
|
|
688
|
+
|
|
689
|
+
5. **List all variants**:
|
|
690
|
+
```
|
|
691
|
+
"Show me all locale variants of entry 'post-123'"
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
### Locale Validation
|
|
695
|
+
|
|
696
|
+
Locale codes must match the BCP-47 format (language-COUNTRY):
|
|
697
|
+
- ✅ Valid: `en-US`, `fr-FR`, `zh-CN`
|
|
698
|
+
- ❌ Invalid: `en`, `french`, `EN-us`
|
|
699
|
+
|
|
700
|
+
The client automatically validates locale codes against the supported locales list.
|
|
701
|
+
|
|
702
|
+
### Response Format
|
|
703
|
+
|
|
704
|
+
When creating a locale variant, the response includes:
|
|
705
|
+
- `variant`: The created locale variant entry
|
|
706
|
+
- `createdEntries`: Array of all entries created (if `translateReferences=true`)
|
|
707
|
+
- `totalCreated`: Total number of entries created (including the main variant)
|
|
708
|
+
- `message`: Success message
|
|
709
|
+
|
|
710
|
+
Example response:
|
|
711
|
+
```json
|
|
712
|
+
{
|
|
713
|
+
"variant": { "id": "new-variant-id", "locale": "fr-FR", ... },
|
|
714
|
+
"createdEntries": [
|
|
715
|
+
{ "id": "ref-1-fr", "title": "Referenced Entry 1" },
|
|
716
|
+
{ "id": "ref-2-fr", "title": "Referenced Entry 2" }
|
|
717
|
+
],
|
|
718
|
+
"totalCreated": 3,
|
|
719
|
+
"message": "Locale variant created successfully with references"
|
|
720
|
+
}
|
|
721
|
+
```
|
|
722
|
+
|
|
723
|
+
## Getting Your API Key
|
|
724
|
+
|
|
725
|
+
1. Log in to your Contensa dashboard
|
|
726
|
+
2. Go to Settings → API Keys
|
|
727
|
+
3. Generate a new API key
|
|
728
|
+
4. Copy the key and add it to your MCP configuration
|
|
729
|
+
|
|
730
|
+
## Development
|
|
731
|
+
|
|
732
|
+
```bash
|
|
733
|
+
# Install dependencies
|
|
734
|
+
npm install
|
|
735
|
+
|
|
736
|
+
# Build
|
|
737
|
+
npm run build
|
|
738
|
+
|
|
739
|
+
# Run in development
|
|
740
|
+
npm run dev
|
|
741
|
+
|
|
742
|
+
# Start the server
|
|
743
|
+
npm start
|
|
744
|
+
```
|
|
745
|
+
|
|
746
|
+
## Troubleshooting
|
|
747
|
+
|
|
748
|
+
### "API key is required" error
|
|
749
|
+
|
|
750
|
+
Make sure `CONTENSA_API_KEY` is set in your MCP configuration.
|
|
751
|
+
|
|
752
|
+
### Tools not showing up
|
|
753
|
+
|
|
754
|
+
1. Restart Cursor/Claude Desktop after updating the config
|
|
755
|
+
2. Check the MCP server logs for errors
|
|
756
|
+
3. Verify the path to the CLI is correct
|
|
757
|
+
|
|
758
|
+
### Permission errors
|
|
759
|
+
|
|
760
|
+
Ensure your API key has the necessary permissions for the operations you're trying to perform.
|
|
761
|
+
|
|
762
|
+
## License
|
|
763
|
+
|
|
764
|
+
MIT
|
|
765
|
+
|