@curenorway/kode-mcp 1.3.0 → 1.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 (3) hide show
  1. package/README.md +183 -83
  2. package/dist/index.js +85 -3
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -2,42 +2,52 @@
2
2
 
3
3
  MCP (Model Context Protocol) server that enables AI agents to manage Webflow scripts via Cure Kode CDN.
4
4
 
5
- ## What is this?
5
+ ## Features
6
6
 
7
- This MCP server allows AI assistants like Claude to directly interact with Cure Kode:
8
- - List, create, update, and delete scripts
9
- - Deploy to staging and production
10
- - Check deployment status
11
- - Analyze web pages for script detection
7
+ - **Script Management** - List, create, update, and delete scripts
8
+ - **Deployment Control** - Deploy to staging, promote to production, rollback
9
+ - **Page Context** - Cache and retrieve page structures for development
10
+ - **Script Analysis** - Auto-analyze scripts for metadata (selectors, triggers, dependencies)
11
+ - **Production Safety** - Explicit enable required, confirmation for promote
12
12
 
13
13
  ## Installation
14
14
 
15
15
  ### For Claude Code
16
16
 
17
- Add to your Claude Code configuration (`~/.claude/claude_code_config.json`):
17
+ The easiest way is to run `kode init` in your project, which creates `.mcp.json`:
18
18
 
19
19
  ```json
20
20
  {
21
21
  "mcpServers": {
22
22
  "cure-kode": {
23
+ "type": "stdio",
23
24
  "command": "npx",
24
- "args": ["@curenorway/kode-mcp"]
25
+ "args": ["-y", "@curenorway/kode-mcp"]
25
26
  }
26
27
  }
27
28
  }
28
29
  ```
29
30
 
30
- ### For Cursor / Other IDEs
31
+ Then restart Claude Code and approve the MCP when prompted.
31
32
 
32
- Refer to your IDE's MCP configuration documentation.
33
+ ### Manual Configuration
33
34
 
34
- ## Configuration
35
+ Add to your Claude Code configuration (`~/.claude/claude_code_config.json`):
35
36
 
36
- The MCP server needs to know which site to manage. Configure via:
37
+ ```json
38
+ {
39
+ "mcpServers": {
40
+ "cure-kode": {
41
+ "command": "npx",
42
+ "args": ["-y", "@curenorway/kode-mcp"]
43
+ }
44
+ }
45
+ }
46
+ ```
37
47
 
38
- ### Option 1: Project Config (Recommended)
48
+ ## Configuration
39
49
 
40
- Run `kode init` in your project to create `.cure-kode/config.json`:
50
+ The MCP server reads configuration from `.cure-kode/config.json` (created by `kode init`):
41
51
 
42
52
  ```json
43
53
  {
@@ -45,46 +55,151 @@ Run `kode init` in your project to create `.cure-kode/config.json`:
45
55
  "siteSlug": "my-site",
46
56
  "siteName": "My Site",
47
57
  "apiKey": "ck_...",
48
- "scriptsDir": "kode",
58
+ "scriptsDir": ".cure-kode-scripts",
49
59
  "environment": "staging"
50
60
  }
51
61
  ```
52
62
 
53
- ### Option 2: Environment Variables
54
-
63
+ Or via environment variables:
55
64
  ```bash
56
65
  export CURE_KODE_API_KEY="ck_..."
57
66
  export CURE_KODE_SITE_ID="your-site-uuid"
58
- export CURE_KODE_API_URL="https://app.cure.no" # optional
59
67
  ```
60
68
 
61
69
  ## Available Tools
62
70
 
71
+ ### Script Management
72
+
63
73
  | Tool | Description |
64
74
  |------|-------------|
65
75
  | `kode_list_scripts` | List all scripts for the site |
66
- | `kode_get_script` | Get script content by slug |
67
- | `kode_create_script` | Create a new script |
68
- | `kode_update_script` | Update script content |
76
+ | `kode_get_script` | Get script by slug (supports `includeContent: false` for metadata only) |
77
+ | `kode_create_script` | Create a new script entry (metadata only, no content) |
78
+ | `kode_update_script` | Update script settings (autoLoad, scope, purpose) |
69
79
  | `kode_delete_script` | Delete a script |
70
- | `kode_deploy` | Deploy to staging/production |
71
- | `kode_promote` | Promote staging to production |
80
+ | `kode_push` | Upload local files from `.cure-kode-scripts/` to server |
81
+
82
+ ### Deployment
83
+
84
+ | Tool | Description |
85
+ |------|-------------|
86
+ | `kode_deploy` | Deploy to staging |
87
+ | `kode_promote` | Promote staging to production (**requires `confirmed: true`**) |
88
+ | `kode_rollback` | Rollback to previous deployment |
72
89
  | `kode_status` | Get deployment status |
73
- | `kode_fetch_html` | Analyze a webpage |
74
- | `kode_list_pages` | List page definitions |
90
+
91
+ ### Production Management
92
+
93
+ | Tool | Description |
94
+ |------|-------------|
95
+ | `kode_production_enable` | Enable production environment |
96
+ | `kode_production_disable` | Disable production environment |
97
+
98
+ ### Page & HTML Analysis
99
+
100
+ | Tool | Description |
101
+ |------|-------------|
102
+ | `kode_fetch_html` | Fetch and parse HTML from URL |
103
+ | `kode_fetch_html_smart` | Fetch with CMS truncation for smaller context |
104
+ | `kode_list_pages` | List page definitions for the site |
105
+ | `kode_assign_script_to_page` | Assign script to specific pages |
106
+ | `kode_remove_script_from_page` | Remove script from page |
107
+
108
+ ### Page Context (for AI Development)
109
+
110
+ | Tool | Description |
111
+ |------|-------------|
112
+ | `kode_refresh_page` | Fetch and cache page structure |
113
+ | `kode_get_page_context` | Get cached page context (sections, forms, CTAs, selectors) |
114
+ | `kode_list_pages_context` | List all cached page contexts |
115
+
116
+ ### Script Metadata
117
+
118
+ | Tool | Description |
119
+ |------|-------------|
120
+ | `kode_analyze_script` | Analyze script and generate metadata |
121
+ | `kode_get_script_metadata` | Get script metadata and AI summary |
122
+
123
+ ### Other
124
+
125
+ | Tool | Description |
126
+ |------|-------------|
75
127
  | `kode_site_info` | Get site info and CDN URL |
128
+ | `kode_read_context` | Read AI context file |
129
+ | `kode_update_context` | Update AI context file |
130
+
131
+ ## Important: Content Workflow
132
+
133
+ **MCP is the control plane - never send script content through MCP tools.**
134
+
135
+ The correct workflow:
136
+ 1. Write script file locally to `.cure-kode-scripts/script-name.js`
137
+ 2. Use `kode_push` to upload local files to server
138
+ 3. Use `kode_deploy` to deploy
139
+
140
+ ```
141
+ AI writes file → kode_push → kode_deploy
142
+ ```
143
+
144
+ **Do NOT** pass content to `kode_create_script` or `kode_update_script` - these only handle metadata.
145
+
146
+ ## Safety Features
147
+
148
+ ### Production Confirmation
149
+
150
+ `kode_promote` requires explicit confirmation to prevent accidental production deployments:
151
+
152
+ ```typescript
153
+ // This will fail:
154
+ kode_promote()
155
+
156
+ // This works:
157
+ kode_promote({ confirmed: true })
158
+ ```
159
+
160
+ ### Production Disabled by Default
161
+
162
+ New sites start with production disabled. Must explicitly enable:
163
+
164
+ ```typescript
165
+ kode_production_enable()
166
+ // Then can promote
167
+ kode_promote({ confirmed: true })
168
+ ```
169
+
170
+ ## Example Usage
76
171
 
77
- ## Example Prompts
172
+ ### Create and Deploy a Script
78
173
 
79
- Once configured, you can ask Claude:
174
+ ```
175
+ 1. "Create a new script called tracking.js"
176
+ → kode_create_script({ name: "tracking", slug: "tracking", type: "javascript" })
177
+
178
+ 2. Write the file locally
179
+ → Write to .cure-kode-scripts/tracking.js
180
+
181
+ 3. "Push the changes"
182
+ → kode_push()
183
+
184
+ 4. "Deploy to staging"
185
+ → kode_deploy()
186
+
187
+ 5. "Promote to production"
188
+ → kode_promote({ confirmed: true })
189
+ ```
190
+
191
+ ### Analyze a Page and Add Functionality
80
192
 
81
193
  ```
82
- "List all the scripts in Cure Kode"
83
- "Create a new tracking script that logs page views"
84
- "Update the init.js script to add error handling"
85
- "Deploy to staging"
86
- "What's the current deployment status?"
87
- "Analyze example.com to see what scripts are loaded"
194
+ 1. "Analyze the homepage"
195
+ kode_fetch_html_smart({ url: "https://mysite.com" })
196
+ kode_refresh_page({ url: "https://mysite.com" })
197
+
198
+ 2. "What sections are on this page?"
199
+ → kode_get_page_context({ url: "https://mysite.com" })
200
+
201
+ 3. "Add a script to animate the hero section"
202
+ → Create script, write file, push, deploy
88
203
  ```
89
204
 
90
205
  ## How It Works
@@ -92,88 +207,73 @@ Once configured, you can ask Claude:
92
207
  ```
93
208
  ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
94
209
  │ AI Agent │ MCP │ Kode MCP │ REST │ Cure Kode API │
95
- │ (Claude/etc) │─────▶│ Server │─────▶│ (Railway)
210
+ │ (Claude/etc) │─────▶│ Server │─────▶│ (app.cure.no)
96
211
  └─────────────────┘ └─────────────────┘ └─────────────────┘
97
212
 
98
213
 
99
214
  ┌─────────────────┐
100
215
  │ Local Scripts │
101
- (.cure-kode/)
216
+ │(.cure-kode-scripts/)│
102
217
  └─────────────────┘
103
218
  ```
104
219
 
105
- 1. AI agent calls MCP tools (e.g., `kode_create_script`)
106
- 2. MCP server reads config from `.cure-kode/config.json`
107
- 3. MCP server calls Cure Kode REST API with API key
108
- 4. Results returned to AI agent
109
-
110
220
  ## Security
111
221
 
112
222
  ### API Key Authentication
113
223
 
114
- - **SHA256 Hashed Storage**: API keys are hashed before storage on the server
224
+ - **Hashed Storage**: API keys are SHA256/HMAC hashed before server storage
115
225
  - **Site-scoped**: Each API key is bound to a specific CDN site
116
- - **Permission-based**: Keys have granular permissions:
117
- - `read` - List/view scripts and deployments
118
- - `write` - Create and update scripts
119
- - `deploy` - Deploy to staging/production
120
- - `delete` - Delete scripts
226
+ - **Permission-based**: Granular permissions (read, write, deploy, delete)
121
227
  - **Expiration**: Keys can have optional expiration dates
122
228
 
123
- ### Local Security
229
+ ### CORS Security (v2.6)
124
230
 
125
- - API keys stored in `.cure-kode/config.json` (auto-gitignored)
126
- - Never commit API keys to version control
127
- - Keys prefixed with `ck_` for easy identification
231
+ Script endpoints restrict CORS to configured domains:
232
+ - Site's domain, staging_domain, production_domain
233
+ - Webflow preview domains (*.webflow.io)
234
+ - Localhost for development
235
+ - **No wildcard CORS** on script endpoints
128
236
 
129
- ### Network Security
237
+ ### SSRF Protection
130
238
 
131
- - All API calls use HTTPS
132
- - **SSRF Protection**: HTML fetch endpoints block:
133
- - Private IP ranges (127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)
134
- - Localhost and internal hostnames
135
- - Cloud metadata endpoints (169.254.169.254)
136
- - Only HTTP/HTTPS protocols allowed
137
-
138
- ### Best Practices
139
-
140
- - Generate separate API keys for different environments/developers
141
- - Use read-only keys when full access isn't needed
142
- - Rotate keys periodically
143
- - Revoke keys when team members leave
239
+ HTML fetch endpoints block:
240
+ - Private IP ranges (127.0.0.0/8, 10.0.0.0/8, etc.)
241
+ - Cloud metadata endpoints (169.254.169.254)
242
+ - Internal hostnames
144
243
 
145
244
  ## Troubleshooting
146
245
 
147
246
  ### "Cure Kode not configured"
148
247
 
149
- Either:
150
- 1. Run `kode init` in your project directory
151
- 2. Set `CURE_KODE_API_KEY` and `CURE_KODE_SITE_ID` environment variables
248
+ Run `kode init` in your project directory to create configuration.
152
249
 
153
250
  ### "API key invalid"
154
251
 
155
- - Check your API key starts with `ck_`
156
- - Verify the key hasn't expired
157
- - Ensure the key has required permissions
252
+ - Check key starts with `ck_`
253
+ - Verify key hasn't expired
254
+ - Ensure key has required permissions
158
255
 
159
- ### Tools not appearing in Claude
256
+ ### "Production not enabled"
160
257
 
161
- - Restart Claude Code after configuration changes
162
- - Check the MCP server is running: `npx @curenorway/kode-mcp`
163
- - Verify config file syntax
258
+ Use `kode_production_enable()` before promoting.
164
259
 
165
- ## Development
260
+ ### "Promote requires confirmation"
166
261
 
167
- ```bash
168
- # Install dependencies
169
- pnpm install
262
+ Add `confirmed: true` parameter:
263
+ ```typescript
264
+ kode_promote({ confirmed: true })
265
+ ```
170
266
 
171
- # Build
172
- pnpm build
267
+ ### Tools not appearing in Claude
173
268
 
174
- # Run locally
175
- node dist/index.js
176
- ```
269
+ 1. Restart Claude Code after config changes
270
+ 2. Check `.mcp.json` syntax
271
+ 3. Verify MCP server runs: `npx @curenorway/kode-mcp`
272
+
273
+ ## Requirements
274
+
275
+ - Node.js 18 or later
276
+ - Cure Kode API key (from https://app.cure.no/tools/kode)
177
277
 
178
278
  ## License
179
279
 
package/dist/index.js CHANGED
@@ -105,6 +105,15 @@ var KodeApiClient = class {
105
105
  async getDeploymentStatus(siteId) {
106
106
  return this.request(`/api/cdn/sites/${siteId}/deployments/status`);
107
107
  }
108
+ async rollback(siteId, environment = "staging") {
109
+ return this.request("/api/cdn/deploy/rollback", {
110
+ method: "POST",
111
+ body: JSON.stringify({
112
+ siteId,
113
+ environment
114
+ })
115
+ });
116
+ }
108
117
  // v2.3: Production enabled toggle
109
118
  async setProductionEnabled(siteId, enabled, productionDomain) {
110
119
  return this.request(`/api/cdn/sites/${siteId}/production`, {
@@ -408,10 +417,30 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
408
417
  },
409
418
  {
410
419
  name: "kode_promote",
411
- description: "Promote the latest staging deployment to production. Use this after testing on staging.",
420
+ description: "Promote the latest staging deployment to production. Use this after testing on staging. IMPORTANT: Requires confirmed=true to actually promote - this prevents accidental production deployments.",
412
421
  inputSchema: {
413
422
  type: "object",
414
- properties: {},
423
+ properties: {
424
+ confirmed: {
425
+ type: "boolean",
426
+ description: "Safety confirmation. Must be set to true to proceed with production promotion. If false or missing, returns a preview of what would be promoted."
427
+ }
428
+ },
429
+ required: []
430
+ }
431
+ },
432
+ {
433
+ name: "kode_rollback",
434
+ description: "Rollback to the previous deployment. Copies the previous version back to the active environment. Use this if a deployment caused issues.",
435
+ inputSchema: {
436
+ type: "object",
437
+ properties: {
438
+ environment: {
439
+ type: "string",
440
+ enum: ["staging", "production"],
441
+ description: "Environment to rollback. Default: staging"
442
+ }
443
+ },
415
444
  required: []
416
445
  }
417
446
  },
@@ -1009,6 +1038,7 @@ Scripts deployed (${scriptSizes.length}):`;
1009
1038
  };
1010
1039
  }
1011
1040
  case "kode_promote": {
1041
+ const { confirmed } = args;
1012
1042
  const status = await client.getDeploymentStatus(siteId);
1013
1043
  if (!status.productionEnabled) {
1014
1044
  return {
@@ -1032,17 +1062,69 @@ Scripts deployed (${scriptSizes.length}):`;
1032
1062
  isError: true
1033
1063
  };
1034
1064
  }
1065
+ if (!confirmed) {
1066
+ const stagingVersion = status.staging.lastSuccessful?.version || "unknown";
1067
+ const productionVersion = status.production.lastSuccessful?.version || "(none)";
1068
+ return {
1069
+ content: [
1070
+ {
1071
+ type: "text",
1072
+ text: `\u26A0\uFE0F PRODUCTION PROMOTION CONFIRMATION REQUIRED
1073
+
1074
+ This will deploy to production:
1075
+ Staging version: ${stagingVersion}
1076
+ Current production: ${productionVersion}
1077
+
1078
+ To proceed, call kode_promote with confirmed: true
1079
+
1080
+ Note: Always test on staging first before promoting to production.`
1081
+ }
1082
+ ]
1083
+ };
1084
+ }
1035
1085
  const deployment = await client.promoteToProduction(siteId);
1036
1086
  return {
1037
1087
  content: [
1038
1088
  {
1039
1089
  type: "text",
1040
- text: `Promoted ${deployment.version} to production
1090
+ text: `\u2705 Promoted ${deployment.version} to production
1041
1091
  Status: ${deployment.status}`
1042
1092
  }
1043
1093
  ]
1044
1094
  };
1045
1095
  }
1096
+ case "kode_rollback": {
1097
+ const { environment = "staging" } = args;
1098
+ if (environment === "production") {
1099
+ const status = await client.getDeploymentStatus(siteId);
1100
+ if (!status.productionEnabled) {
1101
+ return {
1102
+ content: [
1103
+ {
1104
+ type: "text",
1105
+ text: "Cannot rollback production: Production is not enabled for this site."
1106
+ }
1107
+ ],
1108
+ isError: true
1109
+ };
1110
+ }
1111
+ }
1112
+ const result = await client.rollback(siteId, environment);
1113
+ return {
1114
+ content: [
1115
+ {
1116
+ type: "text",
1117
+ text: `\u2705 Rolled back ${environment}
1118
+
1119
+ From: ${result.rolledBackFrom.version}
1120
+ To: ${result.rolledBackTo.version}
1121
+
1122
+ CDN URL: ${result.cdn_url}
1123
+ Duration: ${result.duration_ms}ms`
1124
+ }
1125
+ ]
1126
+ };
1127
+ }
1046
1128
  case "kode_production_enable": {
1047
1129
  const { productionDomain } = args;
1048
1130
  const result = await client.setProductionEnabled(siteId, true, productionDomain);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@curenorway/kode-mcp",
3
- "version": "1.3.0",
4
- "description": "MCP server for Cure Kode - enables AI agents to manage Webflow scripts",
3
+ "version": "1.4.0",
4
+ "description": "MCP server for Cure Kode CDN - enables AI agents to manage, deploy, and analyze Webflow scripts",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "cure-kode-mcp": "./dist/index.js"