@latellu/atlas-mcp 1.0.2 → 1.0.4

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 (3) hide show
  1. package/README.md +12 -1
  2. package/dist/index.js +28 -18
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -61,6 +61,17 @@ atlas-mcp
61
61
 
62
62
  ## Configuration
63
63
 
64
+ ### Getting an API Key
65
+
66
+ 1. Open the Atlas dashboard: **https://cms.atlas.latellu.com**
67
+ 2. Go to **Settings → API Keys**
68
+ 3. Click **Create API Key**, give it a name, and save
69
+ 4. Copy the key — it is only shown once
70
+
71
+ **Key types:**
72
+ - `atlas_live_*` — Read-only access (delivery API). Use for fetching content.
73
+ - `atlas_mgmt_*` — Read-write access (management API). Use for creating/updating content.
74
+
64
75
  ### Environment Variables
65
76
 
66
77
  | Variable | Required | Description |
@@ -161,7 +172,7 @@ AI: → Calls upload_media with file_path='/Users/you/Pictures/tokyo.png'
161
172
 
162
173
  ### Best Practices
163
174
 
164
- 1. **Scope API keys**: Use minimal scopes required
175
+ 1. **Scope API keys**: For management keys, grant only the scopes each tool needs — `content:write` for create/update/delete/reorder, `content:publish` for publish/unpublish/archive/schedule, `media:write` for uploads/deletes. Leave unused scopes off.
165
176
  2. **Restrict upload paths**: Only allow necessary directories
166
177
  3. **Rotate keys**: Regularly rotate API keys
167
178
  4. **Monitor usage**: Review MCP tool calls for suspicious activity
package/dist/index.js CHANGED
@@ -12553,6 +12553,20 @@ var AtlasClient = class {
12553
12553
  ...options?.headers
12554
12554
  }
12555
12555
  });
12556
+ return this.handleResponse(response);
12557
+ }
12558
+ // Write requests to /api/v1/manage/* carry an Idempotency-Key so that
12559
+ // AI-agent-driven retries don't risk double-create/double-publish.
12560
+ async writeRequest(path, options) {
12561
+ return this.request(path, {
12562
+ ...options,
12563
+ headers: {
12564
+ "Idempotency-Key": crypto.randomUUID(),
12565
+ ...options.headers
12566
+ }
12567
+ });
12568
+ }
12569
+ async handleResponse(response) {
12556
12570
  if (!response.ok) {
12557
12571
  const error = await response.json().catch(() => ({}));
12558
12572
  throw new Error(
@@ -12591,39 +12605,39 @@ var AtlasClient = class {
12591
12605
  return this.request(`/api/v1/public/entries/${slug}`);
12592
12606
  }
12593
12607
  async createEntry(contentType, data, slug) {
12594
- return this.request(`/api/v1/manage/content-types/${contentType}/entries`, {
12608
+ return this.writeRequest(`/api/v1/manage/content-types/${contentType}/entries`, {
12595
12609
  method: "POST",
12596
12610
  body: JSON.stringify({ slug, data })
12597
12611
  });
12598
12612
  }
12599
12613
  async updateEntry(contentType, slug, data) {
12600
- return this.request(`/api/v1/manage/content-types/${contentType}/entries/${slug}`, {
12614
+ return this.writeRequest(`/api/v1/manage/content-types/${contentType}/entries/${slug}`, {
12601
12615
  method: "PUT",
12602
12616
  body: JSON.stringify({ data })
12603
12617
  });
12604
12618
  }
12605
12619
  async deleteEntry(contentType, slug) {
12606
- return this.request(`/api/v1/manage/content-types/${contentType}/entries/${slug}`, {
12620
+ return this.writeRequest(`/api/v1/manage/content-types/${contentType}/entries/${slug}`, {
12607
12621
  method: "DELETE"
12608
12622
  });
12609
12623
  }
12610
12624
  async publishEntry(contentType, slug) {
12611
- return this.request(`/api/v1/manage/content-types/${contentType}/entries/${slug}/publish`, {
12625
+ return this.writeRequest(`/api/v1/manage/content-types/${contentType}/entries/${slug}/publish`, {
12612
12626
  method: "PATCH"
12613
12627
  });
12614
12628
  }
12615
12629
  async unpublishEntry(contentType, slug) {
12616
- return this.request(`/api/v1/manage/content-types/${contentType}/entries/${slug}/unpublish`, {
12630
+ return this.writeRequest(`/api/v1/manage/content-types/${contentType}/entries/${slug}/unpublish`, {
12617
12631
  method: "PATCH"
12618
12632
  });
12619
12633
  }
12620
12634
  async archiveEntry(contentType, slug) {
12621
- return this.request(`/api/v1/manage/content-types/${contentType}/entries/${slug}/archive`, {
12635
+ return this.writeRequest(`/api/v1/manage/content-types/${contentType}/entries/${slug}/archive`, {
12622
12636
  method: "PATCH"
12623
12637
  });
12624
12638
  }
12625
12639
  async duplicateEntry(contentType, slug) {
12626
- return this.request(`/api/v1/manage/content-types/${contentType}/entries/${slug}/duplicate`, {
12640
+ return this.writeRequest(`/api/v1/manage/content-types/${contentType}/entries/${slug}/duplicate`, {
12627
12641
  method: "POST"
12628
12642
  });
12629
12643
  }
@@ -12638,24 +12652,24 @@ var AtlasClient = class {
12638
12652
  return this.request(`/api/v1/public/pages/${slug}`);
12639
12653
  }
12640
12654
  async createPage(data) {
12641
- return this.request("/api/v1/manage/pages", {
12655
+ return this.writeRequest("/api/v1/manage/pages", {
12642
12656
  method: "POST",
12643
12657
  body: JSON.stringify(data)
12644
12658
  });
12645
12659
  }
12646
12660
  async updatePage(slug, data) {
12647
- return this.request(`/api/v1/manage/pages/${slug}`, {
12661
+ return this.writeRequest(`/api/v1/manage/pages/${slug}`, {
12648
12662
  method: "PUT",
12649
12663
  body: JSON.stringify(data)
12650
12664
  });
12651
12665
  }
12652
12666
  async deletePage(slug) {
12653
- return this.request(`/api/v1/manage/pages/${slug}`, {
12667
+ return this.writeRequest(`/api/v1/manage/pages/${slug}`, {
12654
12668
  method: "DELETE"
12655
12669
  });
12656
12670
  }
12657
12671
  async publishPage(slug) {
12658
- return this.request(`/api/v1/manage/pages/${slug}/publish`, {
12672
+ return this.writeRequest(`/api/v1/manage/pages/${slug}/publish`, {
12659
12673
  method: "PATCH"
12660
12674
  });
12661
12675
  }
@@ -12678,16 +12692,12 @@ var AtlasClient = class {
12678
12692
  const response = await fetch(`${this.baseUrl}/api/v1/manage/media/upload`, {
12679
12693
  method: "POST",
12680
12694
  headers: {
12681
- "X-API-Key": this.apiKey
12695
+ "X-API-Key": this.apiKey,
12696
+ "Idempotency-Key": crypto.randomUUID()
12682
12697
  },
12683
12698
  body: formData
12684
12699
  });
12685
- if (!response.ok) {
12686
- const error = await response.json().catch(() => ({}));
12687
- throw new Error(`Upload failed: ${response.status} - ${error.message || response.statusText}`);
12688
- }
12689
- const data = await response.json();
12690
- return data.data || data;
12700
+ return this.handleResponse(response);
12691
12701
  }
12692
12702
  };
12693
12703
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@latellu/atlas-mcp",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },