@aborruso/ckan-mcp-server 0.4.17 → 0.4.19

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 (87) hide show
  1. package/LOG.md +64 -0
  2. package/README.md +104 -34
  3. package/dist/index.js +161 -45
  4. package/dist/worker.js +42 -42
  5. package/package.json +12 -1
  6. package/.devin/wiki.json +0 -273
  7. package/CLAUDE.md +0 -398
  8. package/PRD.md +0 -999
  9. package/REFACTORING.md +0 -238
  10. package/examples/langgraph/01_basic_workflow.py +0 -277
  11. package/examples/langgraph/02_data_exploration.py +0 -366
  12. package/examples/langgraph/README.md +0 -719
  13. package/examples/langgraph/metadata_quality.py +0 -299
  14. package/examples/langgraph/requirements.txt +0 -12
  15. package/examples/langgraph/setup.sh +0 -32
  16. package/examples/langgraph/test_setup.py +0 -106
  17. package/openspec/AGENTS.md +0 -456
  18. package/openspec/changes/add-ckan-analyze-dataset-structure/proposal.md +0 -17
  19. package/openspec/changes/add-ckan-analyze-dataset-structure/specs/ckan-insights/spec.md +0 -7
  20. package/openspec/changes/add-ckan-analyze-dataset-structure/tasks.md +0 -6
  21. package/openspec/changes/add-ckan-analyze-dataset-updates/proposal.md +0 -17
  22. package/openspec/changes/add-ckan-analyze-dataset-updates/specs/ckan-insights/spec.md +0 -7
  23. package/openspec/changes/add-ckan-analyze-dataset-updates/tasks.md +0 -6
  24. package/openspec/changes/add-ckan-audit-tool/proposal.md +0 -17
  25. package/openspec/changes/add-ckan-audit-tool/specs/ckan-insights/spec.md +0 -7
  26. package/openspec/changes/add-ckan-audit-tool/tasks.md +0 -6
  27. package/openspec/changes/add-ckan-dataset-insights/proposal.md +0 -17
  28. package/openspec/changes/add-ckan-dataset-insights/specs/ckan-insights/spec.md +0 -7
  29. package/openspec/changes/add-ckan-dataset-insights/tasks.md +0 -6
  30. package/openspec/changes/add-ckan-host-allowlist-env/design.md +0 -38
  31. package/openspec/changes/add-ckan-host-allowlist-env/proposal.md +0 -16
  32. package/openspec/changes/add-ckan-host-allowlist-env/specs/ckan-request-allowlist/spec.md +0 -15
  33. package/openspec/changes/add-ckan-host-allowlist-env/specs/cloudflare-deployment/spec.md +0 -11
  34. package/openspec/changes/add-ckan-host-allowlist-env/tasks.md +0 -12
  35. package/openspec/changes/add-escape-text-query/proposal.md +0 -12
  36. package/openspec/changes/add-escape-text-query/specs/ckan-search/spec.md +0 -11
  37. package/openspec/changes/add-escape-text-query/tasks.md +0 -8
  38. package/openspec/changes/add-mqa-quality-tool/proposal.md +0 -21
  39. package/openspec/changes/add-mqa-quality-tool/specs/ckan-quality/spec.md +0 -71
  40. package/openspec/changes/add-mqa-quality-tool/tasks.md +0 -29
  41. package/openspec/changes/archive/2026-01-08-add-mcp-resources/design.md +0 -115
  42. package/openspec/changes/archive/2026-01-08-add-mcp-resources/proposal.md +0 -52
  43. package/openspec/changes/archive/2026-01-08-add-mcp-resources/specs/mcp-resources/spec.md +0 -92
  44. package/openspec/changes/archive/2026-01-08-add-mcp-resources/tasks.md +0 -56
  45. package/openspec/changes/archive/2026-01-08-expand-test-coverage-specs/design.md +0 -355
  46. package/openspec/changes/archive/2026-01-08-expand-test-coverage-specs/proposal.md +0 -161
  47. package/openspec/changes/archive/2026-01-08-expand-test-coverage-specs/tasks.md +0 -162
  48. package/openspec/changes/archive/2026-01-08-translate-project-to-english/proposal.md +0 -115
  49. package/openspec/changes/archive/2026-01-08-translate-project-to-english/specs/documentation-language/spec.md +0 -32
  50. package/openspec/changes/archive/2026-01-08-translate-project-to-english/tasks.md +0 -115
  51. package/openspec/changes/archive/2026-01-10-add-ckan-find-relevant-datasets/proposal.md +0 -17
  52. package/openspec/changes/archive/2026-01-10-add-ckan-find-relevant-datasets/specs/ckan-insights/spec.md +0 -7
  53. package/openspec/changes/archive/2026-01-10-add-ckan-find-relevant-datasets/tasks.md +0 -6
  54. package/openspec/changes/archive/2026-01-10-add-cloudflare-workers/design.md +0 -734
  55. package/openspec/changes/archive/2026-01-10-add-cloudflare-workers/proposal.md +0 -183
  56. package/openspec/changes/archive/2026-01-10-add-cloudflare-workers/specs/cloudflare-deployment/spec.md +0 -389
  57. package/openspec/changes/archive/2026-01-10-add-cloudflare-workers/tasks.md +0 -519
  58. package/openspec/changes/archive/2026-01-15-add-mcp-prompts/proposal.md +0 -13
  59. package/openspec/changes/archive/2026-01-15-add-mcp-prompts/specs/mcp-prompts/spec.md +0 -22
  60. package/openspec/changes/archive/2026-01-15-add-mcp-prompts/tasks.md +0 -10
  61. package/openspec/changes/archive/2026-01-15-add-mcp-resource-filters/proposal.md +0 -13
  62. package/openspec/changes/archive/2026-01-15-add-mcp-resource-filters/specs/mcp-resources/spec.md +0 -38
  63. package/openspec/changes/archive/2026-01-15-add-mcp-resource-filters/tasks.md +0 -10
  64. package/openspec/changes/archive/2026-01-19-update-repo-owner-ondata/proposal.md +0 -13
  65. package/openspec/changes/archive/2026-01-19-update-repo-owner-ondata/specs/repository-metadata/spec.md +0 -14
  66. package/openspec/changes/archive/2026-01-19-update-repo-owner-ondata/tasks.md +0 -12
  67. package/openspec/changes/archive/2026-01-19-update-search-parser-config/proposal.md +0 -13
  68. package/openspec/changes/archive/2026-01-19-update-search-parser-config/specs/ckan-insights/spec.md +0 -11
  69. package/openspec/changes/archive/2026-01-19-update-search-parser-config/specs/ckan-search/spec.md +0 -11
  70. package/openspec/changes/archive/2026-01-19-update-search-parser-config/tasks.md +0 -6
  71. package/openspec/changes/archive/add-automated-tests/design.md +0 -324
  72. package/openspec/changes/archive/add-automated-tests/proposal.md +0 -167
  73. package/openspec/changes/archive/add-automated-tests/specs/automated-testing/spec.md +0 -143
  74. package/openspec/changes/archive/add-automated-tests/tasks.md +0 -132
  75. package/openspec/project.md +0 -115
  76. package/openspec/specs/ckan-insights/spec.md +0 -23
  77. package/openspec/specs/ckan-search/spec.md +0 -16
  78. package/openspec/specs/cloudflare-deployment/spec.md +0 -344
  79. package/openspec/specs/documentation-language/spec.md +0 -32
  80. package/openspec/specs/mcp-prompts/spec.md +0 -26
  81. package/openspec/specs/mcp-resources/spec.md +0 -120
  82. package/openspec/specs/repository-metadata/spec.md +0 -19
  83. package/private/commenti-privati.yaml +0 -14
  84. package/testo.md +0 -12
  85. package/web-gui/PRD.md +0 -158
  86. package/web-gui/public/index.html +0 -883
  87. package/wrangler.toml +0 -6
@@ -1,132 +0,0 @@
1
- # Tasks: Add Automated Testing
2
-
3
- Ordered list of work items to add automated tests to the project.
4
-
5
- ## Phase 1: Foundation
6
-
7
- - [x] Install Vitest and related dependencies
8
- - [x] Create vitest.config.ts with TypeScript support
9
- - [x] Create test directory structure: `tests/unit/`, `tests/integration/`, `tests/fixtures/`
10
- - [x] Add test scripts to package.json (test, test:watch, test:coverage)
11
- - [x] Create .gitignore entry for coverage directory
12
- - [x] Configure coverage settings (threshold: 80%)
13
-
14
- ## Phase 2: Create Mock Fixtures
15
-
16
- - [x] Create `tests/fixtures/responses/status-success.json`
17
- - [x] Create `tests/fixtures/responses/package-search-success.json`
18
- - [x] Create `tests/fixtures/responses/package-show-success.json`
19
- - [x] Create `tests/fixtures/responses/organization-list-success.json`
20
- - [x] Create `tests/fixtures/responses/organization-show-success.json`
21
- - [x] Create `tests/fixtures/responses/organization-search-success.json`
22
- - [x] Create `tests/fixtures/responses/datastore-search-success.json`
23
- - [x] Create `tests/fixtures/errors/timeout.json`
24
- - [x] Create `tests/fixtures/errors/not-found.json`
25
- - [x] Create `tests/fixtures/errors/server-error.json`
26
- - [x] Document fixture structure in tests/README.md
27
-
28
- ## Phase 3: Unit Tests for Utils
29
-
30
- - [x] Create `tests/unit/formatting.test.ts`
31
- - [x] Write test for truncateText() with normal text
32
- - [x] Write test for truncateText() with empty string
33
- - [x] Write test for truncateText() with text under limit
34
- - [x] Write test for truncateText() with text over limit
35
- - [x] Write test for formatDate() with ISO date string
36
- - [x] Write test for formatDate() with null/undefined
37
- - [x] Write test for formatBytes() with bytes
38
- - [x] Write test for formatBytes() with kilobytes
39
- - [x] Write test for formatBytes() with megabytes
40
- - [x] Write test for formatBytes() with gigabytes
41
- - [x] Run tests and verify all pass
42
-
43
- - [x] Create `tests/unit/http.test.ts`
44
- - [x] Write test for makeCkanRequest() successful response
45
- - [x] Write test for makeCkanRequest() with error (404)
46
- - [x] Write test for makeCkanRequest() with error (500)
47
- - [x] Write test for makeCkanRequest() with timeout
48
- - [x] Write test for makeCkanRequest() URL normalization (trailing slash)
49
- - [x] Write test for makeCkanRequest() User-Agent header
50
- - [x] Run tests and verify all pass
51
-
52
- ## Phase 4: Integration Tests for Tools
53
-
54
- ### Status Tool
55
- - [x] Create `tests/integration/status.test.ts`
56
- - [x] Write test for ckan_status_show with valid server URL
57
- - [x] Write test for ckan_status_show with invalid URL
58
- - [ ] Write test for ckan_status_show with server error
59
- - [ ] Write test for markdown output format
60
- - [ ] Write test for JSON output format
61
- - [x] Run tests and verify all pass
62
-
63
- ### Package Tools
64
- - [ ] Create `tests/integration/package.test.ts`
65
- - [ ] Write test for ckan_package_search with basic query
66
- - [ ] Write test for ckan_package_search with facets
67
- - [ ] Write test for ckan_package_search with pagination
68
- - [ ] Write test for ckan_package_search with sorting
69
- - [ ] Write test for ckan_package_search with filter query
70
- - [ ] Write test for ckan_package_show with valid package ID
71
- - [ ] Write test for ckan_package_show with invalid package ID
72
- - [ ] Write test for markdown output format
73
- - [ ] Write test for JSON output format
74
- - [ ] Run tests and verify all pass
75
-
76
- ### Organization Tools
77
- - [ ] Create `tests/integration/organization.test.ts`
78
- - [ ] Write test for ckan_organization_list
79
- - [ ] Write test for ckan_organization_list with sorting
80
- - [ ] Write test for ckan_organization_show
81
- - [ ] Write test for ckan_organization_search
82
- - [ ] Write test for markdown output format
83
- - [ ] Write test for JSON output format
84
- - [ ] Run tests and verify all pass
85
-
86
- ### DataStore Tool
87
- - [ ] Create `tests/integration/datastore.test.ts`
88
- - [ ] Write test for ckan_datastore_search with basic query
89
- - [ ] Write test for ckan_datastore_search with filters
90
- - [ ] Write test for ckan_datastore_search with sorting
91
- - [ ] Write test for ckan_datastore_search with pagination
92
- - [ ] Write test for markdown output format
93
- - [ ] Write test for JSON output format
94
- - [ ] Run tests and verify all pass
95
-
96
- ## Phase 5: Validation and Documentation
97
-
98
- - [x] Run `npm test` and verify all tests pass
99
- - [x] Run `npm run test:coverage` and check coverage report
100
- - [ ] Verify coverage meets 80% threshold
101
- - [ ] Update CLAUDE.md with testing instructions
102
- - [ ] Update README.md with test section
103
- - [x] Create test writing guide in tests/README.md
104
- - [ ] Add example test in test writing guide
105
-
106
- ## Phase 6: Continuous Integration
107
-
108
- - [ ] Check if CI/CD exists (GitHub Actions, etc.)
109
- - [ ] Add test step to CI pipeline if exists
110
- - [ ] Add coverage reporting to CI if exists
111
- - [ ] Verify tests run in CI environment
112
- - [ ] Configure coverage upload to service (optional)
113
-
114
- ## Dependencies
115
-
116
- - Phase 1 must complete before Phase 2, 3, 4
117
- - Phase 2 must complete before Phase 4 (fixtures needed)
118
- - Phase 3 and Phase 4 can be done in parallel after Phase 2
119
- - Phase 5 depends on completion of Phase 3 and Phase 4
120
- - Phase 6 is optional and depends on CI infrastructure
121
-
122
- ## Notes
123
-
124
- - Use vi.fn() for mocking axios
125
- - Keep tests focused and readable
126
- - Mock realistic CKAN API responses from actual documentation
127
- - One assertion per test when possible
128
- - Describe expected behavior clearly in test names
129
- - Use describe blocks for grouping related tests
130
- - Use test.only sparingly and remove before committing
131
- - Run tests in watch mode during development: `npm run test:watch`
132
- - Generate coverage report: `npm run test:coverage`
@@ -1,115 +0,0 @@
1
- # Project Context
2
-
3
- ## Purpose
4
- CKAN MCP Server - MCP (Model Context Protocol) server for interacting with open data portals based on CKAN (dati.gov.it, data.gov, demo.ckan.org, etc.).
5
-
6
- Exposes MCP tools for:
7
- - Advanced dataset search with Solr syntax
8
- - DataStore queries for tabular data analysis
9
- - Organization and group exploration
10
- - Complete metadata access
11
-
12
- ## Tech Stack
13
- - **TypeScript** (ES2022 target)
14
- - **Node.js**
15
- - **esbuild** - ultra-fast build system (preferred over tsc for memory efficiency)
16
- - **@modelcontextprotocol/sdk** - official MCP SDK
17
- - **axios** - HTTP client for CKAN API calls
18
- - **zod** - schema validation for tool inputs
19
- - **express** - HTTP server (for HTTP transport mode)
20
-
21
- ## Project Conventions
22
-
23
- ### Code Style
24
- - TypeScript strict mode enabled
25
- - Modular tool files in `src/tools/*`
26
- - Utility functions for reusable operations (makeCkanRequest, truncateText, formatDate)
27
- - Zod schemas for strict input validation (reject extra parameters)
28
- - Italian locale for date formatting (it-IT)
29
- - Markdown output optimized for human readability; JSON available for programmatic use
30
-
31
- ### Architecture Patterns
32
- - **Modular MCP server** - registration in `src/server.ts`
33
- - **Tool-based architecture** - 13 registered MCP tools for CKAN operations
34
- - **Multiple transport modes**:
35
- - stdio (default) - for local MCP client integration
36
- - HTTP - for remote access via POST /mcp endpoint
37
- - Cloudflare Workers - `/mcp` endpoint in `src/worker.ts`
38
- - **Read-only operations** - no data modification on CKAN
39
- - **No caching** - fresh API calls for each request
40
- - **Error handling** - HTTP errors, timeouts, server validation
41
-
42
- ### Testing Strategy
43
- - **Automated tests** with Vitest (integration fixtures)
44
- - Manual testing:
45
- - stdio mode: direct integration testing with Claude Desktop
46
- - HTTP mode: curl-based testing against localhost endpoint
47
- - Build validation via `npm run build` before deployment
48
-
49
- ### Git Workflow
50
- - **Main branch**: `main`
51
- - **Commit style**: extremely concise, prioritize brevity over grammar
52
- - **LOG.md**: date-based entries (YYYY-MM-DD format), most recent at top
53
- - **GitHub operations**: use `gh` CLI exclusively
54
- - Update LOG.md for any significant change
55
-
56
- ## Domain Context
57
-
58
- ### CKAN Knowledge
59
- - **CKAN API v3** - standard API across all CKAN portals
60
- - **Apache Solr** - powers search functionality
61
- - Supports field:value syntax, AND/OR/NOT operators, wildcards, ranges
62
- - Filter queries (fq) for filtering without affecting score
63
- - Facets for statistical aggregations
64
- - Sort and pagination (start/rows)
65
-
66
- ### Output Conventions
67
- - All tools support `format` parameter: `markdown` (default) or `json`
68
- - Output truncated to 50000 characters max (hardcoded)
69
- - Dates formatted in Italian locale
70
- - File sizes in human-readable format
71
- - `server_url` for Italy uses `https://dati.gov.it/opendata`
72
-
73
- ## Important Constraints
74
-
75
- ### Environment
76
- - **WSL considerations** - memory constraints require esbuild instead of tsc
77
- - Always use `npm run build` (esbuild) not `npm run build:tsc`
78
- - esbuild bundles internal modules but keeps external deps as-is
79
-
80
- ### Technical Limits
81
- - 50000 character output limit (hardcoded, could be configurable)
82
- - 30-second timeout for CKAN API calls
83
- - Read-only operations only (security by design)
84
- - No authentication (public endpoints only)
85
- - No caching (trade-off: freshness vs performance)
86
-
87
- ### Build System
88
- - esbuild config: bundles TypeScript, externalizes runtime deps
89
- - External deps must be in node_modules: @modelcontextprotocol/sdk, axios, express, zod
90
- - tsconfig.json mainly for IDE support (esbuild ignores most options)
91
-
92
- ## External Dependencies
93
-
94
- ### CKAN Portals
95
- Major supported portals:
96
- - 🇮🇹 https://dati.gov.it/opendata (Italia)
97
- - 🇺🇸 https://catalog.data.gov (United States)
98
- - 🇨🇦 https://open.canada.ca/data (Canada)
99
- - 🇬🇧 https://data.gov.uk (United Kingdom)
100
- - 🇪🇺 https://data.europa.eu (European Union)
101
- - 🌍 https://demo.ckan.org (Official CKAN demo)
102
-
103
- ### CKAN API Integration
104
- - All requests use axios with 30s timeout
105
- - User-Agent: `CKAN-MCP-Server/1.0`
106
- - URL normalization (remove trailing slash)
107
- - Response validation (success === true)
108
- - Error handling: HTTP errors, timeouts, unreachable servers
109
-
110
- ### Portal Variations
111
- Each CKAN portal may differ in:
112
- - DataStore availability
113
- - Custom dataset fields
114
- - Available organizations and tags
115
- - Supported resource formats
@@ -1,23 +0,0 @@
1
- # ckan-insights Specification
2
-
3
- ## Purpose
4
- Describe dataset insight tools (relevance, freshness, structure) once implemented.
5
- ## Requirements
6
- ### Requirement: Insights capability reserved
7
- The system SHALL maintain this specification to document dataset insight tools when they are added.
8
-
9
- #### Scenario: Insight tools documented
10
- - **WHEN** new insight tools are implemented
11
- - **THEN** their requirements are captured in this specification
12
-
13
- ### Requirement: Find relevant datasets
14
- The system SHALL provide a `ckan_find_relevant_datasets` tool that accepts `server_url`, `query`, `limit`, optional weights for title, notes, tags, and organization, and an optional search parser override, and returns the top N datasets ranked by score with a per-field score breakdown.
15
-
16
- #### Scenario: Ranked results returned
17
- - **WHEN** the tool is invoked with a query and limit
18
- - **THEN** the system uses `package_search` results to return the top N datasets with numeric scores and field contributions
19
-
20
- #### Scenario: Search parser override applied
21
- - **WHEN** the tool is invoked with a search parser override
22
- - **THEN** the system applies the override to the underlying `package_search` query
23
-
@@ -1,16 +0,0 @@
1
- # ckan-search Specification
2
-
3
- ## Purpose
4
- TBD - created by archiving change update-search-parser-config. Update Purpose after archive.
5
- ## Requirements
6
- ### Requirement: Package search parser override
7
- The system SHALL support a per-portal default and a per-request override to force package search queries through the `text` field when needed.
8
-
9
- #### Scenario: Portal default applies
10
- - **WHEN** a portal is configured to force the text-field parser
11
- - **THEN** `ckan_package_search` uses `text:(...)` for non-fielded queries by default
12
-
13
- #### Scenario: Request override applies
14
- - **WHEN** a client explicitly requests the text-field parser
15
- - **THEN** `ckan_package_search` uses `text:(...)` regardless of portal defaults
16
-
@@ -1,344 +0,0 @@
1
- # cloudflare-deployment Specification
2
-
3
- ## Purpose
4
- TBD - created by archiving change add-cloudflare-workers. Update Purpose after archive.
5
- ## Requirements
6
- ### Requirement: Workers Entry Point
7
-
8
- The system SHALL provide a Cloudflare Workers-compatible entry point that handles HTTP requests using the Workers fetch API.
9
-
10
- #### Scenario: Health check endpoint
11
-
12
- - **WHEN** client sends `GET /health` to Workers endpoint
13
- - **THEN** server returns JSON with status, version, tool count, and resource count
14
-
15
- #### Scenario: MCP protocol endpoint
16
-
17
- - **WHEN** client sends `POST /mcp` with JSON-RPC request to Workers endpoint
18
- - **THEN** server processes MCP request and returns JSON-RPC response
19
-
20
- #### Scenario: Invalid route
21
-
22
- - **WHEN** client requests any path other than `/health` or `/mcp`
23
- - **THEN** server returns 404 Not Found
24
-
25
- #### Scenario: Invalid method on MCP endpoint
26
-
27
- - **WHEN** client sends non-POST request to `/mcp`
28
- - **THEN** server returns 404 Not Found
29
-
30
- ---
31
-
32
- ### Requirement: MCP Server Integration
33
-
34
- The system SHALL initialize MCP server instance on each Workers invocation and register all tools and resources.
35
-
36
- #### Scenario: Server initialization
37
-
38
- - **WHEN** Workers receives MCP request
39
- - **THEN** server creates MCP Server instance with name "ckan-mcp-server" and version "0.4.0"
40
-
41
- #### Scenario: Tool registration
42
-
43
- - **WHEN** Workers initializes MCP server
44
- - **THEN** server registers all 7 CKAN tools (package_search, package_show, organization_list, organization_show, organization_search, datastore_search, status_show)
45
-
46
- #### Scenario: Resource registration
47
-
48
- - **WHEN** Workers initializes MCP server
49
- - **THEN** server registers all 3 resource templates (dataset, resource, organization)
50
-
51
- #### Scenario: Tools list request
52
-
53
- - **WHEN** client calls `tools/list` method via Workers endpoint
54
- - **THEN** response includes all 7 registered CKAN tools with descriptions
55
-
56
- ---
57
-
58
- ### Requirement: Web Standards HTTP Client
59
-
60
- The system SHALL use native Web Fetch API for CKAN API requests instead of Node.js-specific libraries.
61
-
62
- #### Scenario: CKAN API request with fetch
63
-
64
- - **WHEN** tool calls `makeCkanRequest()` in Workers runtime
65
- - **THEN** client uses native `fetch()` with 30-second timeout
66
-
67
- #### Scenario: Query parameter encoding
68
-
69
- - **WHEN** CKAN request includes parameters (e.g., `q`, `rows`, `start`)
70
- - **THEN** client encodes parameters in URL using `URLSearchParams`
71
-
72
- #### Scenario: Request timeout
73
-
74
- - **WHEN** CKAN API takes longer than 30 seconds
75
- - **THEN** client aborts request using `AbortController` and returns timeout error
76
-
77
- #### Scenario: HTTP error handling
78
-
79
- - **WHEN** CKAN API returns HTTP error status (4xx, 5xx)
80
- - **THEN** client throws error with status code and message
81
-
82
- #### Scenario: CKAN API validation
83
-
84
- - **WHEN** CKAN API returns 200 OK but `success: false`
85
- - **THEN** client throws error with CKAN error message
86
-
87
- ---
88
-
89
- ### Requirement: Workers Build Configuration
90
-
91
- The system SHALL provide separate build configuration for Workers deployment targeting browser platform with ESM format.
92
-
93
- #### Scenario: Workers build script
94
-
95
- - **WHEN** user runs `npm run build:worker`
96
- - **THEN** esbuild compiles `src/worker.ts` to `dist/worker.js` in ESM format
97
-
98
- #### Scenario: Bundle all dependencies
99
-
100
- - **WHEN** esbuild builds Workers bundle
101
- - **THEN** all dependencies are bundled (no external modules)
102
-
103
- #### Scenario: Platform targeting
104
-
105
- - **WHEN** esbuild builds Workers bundle
106
- - **THEN** platform is set to `browser` and target is `es2022`
107
-
108
- #### Scenario: Output format
109
-
110
- - **WHEN** Workers build completes
111
- - **THEN** output is ESM format (not CommonJS)
112
-
113
- #### Scenario: Bundle size validation
114
-
115
- - **WHEN** Workers build completes
116
- - **THEN** bundle size is less than 1MB (Workers script size limit)
117
-
118
- ---
119
-
120
- ### Requirement: Wrangler Configuration
121
-
122
- The system SHALL provide Wrangler configuration file for Workers deployment and local development.
123
-
124
- #### Scenario: Wrangler configuration file
125
-
126
- - **WHEN** project contains `wrangler.toml` in root directory
127
- - **THEN** configuration specifies name, main entry point, and compatibility date
128
-
129
- #### Scenario: Build command
130
-
131
- - **WHEN** `wrangler deploy` or `wrangler dev` runs
132
- - **THEN** Wrangler executes `npm run build:worker` before deployment
133
-
134
- #### Scenario: Local development server
135
-
136
- - **WHEN** user runs `npm run dev:worker`
137
- - **THEN** Wrangler starts local Workers server on http://localhost:8787
138
-
139
- ---
140
-
141
- ### Requirement: Workers Deployment
142
-
143
- The system SHALL deploy to Cloudflare Workers and provide public HTTPS endpoint.
144
-
145
- #### Scenario: Deploy to Workers
146
-
147
- - **WHEN** user runs `npm run deploy`
148
- - **THEN** Wrangler builds and uploads worker to Cloudflare
149
-
150
- #### Scenario: Public endpoint
151
-
152
- - **WHEN** deployment succeeds
153
- - **THEN** Workers script is accessible at `https://ckan-mcp-server.<account>.workers.dev`
154
-
155
- #### Scenario: HTTPS support
156
-
157
- - **WHEN** client accesses Workers endpoint
158
- - **THEN** connection uses HTTPS with valid certificate
159
-
160
- ---
161
-
162
- ### Requirement: Tool Functionality Preservation
163
-
164
- The system SHALL maintain identical functionality for all CKAN tools in Workers runtime compared to Node.js runtime.
165
-
166
- #### Scenario: Package search in Workers
167
-
168
- - **WHEN** client calls `ckan_package_search` via Workers endpoint
169
- - **THEN** response is identical to Node.js runtime response
170
-
171
- #### Scenario: Datastore query in Workers
172
-
173
- - **WHEN** client calls `ckan_datastore_search` via Workers endpoint
174
- - **THEN** response is identical to Node.js runtime response
175
-
176
- #### Scenario: Resource template in Workers
177
-
178
- - **WHEN** client reads `ckan://{server}/dataset/{id}` via Workers
179
- - **THEN** response is identical to Node.js runtime response
180
-
181
- #### Scenario: Error handling in Workers
182
-
183
- - **WHEN** CKAN API is unreachable in Workers runtime
184
- - **THEN** error response matches Node.js runtime error format
185
-
186
- ---
187
-
188
- ### Requirement: Response Format Compatibility
189
-
190
- The system SHALL support both markdown and JSON output formats in Workers runtime.
191
-
192
- #### Scenario: Markdown format
193
-
194
- - **WHEN** client requests tool with `response_format: "markdown"`
195
- - **THEN** Workers returns formatted markdown text
196
-
197
- #### Scenario: JSON format
198
-
199
- - **WHEN** client requests tool with `response_format: "json"`
200
- - **THEN** Workers returns raw JSON data
201
-
202
- #### Scenario: Character limit
203
-
204
- - **WHEN** response exceeds CHARACTER_LIMIT (50000 characters)
205
- - **THEN** Workers truncates response identically to Node.js runtime
206
-
207
- ---
208
-
209
- ### Requirement: Error Handling
210
-
211
- The system SHALL handle Workers-specific errors gracefully with JSON-RPC error responses.
212
-
213
- #### Scenario: Malformed JSON-RPC request
214
-
215
- - **WHEN** client sends invalid JSON to `/mcp` endpoint
216
- - **THEN** Workers returns JSON-RPC error with code -32700 (Parse error)
217
-
218
- #### Scenario: Internal worker error
219
-
220
- - **WHEN** worker encounters unexpected exception
221
- - **THEN** Workers returns JSON-RPC error with code -32603 (Internal error)
222
-
223
- #### Scenario: Method not found
224
-
225
- - **WHEN** client calls non-existent MCP method
226
- - **THEN** Workers returns JSON-RPC error with code -32601 (Method not found)
227
-
228
- ---
229
-
230
- ### Requirement: CORS Support
231
-
232
- The system SHALL include CORS headers to enable browser-based MCP clients.
233
-
234
- #### Scenario: CORS headers on success
235
-
236
- - **WHEN** Workers returns successful response
237
- - **THEN** response includes `Access-Control-Allow-Origin: *` header
238
-
239
- #### Scenario: CORS headers on error
240
-
241
- - **WHEN** Workers returns error response
242
- - **THEN** response includes `Access-Control-Allow-Origin: *` header
243
-
244
- #### Scenario: Preflight request
245
-
246
- - **WHEN** browser sends OPTIONS request for CORS preflight
247
- - **THEN** Workers returns allowed methods and headers
248
-
249
- ---
250
-
251
- ### Requirement: Deployment Documentation
252
-
253
- The system SHALL provide comprehensive documentation for deploying to Cloudflare Workers.
254
-
255
- #### Scenario: Deployment guide
256
-
257
- - **WHEN** contributor wants to deploy Workers instance
258
- - **THEN** `docs/DEPLOYMENT.md` provides step-by-step instructions
259
-
260
- #### Scenario: Prerequisites documentation
261
-
262
- - **WHEN** contributor reads DEPLOYMENT.md
263
- - **THEN** document lists all prerequisites (Cloudflare account, wrangler CLI)
264
-
265
- #### Scenario: Troubleshooting guide
266
-
267
- - **WHEN** deployment fails
268
- - **THEN** DEPLOYMENT.md includes common errors and solutions
269
-
270
- #### Scenario: README update
271
-
272
- - **WHEN** user reads README.md
273
- - **THEN** deployment options section includes Cloudflare Workers option
274
-
275
- ---
276
-
277
- ### Requirement: Backwards Compatibility
278
-
279
- The system SHALL maintain all existing deployment modes (stdio, self-hosted HTTP) without breaking changes.
280
-
281
- #### Scenario: Stdio mode unchanged
282
-
283
- - **WHEN** user runs `npm start` after Workers implementation
284
- - **THEN** stdio transport works identically to pre-Workers version
285
-
286
- #### Scenario: Self-hosted HTTP mode unchanged
287
-
288
- - **WHEN** user runs `TRANSPORT=http PORT=3000 npm start` after Workers implementation
289
- - **THEN** HTTP server works identically to pre-Workers version
290
-
291
- #### Scenario: Existing tests pass
292
-
293
- - **WHEN** user runs `npm test` after Workers implementation
294
- - **THEN** all 113 existing tests pass without modification
295
-
296
- #### Scenario: Node.js bundle unchanged
297
-
298
- - **WHEN** user runs `npm run build` after Workers implementation
299
- - **THEN** Node.js bundle (`dist/index.js`) is unchanged
300
-
301
- ---
302
-
303
- ### Requirement: Development Workflow
304
-
305
- The system SHALL support efficient local development and testing of Workers deployment.
306
-
307
- #### Scenario: Local Workers testing
308
-
309
- - **WHEN** developer runs `npm run dev:worker`
310
- - **THEN** wrangler starts local server with hot reload
311
-
312
- #### Scenario: Quick iteration
313
-
314
- - **WHEN** developer modifies `src/worker.ts`
315
- - **THEN** wrangler automatically rebuilds and reloads
316
-
317
- #### Scenario: curl testing
318
-
319
- - **WHEN** developer sends curl request to local Workers
320
- - **THEN** response matches expected MCP protocol format
321
-
322
- ---
323
-
324
- ### Requirement: Monitoring and Debugging
325
-
326
- The system SHALL provide access to Workers logs and metrics for troubleshooting.
327
-
328
- #### Scenario: Real-time logs
329
-
330
- - **WHEN** developer runs `wrangler tail`
331
- - **THEN** console.log output from worker appears in terminal
332
-
333
- #### Scenario: Error logs
334
-
335
- - **WHEN** worker throws exception
336
- - **THEN** stack trace appears in `wrangler tail` output
337
-
338
- #### Scenario: Cloudflare dashboard
339
-
340
- - **WHEN** user accesses Cloudflare Workers dashboard
341
- - **THEN** metrics show request count, error rate, and CPU time
342
-
343
- ---
344
-
@@ -1,32 +0,0 @@
1
- # documentation-language Specification
2
-
3
- ## Purpose
4
- TBD - created by archiving change translate-project-to-english. Update Purpose after archive.
5
- ## Requirements
6
- ### Requirement: Project documentation in English
7
-
8
- The project SHALL provide all user-facing documentation in English to ensure accessibility for the international open data community.
9
-
10
- #### Scenario: English documentation
11
- Given a CKAN MCP Server project
12
- When a user reads the documentation
13
- Then the documentation is in English
14
- And code examples are in English
15
- And technical terms follow CKAN API terminology
16
-
17
- ### Requirement: Preserve multilingual examples
18
-
19
- The project SHALL preserve non-English portal names, organization titles, or data values in their original language to accurately reflect real-world CKAN portals.
20
-
21
- #### Scenario: Italian portal example
22
- Given an example using dati.gov.it
23
- When the example references Italian organizations
24
- Then organization names remain in Italian (e.g., "Regione Siciliana")
25
- And descriptions are in English
26
-
27
- #### Scenario: Non-English data values
28
- Given an example query with data filters
29
- When the data contains non-English values
30
- Then those values are preserved in their original language
31
- And the surrounding documentation explains the context in English
32
-
@@ -1,26 +0,0 @@
1
- # mcp-prompts Specification
2
-
3
- ## Purpose
4
- TBD - created by archiving change add-mcp-prompts. Update Purpose after archive.
5
- ## Requirements
6
- ### Requirement: Guided prompts are available
7
- The system SHALL expose a set of guided MCP prompts for common CKAN discovery workflows.
8
-
9
- #### Scenario: User requests a guided search prompt
10
- - **WHEN** a client lists MCP prompts
11
- - **THEN** the guided prompts are returned with name, description, and parameters
12
-
13
- ### Requirement: Prompt output includes tool usage instructions
14
- Each guided prompt SHALL produce instructions that reference the appropriate CKAN tools and parameters.
15
-
16
- #### Scenario: Prompt generation for thematic search
17
- - **WHEN** the user generates a prompt for a specific theme and format
18
- - **THEN** the output includes the correct tool name and required parameters
19
-
20
- ### Requirement: Prompt content is localized and consistent
21
- Guided prompts SHALL use consistent language and parameter naming aligned with CKAN tool schemas.
22
-
23
- #### Scenario: Prompt content consistency
24
- - **WHEN** a prompt is generated
25
- - **THEN** parameter names match the tool schema (e.g., `server_url`, `q`, `fq`, `rows`)
26
-