@aborruso/ckan-mcp-server 0.4.17 → 0.4.18

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 +59 -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,12 +0,0 @@
1
- ## 1. Implementation
2
- - [ ] Add allowlist parsing utility for `ALLOWED_CKAN_HOSTS` (comma-separated hostnames, case-insensitive, trim whitespace).
3
- - [ ] Enforce allowlist for all CKAN requests (tools and resource templates) with clear error messaging.
4
- - [ ] Ensure allowlist applies to both Node and Workers runtimes.
5
-
6
- ## 2. Configuration
7
- - [ ] Add `ALLOWED_CKAN_HOSTS` to `wrangler.toml` with example values.
8
- - [ ] Update docs/README to describe the env var and behavior (optional if required by spec).
9
-
10
- ## 3. Tests
11
- - [ ] Add unit tests for allowlist parsing and validation.
12
- - [ ] Add tool/resource tests verifying rejection for non-allowed hosts when env var is set.
@@ -1,12 +0,0 @@
1
- # Change: Escape text-field query wrapping in search parser
2
-
3
- ## Why
4
- Wrapping arbitrary user input in `text:(...)` without escaping allows query parser errors or unintended semantics when the input contains Solr/Lucene metacharacters (e.g., `"` or `)`).
5
-
6
- ## What Changes
7
- - Escape Solr/Lucene special characters before wrapping user input in `text:(...)`.
8
- - Add tests to confirm escaped output and prevent regressions.
9
-
10
- ## Impact
11
- - Affected specs: `ckan-search`
12
- - Affected code: `src/utils/search.ts`, package search tool behavior, related tests.
@@ -1,11 +0,0 @@
1
- ## MODIFIED Requirements
2
- ### Requirement: Package search parser override
3
- The system SHALL support a per-portal default and a per-request override to force package search queries through the `text` field when needed, and SHALL escape Solr/Lucene special characters when wrapping queries in `text:(...)`.
4
-
5
- #### Scenario: Portal default applies
6
- - **WHEN** a portal is configured to force the text-field parser
7
- - **THEN** `ckan_package_search` uses `text:(...)` for non-fielded queries by default with escaped query content
8
-
9
- #### Scenario: Request override applies
10
- - **WHEN** a client explicitly requests the text-field parser
11
- - **THEN** `ckan_package_search` uses `text:(...)` regardless of portal defaults with escaped query content
@@ -1,8 +0,0 @@
1
- ## 1. Implementation
2
- - [x] Add a Solr/Lucene escaping helper for text-field queries.
3
- - [x] Apply escaping when `resolveSearchQuery` forces `text:(...)`.
4
- - [x] Ensure behavior is unchanged when not forcing the text parser.
5
-
6
- ## 2. Tests
7
- - [x] Add unit tests for escaping behavior (quotes, parentheses, backslashes, colons).
8
- - [x] Add tests to cover `resolveSearchQuery` effectiveQuery output with forced text parser.
@@ -1,21 +0,0 @@
1
- # Change: Add MQA Quality Score Tool for dati.gov.it
2
-
3
- ## Why
4
- Datasets on dati.gov.it display quality scores (Eccellente, Buono, etc.) calculated by data.europa.eu's MQA (Metadata Quality Assurance) system. Currently there's no way to access these quality metrics through the MCP server, limiting users' ability to evaluate dataset quality programmatically.
5
-
6
- ## What Changes
7
- - Add `ckan_get_mqa_quality` tool for retrieving quality metrics from data.europa.eu
8
- - Tool works only with dati.gov.it server (validated at runtime)
9
- - Fetches dataset identifier from CKAN, then queries MQA API
10
- - Returns quality score and detailed metrics (accessibility, reusability, interoperability, findability)
11
- - Supports both markdown and JSON output formats
12
-
13
- ## Impact
14
- - Affected specs: New capability `ckan-quality`
15
- - Affected code:
16
- - New file: `src/tools/quality.ts` (tool handler)
17
- - New file: `tests/integration/quality.test.ts` (tests with mocked responses)
18
- - New file: `tests/fixtures/responses/mqa-quality.json` (mock data)
19
- - Modified: `src/server.ts` (register new tool)
20
- - Modified: `README.md` (document new tool)
21
- - Modified: `EXAMPLES.md` (add usage examples)
@@ -1,71 +0,0 @@
1
- ## ADDED Requirements
2
-
3
- ### Requirement: MQA Quality Score Retrieval
4
- The system SHALL provide a tool to retrieve MQA (Metadata Quality Assurance) quality metrics from data.europa.eu for datasets published on dati.gov.it.
5
-
6
- #### Scenario: Successful quality score retrieval
7
- - **GIVEN** a valid dataset ID from dati.gov.it
8
- - **WHEN** user requests quality metrics
9
- - **THEN** system SHALL fetch identifier field from CKAN package_show
10
- - **AND** system SHALL query data.europa.eu MQA API
11
- - **AND** system SHALL return quality score and detailed metrics (accessibility, reusability, interoperability, findability)
12
-
13
- #### Scenario: Identifier fallback to name
14
- - **GIVEN** a dataset with empty identifier field
15
- - **WHEN** user requests quality metrics
16
- - **THEN** system SHALL use the name field as fallback identifier for MQA API query
17
-
18
- #### Scenario: Dataset not found
19
- - **GIVEN** an invalid or non-existent dataset ID
20
- - **WHEN** user requests quality metrics
21
- - **THEN** system SHALL return clear error message indicating dataset not found
22
-
23
- #### Scenario: MQA API unavailable
24
- - **GIVEN** data.europa.eu MQA API is unavailable or returns error
25
- - **WHEN** user requests quality metrics
26
- - **THEN** system SHALL return clear error message indicating MQA service unavailability
27
-
28
- ### Requirement: Server Validation
29
- The system SHALL restrict MQA quality queries to dati.gov.it server only.
30
-
31
- #### Scenario: Valid dati.gov.it server
32
- - **GIVEN** server_url is "https://www.dati.gov.it/opendata" or "https://dati.gov.it/opendata"
33
- - **WHEN** user requests quality metrics
34
- - **THEN** system SHALL proceed with MQA query
35
-
36
- #### Scenario: Invalid server URL
37
- - **GIVEN** server_url is not dati.gov.it (e.g., "https://catalog.data.gov")
38
- - **WHEN** user requests quality metrics
39
- - **THEN** system SHALL reject request with error message explaining MQA is only available for dati.gov.it
40
-
41
- ### Requirement: Output Formats
42
- The system SHALL support both markdown and JSON output formats for quality metrics.
43
-
44
- #### Scenario: Markdown format (default)
45
- - **GIVEN** user does not specify response_format or specifies "markdown"
46
- - **WHEN** quality metrics are retrieved
47
- - **THEN** system SHALL return human-readable markdown with:
48
- - Overall quality score
49
- - Breakdown by dimension (accessibility, reusability, interoperability, findability)
50
- - Key findings and recommendations
51
-
52
- #### Scenario: JSON format
53
- - **GIVEN** user specifies response_format as "json"
54
- - **WHEN** quality metrics are retrieved
55
- - **THEN** system SHALL return complete MQA API response as structured JSON
56
-
57
- ### Requirement: Tool Parameters
58
- The system SHALL accept the following parameters for the MQA quality tool:
59
- - server_url (required): Base URL of dati.gov.it portal
60
- - dataset_id (required): Dataset ID or name
61
- - response_format (optional): "markdown" (default) or "json"
62
-
63
- #### Scenario: Minimal parameters
64
- - **GIVEN** user provides only server_url and dataset_id
65
- - **WHEN** tool is invoked
66
- - **THEN** system SHALL use default markdown format
67
-
68
- #### Scenario: All parameters specified
69
- - **GIVEN** user provides server_url, dataset_id, and response_format
70
- - **WHEN** tool is invoked
71
- - **THEN** system SHALL use specified format for output
@@ -1,29 +0,0 @@
1
- # Implementation Tasks
2
-
3
- ## 1. Core Implementation
4
- - [x] 1.1 Create `src/tools/quality.ts` with `ckan_get_mqa_quality` tool handler
5
- - [x] 1.2 Implement server URL validation (dati.gov.it only)
6
- - [x] 1.3 Add CKAN package_show call to extract identifier field
7
- - [x] 1.4 Add MQA API client (https://data.europa.eu/api/mqa/cache/datasets/{id})
8
- - [x] 1.5 Implement markdown and JSON formatters for quality metrics
9
- - [x] 1.6 Register tool in `src/server.ts`
10
-
11
- ## 2. Testing
12
- - [x] 2.1 Create mock fixtures for CKAN package_show response
13
- - [x] 2.2 Create mock fixtures for MQA API response
14
- - [x] 2.3 Write integration tests for successful quality retrieval
15
- - [x] 2.4 Write tests for error scenarios (invalid server, dataset not found, MQA API unavailable)
16
- - [x] 2.5 Write tests for fallback from identifier to name field
17
- - [x] 2.6 Verify test coverage matches project standards
18
-
19
- ## 3. Documentation
20
- - [x] 3.1 Add tool description to README.md
21
- - [x] 3.2 Add usage examples to EXAMPLES.md
22
- - [x] 3.3 Document server restriction (dati.gov.it only)
23
- - [x] 3.4 Document quality metrics structure (score, accessibility, reusability, interoperability, findability)
24
-
25
- ## 4. Validation
26
- - [x] 4.1 Run full test suite (npm test) - 212 tests passing
27
- - [x] 4.2 Test manually with real dati.gov.it dataset
28
- - [x] 4.3 Verify error handling for non-dati.gov.it servers
29
- - [x] 4.4 Build project successfully (npm run build)
@@ -1,115 +0,0 @@
1
- # Design: MCP Resource Templates
2
-
3
- ## Context
4
-
5
- MCP protocol supports two primitives:
6
- - **Tools**: Functions that perform actions (current implementation)
7
- - **Resources**: Data that can be read directly (to be added)
8
-
9
- The `@modelcontextprotocol/sdk` provides `server.registerResourceTemplate()` for dynamic resources with URI templates.
10
-
11
- ## Goals / Non-Goals
12
-
13
- ### Goals
14
- - Expose CKAN data as MCP resources using `ckan://` URI scheme
15
- - Support dataset, resource, and organization access
16
- - Reuse existing `makeCkanRequest()` for CKAN API calls
17
- - Maintain consistency with tool output formats
18
-
19
- ### Non-Goals
20
- - Write operations (resources are read-only by design)
21
- - Caching implementation (defer to future enhancement)
22
- - Authentication support (public endpoints only, same as tools)
23
- - Real-time subscriptions (defer to future enhancement)
24
-
25
- ## Decisions
26
-
27
- ### URI Scheme Design
28
-
29
- **Decision**: Use `ckan://{server}/type/{id}` pattern
30
-
31
- ```
32
- ckan://dati.gov.it/dataset/vaccini-covid
33
- ckan://data.gov/resource/abc-123
34
- ckan://demo.ckan.org/organization/sample-org
35
- ```
36
-
37
- **Rationale**:
38
- - Server in hostname position enables multi-server support
39
- - Type in path makes intent clear
40
- - ID as final segment matches REST conventions
41
-
42
- **Alternatives considered**:
43
- 1. `ckan://dataset/{server}/{id}` - rejected: server as path segment is unusual
44
- 2. `ckan+https://{server}/...` - rejected: overly complex
45
- 3. Query parameters `ckan://data?server=...&id=...` - rejected: less readable
46
-
47
- ### Module Structure
48
-
49
- **Decision**: Create `src/resources/` directory with one file per resource type
50
-
51
- ```
52
- src/resources/
53
- ├── index.ts # Export registerAllResources()
54
- ├── dataset.ts # ckan://{server}/dataset/{id}
55
- ├── resource.ts # ckan://{server}/resource/{id}
56
- └── organization.ts # ckan://{server}/organization/{name}
57
- ```
58
-
59
- **Rationale**: Mirrors existing `src/tools/` structure for consistency.
60
-
61
- ### URI Parsing
62
-
63
- **Decision**: Extract server from URI hostname, type and ID from path
64
-
65
- ```typescript
66
- function parseResourceUri(uri: URL): { server: string; type: string; id: string } {
67
- const server = uri.hostname;
68
- const [, type, id] = uri.pathname.split('/');
69
- return { server: `https://${server}`, type, id };
70
- }
71
- ```
72
-
73
- **Rationale**: Simple parsing, assumes HTTPS (most CKAN servers use it).
74
-
75
- ### Response Format
76
-
77
- **Decision**: Return JSON by default (no markdown option for resources)
78
-
79
- **Rationale**:
80
- - Resources are meant for programmatic access
81
- - LLMs can interpret JSON directly
82
- - Keeps implementation simple
83
- - Tools still support markdown for interactive use
84
-
85
- ## Risks / Trade-offs
86
-
87
- | Risk | Mitigation |
88
- |------|------------|
89
- | SDK API changes | Pin SDK version, test before updates |
90
- | URI parsing edge cases | Validate URIs before processing |
91
- | Large responses | Apply existing `CHARACTER_LIMIT` truncation |
92
- | Server unreachable | Same error handling as tools |
93
-
94
- ## Migration Plan
95
-
96
- 1. Add resources alongside existing tools (no breaking changes)
97
- 2. Resources are additive - tools remain fully functional
98
- 3. No migration needed for existing users
99
-
100
- ## Implementation Sequence
101
-
102
- 1. Create `src/resources/` directory structure
103
- 2. Implement URI parsing utility
104
- 3. Implement dataset resource template
105
- 4. Implement resource resource template
106
- 5. Implement organization resource template
107
- 6. Register resources in `src/index.ts`
108
- 7. Add tests for resource handlers
109
- 8. Update documentation
110
-
111
- ## Open Questions
112
-
113
- 1. Should resources support `response_format` parameter like tools?
114
- 2. Should we add `ckan://{server}/search?q=...` for search results as resource?
115
- 3. How to handle CKAN servers that require `www.` prefix (e.g., dati.gov.it)?
@@ -1,52 +0,0 @@
1
- # Change: Add MCP Resource Templates
2
-
3
- ## Why
4
-
5
- MCP has two primitives for exposing data: **Tools** (functions) and **Resources** (data). Currently we only expose tools. Adding resources enables:
6
-
7
- 1. Direct data access without tool calls
8
- 2. Native caching and subscription support
9
- 3. Better LLM context injection
10
- 4. Alignment with MCP best practices (see Data.gov MCP server pattern)
11
-
12
- ## What Changes
13
-
14
- - Add MCP Resource Templates using RFC 6570 URI syntax
15
- - Implement `ckan://` URI scheme for dataset and resource access
16
- - Create new module `src/resources/` for resource handlers
17
- - Register resources alongside existing tools
18
-
19
- **New URI templates**:
20
- - `ckan://{server}/dataset/{id}` - Dataset metadata
21
- - `ckan://{server}/resource/{id}` - Resource metadata and download URL
22
- - `ckan://{server}/organization/{name}` - Organization details
23
-
24
- ## Impact
25
-
26
- - Affected specs: New capability `mcp-resources`
27
- - Affected code:
28
- - `src/index.ts` - import and register resources
29
- - `src/resources/` - new directory with resource handlers
30
- - `src/utils/http.ts` - may need minor adjustments
31
- - No breaking changes to existing tools
32
- - Dependencies: No new dependencies required
33
-
34
- ## Benefits
35
-
36
- | Aspect | Current (Tools) | With Resources |
37
- |--------|-----------------|----------------|
38
- | Data access | Tool call required | Direct read |
39
- | Caching | Manual | MCP native |
40
- | Subscriptions | Not supported | Supported |
41
- | Context loading | Via tool results | Direct injection |
42
-
43
- ## Risks
44
-
45
- - **URI parsing complexity**: Need to handle `ckan://` scheme correctly
46
- - **Error handling**: Different pattern than tools
47
- - **Testing**: New test patterns needed for resources
48
-
49
- ## References
50
-
51
- - [MCP Resources Specification](https://modelcontextprotocol.io/specification/2025-11-25)
52
- - [Data.gov MCP Server](https://skywork.ai/skypage/en/unlocking-government-data-mcp-server/1980445961155629056) - uses `datagov://` scheme
@@ -1,92 +0,0 @@
1
- # MCP Resources Capability
2
-
3
- ## ADDED Requirements
4
-
5
- ### Requirement: Dataset Resource Template
6
-
7
- The system SHALL expose a resource template for accessing CKAN dataset metadata via the URI pattern `ckan://{server}/dataset/{id}`.
8
-
9
- #### Scenario: Read dataset metadata successfully
10
-
11
- - **WHEN** client reads `ckan://dati.gov.it/dataset/vaccini-covid`
12
- - **THEN** server returns JSON with complete dataset metadata including title, description, resources, organization, tags
13
-
14
- #### Scenario: Dataset not found
15
-
16
- - **WHEN** client reads `ckan://demo.ckan.org/dataset/nonexistent-id`
17
- - **THEN** server returns error indicating dataset not found
18
-
19
- #### Scenario: Server unreachable
20
-
21
- - **WHEN** client reads `ckan://invalid-server.example/dataset/test`
22
- - **THEN** server returns error indicating server unreachable
23
-
24
- ### Requirement: Resource Resource Template
25
-
26
- The system SHALL expose a resource template for accessing CKAN resource metadata via the URI pattern `ckan://{server}/resource/{id}`.
27
-
28
- #### Scenario: Read resource metadata successfully
29
-
30
- - **WHEN** client reads `ckan://dati.gov.it/resource/abc-123-def`
31
- - **THEN** server returns JSON with resource metadata including name, format, URL, size, and download link
32
-
33
- #### Scenario: Resource not found
34
-
35
- - **WHEN** client reads `ckan://demo.ckan.org/resource/invalid-id`
36
- - **THEN** server returns error indicating resource not found
37
-
38
- ### Requirement: Organization Resource Template
39
-
40
- The system SHALL expose a resource template for accessing CKAN organization metadata via the URI pattern `ckan://{server}/organization/{name}`.
41
-
42
- #### Scenario: Read organization metadata successfully
43
-
44
- - **WHEN** client reads `ckan://dati.gov.it/organization/regione-toscana`
45
- - **THEN** server returns JSON with organization metadata including title, description, and dataset count
46
-
47
- #### Scenario: Organization not found
48
-
49
- - **WHEN** client reads `ckan://demo.ckan.org/organization/nonexistent-org`
50
- - **THEN** server returns error indicating organization not found
51
-
52
- ### Requirement: URI Scheme Parsing
53
-
54
- The system SHALL parse `ckan://` URIs extracting server hostname and path components.
55
-
56
- #### Scenario: Parse standard URI
57
-
58
- - **WHEN** URI is `ckan://dati.gov.it/dataset/test-id`
59
- - **THEN** server extracts: server=`https://dati.gov.it`, type=`dataset`, id=`test-id`
60
-
61
- #### Scenario: Parse URI with www prefix
62
-
63
- - **WHEN** URI is `ckan://www.dati.gov.it/dataset/test-id`
64
- - **THEN** server extracts: server=`https://www.dati.gov.it`, type=`dataset`, id=`test-id`
65
-
66
- #### Scenario: Reject malformed URI
67
-
68
- - **WHEN** URI is `ckan://invalid` (missing path)
69
- - **THEN** server returns validation error
70
-
71
- ### Requirement: Resource Response Format
72
-
73
- The system SHALL return resource content as JSON with standard MCP resource response structure.
74
-
75
- #### Scenario: JSON response structure
76
-
77
- - **WHEN** client reads any valid resource URI
78
- - **THEN** response contains `contents` array with `uri`, `mimeType` (application/json), and `text` (JSON string)
79
-
80
- #### Scenario: Large response truncation
81
-
82
- - **WHEN** resource content exceeds CHARACTER_LIMIT
83
- - **THEN** response is truncated to CHARACTER_LIMIT with truncation indicator
84
-
85
- ### Requirement: Resource Discovery
86
-
87
- The system SHALL list available resource templates when client requests resource list.
88
-
89
- #### Scenario: List resource templates
90
-
91
- - **WHEN** client calls `resources/listTemplates`
92
- - **THEN** server returns list of available URI templates with descriptions
@@ -1,56 +0,0 @@
1
- # Tasks: Add MCP Resource Templates
2
-
3
- ## 1. Setup
4
-
5
- - [x] 1.1 Create `src/resources/` directory
6
- - [x] 1.2 Create `src/resources/index.ts` with `registerAllResources()` export
7
-
8
- ## 2. URI Utilities
9
-
10
- - [x] 2.1 Create URI parsing function for `ckan://` scheme
11
- - [x] 2.2 Add validation for malformed URIs
12
- - [x] 2.3 Handle edge cases (www prefix, trailing slashes)
13
-
14
- ## 3. Dataset Resource
15
-
16
- - [x] 3.1 Create `src/resources/dataset.ts`
17
- - [x] 3.2 Register template `ckan://{server}/dataset/{id}`
18
- - [x] 3.3 Implement handler using `makeCkanRequest('package_show')`
19
- - [x] 3.4 Return JSON response with dataset metadata
20
-
21
- ## 4. Resource Resource
22
-
23
- - [x] 4.1 Create `src/resources/resource.ts`
24
- - [x] 4.2 Register template `ckan://{server}/resource/{id}`
25
- - [x] 4.3 Implement handler using `makeCkanRequest('resource_show')`
26
- - [x] 4.4 Include download URL in response
27
-
28
- ## 5. Organization Resource
29
-
30
- - [x] 5.1 Create `src/resources/organization.ts`
31
- - [x] 5.2 Register template `ckan://{server}/organization/{name}`
32
- - [x] 5.3 Implement handler using `makeCkanRequest('organization_show')`
33
- - [x] 5.4 Return JSON response with organization metadata
34
-
35
- ## 6. Integration
36
-
37
- - [x] 6.1 Import `registerAllResources` in `src/index.ts`
38
- - [x] 6.2 Call `registerAllResources(server)` after tool registration
39
- - [x] 6.3 Build and verify no compilation errors
40
-
41
- ## 7. Testing
42
-
43
- - [x] 7.1 Create `tests/integration/resources.test.ts`
44
- - [x] 7.2 Add tests for dataset resource template
45
- - [x] 7.3 Add tests for resource resource template
46
- - [x] 7.4 Add tests for organization resource template
47
- - [x] 7.5 Add tests for URI parsing edge cases
48
- - [x] 7.6 Add tests for error handling (invalid URI, server errors)
49
- - [x] 7.7 Run full test suite, ensure 100% pass
50
-
51
- ## 8. Documentation
52
-
53
- - [x] 8.1 Update README.md with resource templates section
54
- - [x] 8.2 Update CLAUDE.md architecture section
55
- - [x] 8.3 Add examples to EXAMPLES.md (deferred - basic examples in README)
56
- - [x] 8.4 Update LOG.md with changes