@aborruso/ckan-mcp-server 0.3.2 → 0.4.1

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,183 @@
1
+ # Proposal: Add Cloudflare Workers Deployment
2
+
3
+ ## Change ID
4
+ `add-cloudflare-workers`
5
+
6
+ ## Summary
7
+ Enable deployment of CKAN MCP Server to Cloudflare Workers platform, providing global HTTP access to the server without requiring local installation.
8
+
9
+ ## Motivation
10
+
11
+ ### Problem
12
+ Currently, CKAN MCP Server can only run:
13
+ - Locally via stdio mode (Claude Desktop integration)
14
+ - Self-hosted via HTTP mode (requires Node.js runtime, port management, server maintenance)
15
+
16
+ This limits accessibility for users who want to use the server remotely without managing infrastructure.
17
+
18
+ ### Solution
19
+ Deploy to Cloudflare Workers - a serverless platform ideal for this use case:
20
+ - **Stateless architecture**: Server makes no persistent state (only API calls to CKAN)
21
+ - **Read-only operations**: All tools are GET-only, perfect for edge deployment
22
+ - **Lightweight**: Small bundle size (~50KB), fast cold starts
23
+ - **Free tier**: 100k requests/day sufficient for typical usage
24
+ - **Global edge**: Low latency worldwide
25
+ - **Zero maintenance**: No server management required
26
+
27
+ ### Alternatives Considered
28
+ - **Railway** ($5/month credit): Overkill for stateless app, requires VM management
29
+ - **Fly.io** (3 free VMs): More infrastructure than needed
30
+ - **Render** (free tier): Spin-down after inactivity causes poor UX for MCP clients
31
+
32
+ ## Goals
33
+
34
+ ### Primary
35
+ - [ ] Deploy server to Cloudflare Workers
36
+ - [ ] Preserve all existing functionality (7 MCP tools, 3 resource templates)
37
+ - [ ] Provide public HTTPS endpoint: `https://ckan-mcp-server.<account>.workers.dev`
38
+ - [ ] Maintain stdio and self-hosted HTTP modes (no breaking changes)
39
+
40
+ ### Secondary
41
+ - [ ] Document deployment process for contributors
42
+ - [ ] Add deployment scripts to package.json
43
+ - [ ] Test with multiple CKAN portals (dati.gov.it, data.gov, demo.ckan.org)
44
+
45
+ ### Non-Goals
46
+ - Authentication/authorization (public read-only access is acceptable)
47
+ - Custom domain setup (workers.dev subdomain is sufficient)
48
+ - Rate limiting beyond Cloudflare's default (100k req/day is adequate)
49
+ - WebSocket support (MCP over HTTP uses SSE, which Workers supports)
50
+
51
+ ## Impact Analysis
52
+
53
+ ### Code Changes
54
+ - **New files**:
55
+ - `src/worker.ts` (~80-100 lines): Workers entry point
56
+ - `wrangler.toml` (~15 lines): Cloudflare configuration
57
+ - `docs/DEPLOYMENT.md` (~100 lines): Deployment guide
58
+ - **Modified files**:
59
+ - `package.json`: Add wrangler scripts and devDependency
60
+ - `esbuild.config.js`: Add Workers build target (or create separate config)
61
+ - `README.md`: Add deployment section
62
+ - `LOG.md`: Document deployment capability
63
+
64
+ ### Build System
65
+ - Add `wrangler` CLI as devDependency
66
+ - Create separate esbuild config for Workers (different entry point, output format)
67
+ - Workers build: `src/worker.ts` → `dist/worker.js` (ESM format, bundled)
68
+ - Existing builds unchanged (stdio/http modes still work)
69
+
70
+ ### Testing
71
+ - Manual testing required: Deploy to workers.dev and test all 7 tools
72
+ - Integration tests already cover tool functionality
73
+ - No new automated tests needed (same MCP server logic)
74
+
75
+ ### Documentation
76
+ - New `docs/DEPLOYMENT.md`: Step-by-step deployment guide
77
+ - Update `README.md`: Add "Deployment" section with 3 options (local, self-hosted, Cloudflare)
78
+ - Update `docs/future-ideas.md`: Move item from backlog to implemented
79
+
80
+ ### Dependencies
81
+ - **New devDependency**: `wrangler` (Cloudflare CLI)
82
+ - **No new runtime dependencies**: Workers runtime provides fetch/Request/Response APIs
83
+
84
+ ## User Experience
85
+
86
+ ### Before
87
+ Users must:
88
+ 1. Install Node.js and npm
89
+ 2. Clone repository or install via npm
90
+ 3. Run server locally (stdio or HTTP mode)
91
+ 4. Configure Claude Desktop with local path
92
+
93
+ ### After (Option 3)
94
+ Users can:
95
+ 1. Use public endpoint directly: `https://ckan-mcp-server.<account>.workers.dev`
96
+ 2. Configure Claude Desktop with HTTP URL (no local installation)
97
+ 3. Access from any MCP client supporting HTTP transport
98
+
99
+ **Benefit**: Zero installation for end users who just want to query CKAN portals.
100
+
101
+ ### For Contributors
102
+ Contributors can:
103
+ 1. Fork repository
104
+ 2. Run `npm run deploy` (after Cloudflare account setup)
105
+ 3. Get personal Workers deployment for testing
106
+
107
+ ## Risks and Mitigations
108
+
109
+ ### Risk: API Rate Limits
110
+ - **Issue**: Cloudflare free tier limits to 100k req/day
111
+ - **Likelihood**: Low (typical usage << 100k/day)
112
+ - **Mitigation**: Document rate limits; users can deploy own Workers instance
113
+
114
+ ### Risk: Workers Runtime Compatibility
115
+ - **Issue**: Node.js APIs may not work in Workers environment
116
+ - **Likelihood**: Low (server uses standard fetch/HTTP APIs)
117
+ - **Mitigation**: Test thoroughly; Workers supports most standard Web APIs
118
+
119
+ ### Risk: Bundle Size Limits
120
+ - **Issue**: Workers free tier limits script size to 1MB
121
+ - **Likelihood**: Very low (current bundle ~50KB)
122
+ - **Mitigation**: Bundle analysis, treeshaking with esbuild
123
+
124
+ ### Risk: Cold Start Latency
125
+ - **Issue**: First request after idle period may be slower
126
+ - **Likelihood**: Medium (Workers spin down after inactivity)
127
+ - **Mitigation**: Document expected latency; acceptable for MCP use case
128
+
129
+ ## Success Criteria
130
+
131
+ ### Must Have
132
+ - [ ] Server deploys successfully to Cloudflare Workers
133
+ - [ ] All 7 MCP tools work identically to local/self-hosted modes
134
+ - [ ] Public HTTPS endpoint accessible from Claude Desktop
135
+ - [ ] Response times < 5 seconds for typical CKAN queries
136
+ - [ ] Documentation complete (DEPLOYMENT.md with screenshots)
137
+
138
+ ### Nice to Have
139
+ - [ ] Deployment CI/CD via GitHub Actions
140
+ - [ ] Monitoring/analytics dashboard
141
+ - [ ] Multiple environment support (dev, staging, prod)
142
+
143
+ ## Timeline Estimate
144
+
145
+ **Total**: 4-6 hours of focused work (spread over multiple sessions for user learning)
146
+
147
+ ### Phase 1: Setup and Configuration (1-2 hours)
148
+ - Install wrangler CLI
149
+ - Create Cloudflare account (free)
150
+ - Initialize Workers project
151
+ - Configure wrangler.toml
152
+
153
+ ### Phase 2: Code Adaptation (1-2 hours)
154
+ - Create src/worker.ts adapter
155
+ - Update build configuration
156
+ - Test local build with `wrangler dev`
157
+
158
+ ### Phase 3: Deployment and Testing (1 hour)
159
+ - Deploy to workers.dev
160
+ - Test all 7 tools with curl/Claude Desktop
161
+ - Verify with multiple CKAN portals
162
+
163
+ ### Phase 4: Documentation (1 hour)
164
+ - Write DEPLOYMENT.md
165
+ - Update README.md
166
+ - Add LOG.md entry
167
+
168
+ ## Open Questions
169
+
170
+ 1. **Cloudflare Account**: Do you already have a Cloudflare account, or do we need to create one?
171
+ 2. **Workers Subdomain**: Are you okay with `ckan-mcp-server.<account>.workers.dev`, or do you want a custom workers.dev name?
172
+ 3. **Public Access**: Are you comfortable with the endpoint being publicly accessible (read-only, no auth)?
173
+ 4. **Environment Variables**: Do we need any configurable settings (e.g., default CKAN server, rate limits)?
174
+
175
+ ## Next Steps
176
+
177
+ 1. User reviews and approves this proposal
178
+ 2. User answers open questions
179
+ 3. Create `tasks.md` with ordered, step-by-step work items
180
+ 4. Create `design.md` with architectural details
181
+ 5. Create spec delta in `specs/cloudflare-deployment/spec.md`
182
+ 6. Validate proposal with `openspec validate add-cloudflare-workers --strict`
183
+ 7. Begin implementation in `openspec:apply` phase (only after approval)
@@ -0,0 +1,389 @@
1
+ # cloudflare-deployment Specification
2
+
3
+ ## Purpose
4
+ Enable deployment of CKAN MCP Server to Cloudflare Workers platform, providing global HTTP access without local installation or server management.
5
+
6
+ ## ADDED Requirements
7
+
8
+ ### Requirement: Workers Entry Point
9
+
10
+ The system SHALL provide a Cloudflare Workers-compatible entry point that handles HTTP requests using the Workers fetch API.
11
+
12
+ #### Scenario: Health check endpoint
13
+
14
+ - **WHEN** client sends `GET /health` to Workers endpoint
15
+ - **THEN** server returns JSON with status, version, tool count, and resource count
16
+
17
+ #### Scenario: MCP protocol endpoint
18
+
19
+ - **WHEN** client sends `POST /mcp` with JSON-RPC request to Workers endpoint
20
+ - **THEN** server processes MCP request and returns JSON-RPC response
21
+
22
+ #### Scenario: Invalid route
23
+
24
+ - **WHEN** client requests any path other than `/health` or `/mcp`
25
+ - **THEN** server returns 404 Not Found
26
+
27
+ #### Scenario: Invalid method on MCP endpoint
28
+
29
+ - **WHEN** client sends non-POST request to `/mcp`
30
+ - **THEN** server returns 404 Not Found
31
+
32
+ ---
33
+
34
+ ### Requirement: MCP Server Integration
35
+
36
+ The system SHALL initialize MCP server instance on each Workers invocation and register all tools and resources.
37
+
38
+ #### Scenario: Server initialization
39
+
40
+ - **WHEN** Workers receives MCP request
41
+ - **THEN** server creates MCP Server instance with name "ckan-mcp-server" and version "0.4.0"
42
+
43
+ #### Scenario: Tool registration
44
+
45
+ - **WHEN** Workers initializes MCP server
46
+ - **THEN** server registers all 7 CKAN tools (package_search, package_show, organization_list, organization_show, organization_search, datastore_search, status_show)
47
+
48
+ #### Scenario: Resource registration
49
+
50
+ - **WHEN** Workers initializes MCP server
51
+ - **THEN** server registers all 3 resource templates (dataset, resource, organization)
52
+
53
+ #### Scenario: Tools list request
54
+
55
+ - **WHEN** client calls `tools/list` method via Workers endpoint
56
+ - **THEN** response includes all 7 registered CKAN tools with descriptions
57
+
58
+ ---
59
+
60
+ ### Requirement: Web Standards HTTP Client
61
+
62
+ The system SHALL use native Web Fetch API for CKAN API requests instead of Node.js-specific libraries.
63
+
64
+ #### Scenario: CKAN API request with fetch
65
+
66
+ - **WHEN** tool calls `makeCkanRequest()` in Workers runtime
67
+ - **THEN** client uses native `fetch()` with 30-second timeout
68
+
69
+ #### Scenario: Query parameter encoding
70
+
71
+ - **WHEN** CKAN request includes parameters (e.g., `q`, `rows`, `start`)
72
+ - **THEN** client encodes parameters in URL using `URLSearchParams`
73
+
74
+ #### Scenario: Request timeout
75
+
76
+ - **WHEN** CKAN API takes longer than 30 seconds
77
+ - **THEN** client aborts request using `AbortController` and returns timeout error
78
+
79
+ #### Scenario: HTTP error handling
80
+
81
+ - **WHEN** CKAN API returns HTTP error status (4xx, 5xx)
82
+ - **THEN** client throws error with status code and message
83
+
84
+ #### Scenario: CKAN API validation
85
+
86
+ - **WHEN** CKAN API returns 200 OK but `success: false`
87
+ - **THEN** client throws error with CKAN error message
88
+
89
+ ---
90
+
91
+ ### Requirement: Workers Build Configuration
92
+
93
+ The system SHALL provide separate build configuration for Workers deployment targeting browser platform with ESM format.
94
+
95
+ #### Scenario: Workers build script
96
+
97
+ - **WHEN** user runs `npm run build:worker`
98
+ - **THEN** esbuild compiles `src/worker.ts` to `dist/worker.js` in ESM format
99
+
100
+ #### Scenario: Bundle all dependencies
101
+
102
+ - **WHEN** esbuild builds Workers bundle
103
+ - **THEN** all dependencies are bundled (no external modules)
104
+
105
+ #### Scenario: Platform targeting
106
+
107
+ - **WHEN** esbuild builds Workers bundle
108
+ - **THEN** platform is set to `browser` and target is `es2022`
109
+
110
+ #### Scenario: Output format
111
+
112
+ - **WHEN** Workers build completes
113
+ - **THEN** output is ESM format (not CommonJS)
114
+
115
+ #### Scenario: Bundle size validation
116
+
117
+ - **WHEN** Workers build completes
118
+ - **THEN** bundle size is less than 1MB (Workers script size limit)
119
+
120
+ ---
121
+
122
+ ### Requirement: Wrangler Configuration
123
+
124
+ The system SHALL provide Wrangler configuration file for Workers deployment and local development.
125
+
126
+ #### Scenario: Wrangler configuration file
127
+
128
+ - **WHEN** project contains `wrangler.toml` in root directory
129
+ - **THEN** configuration specifies name, main entry point, and compatibility date
130
+
131
+ #### Scenario: Build command
132
+
133
+ - **WHEN** `wrangler deploy` or `wrangler dev` runs
134
+ - **THEN** Wrangler executes `npm run build:worker` before deployment
135
+
136
+ #### Scenario: Local development server
137
+
138
+ - **WHEN** user runs `npm run dev:worker`
139
+ - **THEN** Wrangler starts local Workers server on http://localhost:8787
140
+
141
+ ---
142
+
143
+ ### Requirement: Workers Deployment
144
+
145
+ The system SHALL deploy to Cloudflare Workers and provide public HTTPS endpoint.
146
+
147
+ #### Scenario: Deploy to Workers
148
+
149
+ - **WHEN** user runs `npm run deploy`
150
+ - **THEN** Wrangler builds and uploads worker to Cloudflare
151
+
152
+ #### Scenario: Public endpoint
153
+
154
+ - **WHEN** deployment succeeds
155
+ - **THEN** Workers script is accessible at `https://ckan-mcp-server.<account>.workers.dev`
156
+
157
+ #### Scenario: HTTPS support
158
+
159
+ - **WHEN** client accesses Workers endpoint
160
+ - **THEN** connection uses HTTPS with valid certificate
161
+
162
+ ---
163
+
164
+ ### Requirement: Tool Functionality Preservation
165
+
166
+ The system SHALL maintain identical functionality for all CKAN tools in Workers runtime compared to Node.js runtime.
167
+
168
+ #### Scenario: Package search in Workers
169
+
170
+ - **WHEN** client calls `ckan_package_search` via Workers endpoint
171
+ - **THEN** response is identical to Node.js runtime response
172
+
173
+ #### Scenario: Datastore query in Workers
174
+
175
+ - **WHEN** client calls `ckan_datastore_search` via Workers endpoint
176
+ - **THEN** response is identical to Node.js runtime response
177
+
178
+ #### Scenario: Resource template in Workers
179
+
180
+ - **WHEN** client reads `ckan://{server}/dataset/{id}` via Workers
181
+ - **THEN** response is identical to Node.js runtime response
182
+
183
+ #### Scenario: Error handling in Workers
184
+
185
+ - **WHEN** CKAN API is unreachable in Workers runtime
186
+ - **THEN** error response matches Node.js runtime error format
187
+
188
+ ---
189
+
190
+ ### Requirement: Response Format Compatibility
191
+
192
+ The system SHALL support both markdown and JSON output formats in Workers runtime.
193
+
194
+ #### Scenario: Markdown format
195
+
196
+ - **WHEN** client requests tool with `response_format: "markdown"`
197
+ - **THEN** Workers returns formatted markdown text
198
+
199
+ #### Scenario: JSON format
200
+
201
+ - **WHEN** client requests tool with `response_format: "json"`
202
+ - **THEN** Workers returns raw JSON data
203
+
204
+ #### Scenario: Character limit
205
+
206
+ - **WHEN** response exceeds CHARACTER_LIMIT (50000 characters)
207
+ - **THEN** Workers truncates response identically to Node.js runtime
208
+
209
+ ---
210
+
211
+ ### Requirement: Error Handling
212
+
213
+ The system SHALL handle Workers-specific errors gracefully with JSON-RPC error responses.
214
+
215
+ #### Scenario: Malformed JSON-RPC request
216
+
217
+ - **WHEN** client sends invalid JSON to `/mcp` endpoint
218
+ - **THEN** Workers returns JSON-RPC error with code -32700 (Parse error)
219
+
220
+ #### Scenario: Internal worker error
221
+
222
+ - **WHEN** worker encounters unexpected exception
223
+ - **THEN** Workers returns JSON-RPC error with code -32603 (Internal error)
224
+
225
+ #### Scenario: Method not found
226
+
227
+ - **WHEN** client calls non-existent MCP method
228
+ - **THEN** Workers returns JSON-RPC error with code -32601 (Method not found)
229
+
230
+ ---
231
+
232
+ ### Requirement: CORS Support
233
+
234
+ The system SHALL include CORS headers to enable browser-based MCP clients.
235
+
236
+ #### Scenario: CORS headers on success
237
+
238
+ - **WHEN** Workers returns successful response
239
+ - **THEN** response includes `Access-Control-Allow-Origin: *` header
240
+
241
+ #### Scenario: CORS headers on error
242
+
243
+ - **WHEN** Workers returns error response
244
+ - **THEN** response includes `Access-Control-Allow-Origin: *` header
245
+
246
+ #### Scenario: Preflight request
247
+
248
+ - **WHEN** browser sends OPTIONS request for CORS preflight
249
+ - **THEN** Workers returns allowed methods and headers
250
+
251
+ ---
252
+
253
+ ### Requirement: Deployment Documentation
254
+
255
+ The system SHALL provide comprehensive documentation for deploying to Cloudflare Workers.
256
+
257
+ #### Scenario: Deployment guide
258
+
259
+ - **WHEN** contributor wants to deploy Workers instance
260
+ - **THEN** `docs/DEPLOYMENT.md` provides step-by-step instructions
261
+
262
+ #### Scenario: Prerequisites documentation
263
+
264
+ - **WHEN** contributor reads DEPLOYMENT.md
265
+ - **THEN** document lists all prerequisites (Cloudflare account, wrangler CLI)
266
+
267
+ #### Scenario: Troubleshooting guide
268
+
269
+ - **WHEN** deployment fails
270
+ - **THEN** DEPLOYMENT.md includes common errors and solutions
271
+
272
+ #### Scenario: README update
273
+
274
+ - **WHEN** user reads README.md
275
+ - **THEN** deployment options section includes Cloudflare Workers option
276
+
277
+ ---
278
+
279
+ ### Requirement: Backwards Compatibility
280
+
281
+ The system SHALL maintain all existing deployment modes (stdio, self-hosted HTTP) without breaking changes.
282
+
283
+ #### Scenario: Stdio mode unchanged
284
+
285
+ - **WHEN** user runs `npm start` after Workers implementation
286
+ - **THEN** stdio transport works identically to pre-Workers version
287
+
288
+ #### Scenario: Self-hosted HTTP mode unchanged
289
+
290
+ - **WHEN** user runs `TRANSPORT=http PORT=3000 npm start` after Workers implementation
291
+ - **THEN** HTTP server works identically to pre-Workers version
292
+
293
+ #### Scenario: Existing tests pass
294
+
295
+ - **WHEN** user runs `npm test` after Workers implementation
296
+ - **THEN** all 113 existing tests pass without modification
297
+
298
+ #### Scenario: Node.js bundle unchanged
299
+
300
+ - **WHEN** user runs `npm run build` after Workers implementation
301
+ - **THEN** Node.js bundle (`dist/index.js`) is unchanged
302
+
303
+ ---
304
+
305
+ ### Requirement: Development Workflow
306
+
307
+ The system SHALL support efficient local development and testing of Workers deployment.
308
+
309
+ #### Scenario: Local Workers testing
310
+
311
+ - **WHEN** developer runs `npm run dev:worker`
312
+ - **THEN** wrangler starts local server with hot reload
313
+
314
+ #### Scenario: Quick iteration
315
+
316
+ - **WHEN** developer modifies `src/worker.ts`
317
+ - **THEN** wrangler automatically rebuilds and reloads
318
+
319
+ #### Scenario: curl testing
320
+
321
+ - **WHEN** developer sends curl request to local Workers
322
+ - **THEN** response matches expected MCP protocol format
323
+
324
+ ---
325
+
326
+ ### Requirement: Monitoring and Debugging
327
+
328
+ The system SHALL provide access to Workers logs and metrics for troubleshooting.
329
+
330
+ #### Scenario: Real-time logs
331
+
332
+ - **WHEN** developer runs `wrangler tail`
333
+ - **THEN** console.log output from worker appears in terminal
334
+
335
+ #### Scenario: Error logs
336
+
337
+ - **WHEN** worker throws exception
338
+ - **THEN** stack trace appears in `wrangler tail` output
339
+
340
+ #### Scenario: Cloudflare dashboard
341
+
342
+ - **WHEN** user accesses Cloudflare Workers dashboard
343
+ - **THEN** metrics show request count, error rate, and CPU time
344
+
345
+ ---
346
+
347
+ ## Related Specifications
348
+
349
+ - **mcp-resources**: Resource templates must work in Workers runtime
350
+ - **documentation-language**: Deployment docs must be in English
351
+
352
+ ---
353
+
354
+ ## Implementation Notes
355
+
356
+ ### HTTP Client Migration
357
+ - Replace `axios` with `fetch()` in `src/utils/http.ts`
358
+ - Use `AbortController` for timeout (same 30s limit)
359
+ - Maintain identical error handling behavior
360
+
361
+ ### Build System
362
+ - Add `esbuild.worker.js` for Workers-specific build
363
+ - Keep existing `esbuild.config.js` for Node.js build
364
+ - Add npm scripts: `build:worker`, `dev:worker`, `deploy`
365
+
366
+ ### Testing Approach
367
+ - Manual testing with `wrangler dev` and curl
368
+ - Production testing after deployment
369
+ - Claude Desktop integration test
370
+ - Existing test suite validates tool logic (no new tests needed)
371
+
372
+ ### Deployment Process
373
+ 1. User creates Cloudflare account (free)
374
+ 2. User installs wrangler CLI
375
+ 3. User authenticates: `wrangler login`
376
+ 4. User builds: `npm run build:worker`
377
+ 5. User deploys: `wrangler deploy`
378
+ 6. User gets endpoint: `https://ckan-mcp-server.<account>.workers.dev`
379
+
380
+ ### Bundle Size Optimization
381
+ - Remove `axios` dependency (save ~15KB)
382
+ - Use esbuild tree-shaking
383
+ - Minify Workers bundle
384
+ - Target: < 50KB (well below 1MB limit)
385
+
386
+ ### Future Enhancements
387
+ - Add Workers KV caching (documented in future-ideas.md)
388
+ - Support custom domains (documented in future-ideas.md)
389
+ - Add API key authentication via Workers secrets (documented in future-ideas.md)