coalesce-transform-mcp 0.1.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.
- package/LICENSE +21 -0
- package/README.md +304 -0
- package/dist/cache-dir.d.ts +26 -0
- package/dist/cache-dir.js +106 -0
- package/dist/client.d.ts +25 -0
- package/dist/client.js +212 -0
- package/dist/coalesce/api/environments.d.ts +20 -0
- package/dist/coalesce/api/environments.js +15 -0
- package/dist/coalesce/api/git-accounts.d.ts +21 -0
- package/dist/coalesce/api/git-accounts.js +21 -0
- package/dist/coalesce/api/jobs.d.ts +25 -0
- package/dist/coalesce/api/jobs.js +21 -0
- package/dist/coalesce/api/nodes.d.ts +29 -0
- package/dist/coalesce/api/nodes.js +33 -0
- package/dist/coalesce/api/projects.d.ts +22 -0
- package/dist/coalesce/api/projects.js +25 -0
- package/dist/coalesce/api/runs.d.ts +19 -0
- package/dist/coalesce/api/runs.js +34 -0
- package/dist/coalesce/api/subgraphs.d.ts +20 -0
- package/dist/coalesce/api/subgraphs.js +17 -0
- package/dist/coalesce/api/users.d.ts +30 -0
- package/dist/coalesce/api/users.js +31 -0
- package/dist/coalesce/types.d.ts +298 -0
- package/dist/coalesce/types.js +746 -0
- package/dist/generated/.gitkeep +0 -0
- package/dist/generated/node-type-corpus.json +42656 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +10 -0
- package/dist/mcp/cache.d.ts +3 -0
- package/dist/mcp/cache.js +137 -0
- package/dist/mcp/environments.d.ts +3 -0
- package/dist/mcp/environments.js +61 -0
- package/dist/mcp/git-accounts.d.ts +3 -0
- package/dist/mcp/git-accounts.js +70 -0
- package/dist/mcp/jobs.d.ts +3 -0
- package/dist/mcp/jobs.js +77 -0
- package/dist/mcp/node-type-corpus.d.ts +3 -0
- package/dist/mcp/node-type-corpus.js +173 -0
- package/dist/mcp/nodes.d.ts +3 -0
- package/dist/mcp/nodes.js +341 -0
- package/dist/mcp/pipelines.d.ts +3 -0
- package/dist/mcp/pipelines.js +342 -0
- package/dist/mcp/projects.d.ts +3 -0
- package/dist/mcp/projects.js +70 -0
- package/dist/mcp/repo-node-types.d.ts +135 -0
- package/dist/mcp/repo-node-types.js +387 -0
- package/dist/mcp/runs.d.ts +3 -0
- package/dist/mcp/runs.js +92 -0
- package/dist/mcp/subgraphs.d.ts +3 -0
- package/dist/mcp/subgraphs.js +60 -0
- package/dist/mcp/users.d.ts +3 -0
- package/dist/mcp/users.js +107 -0
- package/dist/prompts/index.d.ts +2 -0
- package/dist/prompts/index.js +58 -0
- package/dist/resources/context/aggregation-patterns.md +145 -0
- package/dist/resources/context/data-engineering-principles.md +183 -0
- package/dist/resources/context/hydrated-metadata.md +92 -0
- package/dist/resources/context/id-discovery.md +64 -0
- package/dist/resources/context/intelligent-node-configuration.md +162 -0
- package/dist/resources/context/node-creation-decision-tree.md +156 -0
- package/dist/resources/context/node-operations.md +316 -0
- package/dist/resources/context/node-payloads.md +114 -0
- package/dist/resources/context/node-type-corpus.md +166 -0
- package/dist/resources/context/node-type-selection-guide.md +96 -0
- package/dist/resources/context/overview.md +135 -0
- package/dist/resources/context/pipeline-workflows.md +355 -0
- package/dist/resources/context/run-operations.md +55 -0
- package/dist/resources/context/sql-bigquery.md +41 -0
- package/dist/resources/context/sql-databricks.md +40 -0
- package/dist/resources/context/sql-platform-selection.md +70 -0
- package/dist/resources/context/sql-snowflake.md +43 -0
- package/dist/resources/context/storage-mappings.md +49 -0
- package/dist/resources/context/tool-usage.md +98 -0
- package/dist/resources/index.d.ts +5 -0
- package/dist/resources/index.js +254 -0
- package/dist/schemas/node-payloads.d.ts +5019 -0
- package/dist/schemas/node-payloads.js +147 -0
- package/dist/server.d.ts +7 -0
- package/dist/server.js +63 -0
- package/dist/services/cache/snapshots.d.ts +108 -0
- package/dist/services/cache/snapshots.js +275 -0
- package/dist/services/config/context-analyzer.d.ts +14 -0
- package/dist/services/config/context-analyzer.js +76 -0
- package/dist/services/config/field-classifier.d.ts +23 -0
- package/dist/services/config/field-classifier.js +47 -0
- package/dist/services/config/intelligent.d.ts +55 -0
- package/dist/services/config/intelligent.js +306 -0
- package/dist/services/config/rules.d.ts +6 -0
- package/dist/services/config/rules.js +44 -0
- package/dist/services/config/schema-resolver.d.ts +18 -0
- package/dist/services/config/schema-resolver.js +80 -0
- package/dist/services/corpus/loader.d.ts +56 -0
- package/dist/services/corpus/loader.js +25 -0
- package/dist/services/corpus/search.d.ts +49 -0
- package/dist/services/corpus/search.js +69 -0
- package/dist/services/corpus/templates.d.ts +4 -0
- package/dist/services/corpus/templates.js +11 -0
- package/dist/services/pipelines/execution.d.ts +20 -0
- package/dist/services/pipelines/execution.js +290 -0
- package/dist/services/pipelines/node-type-intent.d.ts +96 -0
- package/dist/services/pipelines/node-type-intent.js +356 -0
- package/dist/services/pipelines/node-type-selection.d.ts +66 -0
- package/dist/services/pipelines/node-type-selection.js +758 -0
- package/dist/services/pipelines/planning.d.ts +543 -0
- package/dist/services/pipelines/planning.js +1839 -0
- package/dist/services/policies/sql-override.d.ts +7 -0
- package/dist/services/policies/sql-override.js +109 -0
- package/dist/services/repo/operations.d.ts +6 -0
- package/dist/services/repo/operations.js +10 -0
- package/dist/services/repo/parser.d.ts +70 -0
- package/dist/services/repo/parser.js +365 -0
- package/dist/services/repo/path.d.ts +2 -0
- package/dist/services/repo/path.js +58 -0
- package/dist/services/templates/nodes.d.ts +50 -0
- package/dist/services/templates/nodes.js +336 -0
- package/dist/services/workspace/analysis.d.ts +56 -0
- package/dist/services/workspace/analysis.js +151 -0
- package/dist/services/workspace/mutations.d.ts +150 -0
- package/dist/services/workspace/mutations.js +1718 -0
- package/dist/utils.d.ts +5 -0
- package/dist/utils.js +7 -0
- package/dist/workflows/get-environment-overview.d.ts +9 -0
- package/dist/workflows/get-environment-overview.js +23 -0
- package/dist/workflows/get-run-details.d.ts +10 -0
- package/dist/workflows/get-run-details.js +28 -0
- package/dist/workflows/progress.d.ts +20 -0
- package/dist/workflows/progress.js +54 -0
- package/dist/workflows/retry-and-wait.d.ts +13 -0
- package/dist/workflows/retry-and-wait.js +139 -0
- package/dist/workflows/run-and-wait.d.ts +13 -0
- package/dist/workflows/run-and-wait.js +141 -0
- package/dist/workflows/run-status.d.ts +10 -0
- package/dist/workflows/run-status.js +27 -0
- package/package.json +34 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# Tool Usage Patterns
|
|
2
|
+
|
|
3
|
+
## Core Rules
|
|
4
|
+
|
|
5
|
+
- Only call tools that actually exist in this MCP server. Do not invent tool names.
|
|
6
|
+
- Prefer the smallest sufficient tool: list for discovery, get for detail, workflow helpers for multi-step operations.
|
|
7
|
+
- If the request is exploratory or ambiguous, ask clarifying questions before mutating anything.
|
|
8
|
+
- Before mutating a node, read the current state unless a helper already does that for you.
|
|
9
|
+
- Treat arrays as full-replacement fields unless a tool explicitly documents merge semantics. This is especially important for `metadata.columns`.
|
|
10
|
+
- When a helper returns `validation`, `warning`, `resultsError`, or `incomplete`, inspect those fields before continuing.
|
|
11
|
+
- Before declaring work complete, verify real outcomes by re-reading the saved node and checking `validation` fields.
|
|
12
|
+
|
|
13
|
+
## Discovery Patterns
|
|
14
|
+
|
|
15
|
+
### Find Projects and Workspaces
|
|
16
|
+
|
|
17
|
+
- `list-projects` or `get-project` to discover project structure
|
|
18
|
+
- For workspace IDs: `list-projects({ includeWorkspaces: true })` or `get-project({ projectID, includeWorkspaces: true })`
|
|
19
|
+
- For broader ID resolution guidance, see `coalesce://context/id-discovery`
|
|
20
|
+
|
|
21
|
+
### List vs Get
|
|
22
|
+
|
|
23
|
+
- **List** endpoints for discovery and broad state: `list-environments`, `list-projects`, `list-runs`, `list-workspace-nodes`, `list-environment-nodes`
|
|
24
|
+
- **Get** endpoints when you have an ID and need the full object: `get-environment`, `get-project`, `get-run`, `get-workspace-node`, `get-environment-node`
|
|
25
|
+
|
|
26
|
+
### Pagination
|
|
27
|
+
|
|
28
|
+
- Large list endpoints may be paginated. Do not assume one page is complete if `next` or paging cursors are present.
|
|
29
|
+
- Prefer discovery first, then targeted reads.
|
|
30
|
+
- Large JSON responses may be auto-cached to `coalesce_transform_mcp_data_cache/auto-cache/`; the tool returns cache metadata plus a `coalesce://cache/...` resource URI and `resource_link` instead of the full payload.
|
|
31
|
+
- Use explicit cache tools for large lists: `cache-workspace-nodes`, `cache-environment-nodes`, `cache-runs`, `cache-org-users`.
|
|
32
|
+
|
|
33
|
+
### Large Workspace Analysis
|
|
34
|
+
|
|
35
|
+
- `analyze-workspace-patterns` for a compact workspace profile (naming, packages, methodology conventions)
|
|
36
|
+
- `cache-workspace-nodes` when the full payload should be written to `coalesce_transform_mcp_data_cache/nodes/` for reuse
|
|
37
|
+
- For architecture guidance, see `coalesce://context/data-engineering-principles`
|
|
38
|
+
|
|
39
|
+
## Mandatory: Plan Before Creating Nodes
|
|
40
|
+
|
|
41
|
+
**NEVER skip `plan-pipeline` before creating nodes.** Do not hardcode node types like "Stage", "65", or any other ID.
|
|
42
|
+
|
|
43
|
+
1. Call `plan-pipeline` with `goal`, `sourceNodeIDs`, and `repoPath` — it discovers and ranks all node types
|
|
44
|
+
2. Use the `nodeType` from the plan result when calling creation tools — the planner already excludes specialized types (Dynamic Table, Incremental, Materialized View, etc.) unless your context explicitly requires them
|
|
45
|
+
|
|
46
|
+
**Common mistake**: Picking node types by ID or name without calling `plan-pipeline`. This leads to wrong types (e.g., Dynamic Tables for batch ETL) because the agent has no visibility into what types are available or appropriate.
|
|
47
|
+
|
|
48
|
+
## Repo-Backed and Corpus Workflows
|
|
49
|
+
|
|
50
|
+
Before creating nodes with complex metadata:
|
|
51
|
+
|
|
52
|
+
1. Check observed types: `list-workspace-node-types` (see `coalesce://context/node-type-corpus`)
|
|
53
|
+
2. If a local repo is available: install the package, commit, update clone, use `list-repo-node-types` / `get-repo-node-type-definition` / `generate-set-workspace-node-template` with `repoPath` or `COALESCE_REPO_PATH`
|
|
54
|
+
3. If the repo lacks the definition: use `search-node-type-variants` / `get-node-type-variant` / `generate-set-workspace-node-template-from-variant`
|
|
55
|
+
4. Adapt the pattern with user-specific data
|
|
56
|
+
5. Create with `create-workspace-node-from-predecessor` or pipeline tools
|
|
57
|
+
|
|
58
|
+
## Parallel vs Sequential Tool Use
|
|
59
|
+
|
|
60
|
+
### Safe to Parallelize
|
|
61
|
+
|
|
62
|
+
- Independent reads
|
|
63
|
+
- Multiple list/get calls for unrelated objects
|
|
64
|
+
- Discovery reads across several predecessor nodes
|
|
65
|
+
|
|
66
|
+
### Usually Sequential
|
|
67
|
+
|
|
68
|
+
- Dependent node creation (upstream before downstream)
|
|
69
|
+
- Create then validate flows
|
|
70
|
+
- Update flows where the next step depends on the saved body
|
|
71
|
+
- Run lifecycle steps
|
|
72
|
+
|
|
73
|
+
### Independent Writes
|
|
74
|
+
|
|
75
|
+
Parallelize only when writes truly do not depend on each other and you verify each result afterward. When in doubt, prefer sequential.
|
|
76
|
+
|
|
77
|
+
## Storage and SQL Context
|
|
78
|
+
|
|
79
|
+
- Use the actual node body to determine storage/location fields when writing SQL references
|
|
80
|
+
- Determine the platform with `coalesce://context/sql-platform-selection`, then read the matching dialect resource
|
|
81
|
+
- Cross-check `{{ ref() }}` assumptions against `coalesce://context/storage-mappings`
|
|
82
|
+
- For full-body edits, cross-check `coalesce://context/node-payloads` and `coalesce://context/hydrated-metadata`
|
|
83
|
+
|
|
84
|
+
## Capabilities and Boundaries
|
|
85
|
+
|
|
86
|
+
Your capabilities are defined by the tools in this MCP server:
|
|
87
|
+
|
|
88
|
+
- **Tool names**: Use exact tool names as listed. If an operation is not available as a tool, it falls outside your scope.
|
|
89
|
+
- **Source nodes**: Read-only. You can read them and use as predecessors, but cannot modify their columns or config.
|
|
90
|
+
- **Array fields**: Always send the full accumulated array. The server replaces — it does not merge.
|
|
91
|
+
- **Helper warnings**: `warning`, `validation`, and `resultsError` fields are actionable. A successful call with warnings may not be fully correct.
|
|
92
|
+
- **Node readiness**: A node is fully usable only when `validation` confirms coverage and correctness.
|
|
93
|
+
|
|
94
|
+
## Related Resources
|
|
95
|
+
|
|
96
|
+
- `coalesce://context/pipeline-workflows` — building pipelines end-to-end
|
|
97
|
+
- `coalesce://context/node-operations` — editing nodes after creation
|
|
98
|
+
- `coalesce://context/node-creation-decision-tree` — which tool to use
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { existsSync, readFileSync, readdirSync } from "fs";
|
|
3
|
+
import { basename, join, dirname } from "path";
|
|
4
|
+
import { fileURLToPath } from "url";
|
|
5
|
+
import { buildCacheResourceUri, getCacheDir, getCacheResourceMimeType, resolveCacheResourceUri, } from "../cache-dir.js";
|
|
6
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
7
|
+
const __dirname = dirname(__filename);
|
|
8
|
+
// Resource URIs
|
|
9
|
+
const RESOURCES = {
|
|
10
|
+
OVERVIEW: "coalesce://context/overview",
|
|
11
|
+
SQL_PLATFORM_SELECTION: "coalesce://context/sql-platform-selection",
|
|
12
|
+
SQL_SNOWFLAKE: "coalesce://context/sql-snowflake",
|
|
13
|
+
SQL_DATABRICKS: "coalesce://context/sql-databricks",
|
|
14
|
+
SQL_BIGQUERY: "coalesce://context/sql-bigquery",
|
|
15
|
+
DATA_ENGINEERING_PRINCIPLES: "coalesce://context/data-engineering-principles",
|
|
16
|
+
STORAGE_MAPPINGS: "coalesce://context/storage-mappings",
|
|
17
|
+
TOOL_USAGE: "coalesce://context/tool-usage",
|
|
18
|
+
ID_DISCOVERY: "coalesce://context/id-discovery",
|
|
19
|
+
NODE_CREATION_DECISION_TREE: "coalesce://context/node-creation-decision-tree",
|
|
20
|
+
NODE_PAYLOADS: "coalesce://context/node-payloads",
|
|
21
|
+
HYDRATED_METADATA: "coalesce://context/hydrated-metadata",
|
|
22
|
+
RUN_OPERATIONS: "coalesce://context/run-operations",
|
|
23
|
+
NODE_TYPE_CORPUS: "coalesce://context/node-type-corpus",
|
|
24
|
+
AGGREGATION_PATTERNS: "coalesce://context/aggregation-patterns",
|
|
25
|
+
INTELLIGENT_NODE_CONFIGURATION: "coalesce://context/intelligent-node-configuration",
|
|
26
|
+
PIPELINE_WORKFLOWS: "coalesce://context/pipeline-workflows",
|
|
27
|
+
NODE_OPERATIONS: "coalesce://context/node-operations",
|
|
28
|
+
NODE_TYPE_SELECTION_GUIDE: "coalesce://context/node-type-selection-guide",
|
|
29
|
+
};
|
|
30
|
+
// Map URIs to file paths
|
|
31
|
+
const RESOURCE_FILES = {
|
|
32
|
+
[RESOURCES.OVERVIEW]: "context/overview.md",
|
|
33
|
+
[RESOURCES.SQL_PLATFORM_SELECTION]: "context/sql-platform-selection.md",
|
|
34
|
+
[RESOURCES.SQL_SNOWFLAKE]: "context/sql-snowflake.md",
|
|
35
|
+
[RESOURCES.SQL_DATABRICKS]: "context/sql-databricks.md",
|
|
36
|
+
[RESOURCES.SQL_BIGQUERY]: "context/sql-bigquery.md",
|
|
37
|
+
[RESOURCES.DATA_ENGINEERING_PRINCIPLES]: "context/data-engineering-principles.md",
|
|
38
|
+
[RESOURCES.STORAGE_MAPPINGS]: "context/storage-mappings.md",
|
|
39
|
+
[RESOURCES.TOOL_USAGE]: "context/tool-usage.md",
|
|
40
|
+
[RESOURCES.ID_DISCOVERY]: "context/id-discovery.md",
|
|
41
|
+
[RESOURCES.NODE_CREATION_DECISION_TREE]: "context/node-creation-decision-tree.md",
|
|
42
|
+
[RESOURCES.NODE_PAYLOADS]: "context/node-payloads.md",
|
|
43
|
+
[RESOURCES.HYDRATED_METADATA]: "context/hydrated-metadata.md",
|
|
44
|
+
[RESOURCES.RUN_OPERATIONS]: "context/run-operations.md",
|
|
45
|
+
[RESOURCES.NODE_TYPE_CORPUS]: "context/node-type-corpus.md",
|
|
46
|
+
[RESOURCES.AGGREGATION_PATTERNS]: "context/aggregation-patterns.md",
|
|
47
|
+
[RESOURCES.INTELLIGENT_NODE_CONFIGURATION]: "context/intelligent-node-configuration.md",
|
|
48
|
+
[RESOURCES.PIPELINE_WORKFLOWS]: "context/pipeline-workflows.md",
|
|
49
|
+
[RESOURCES.NODE_OPERATIONS]: "context/node-operations.md",
|
|
50
|
+
[RESOURCES.NODE_TYPE_SELECTION_GUIDE]: "context/node-type-selection-guide.md",
|
|
51
|
+
};
|
|
52
|
+
// Resource metadata
|
|
53
|
+
const RESOURCE_METADATA = {
|
|
54
|
+
[RESOURCES.OVERVIEW]: {
|
|
55
|
+
name: "Coalesce Overview",
|
|
56
|
+
description: "General Coalesce concepts, response guidelines, and operational constraints for AI assistants",
|
|
57
|
+
mimeType: "text/markdown",
|
|
58
|
+
},
|
|
59
|
+
[RESOURCES.SQL_PLATFORM_SELECTION]: {
|
|
60
|
+
name: "SQL Platform Selection",
|
|
61
|
+
description: "How to determine the active SQL platform from project metadata and existing node SQL before choosing a dialect-specific resource",
|
|
62
|
+
mimeType: "text/markdown",
|
|
63
|
+
},
|
|
64
|
+
[RESOURCES.SQL_SNOWFLAKE]: {
|
|
65
|
+
name: "SQL Rules: Snowflake",
|
|
66
|
+
description: "Snowflake-specific SQL conventions for Coalesce node SQL",
|
|
67
|
+
mimeType: "text/markdown",
|
|
68
|
+
},
|
|
69
|
+
[RESOURCES.SQL_DATABRICKS]: {
|
|
70
|
+
name: "SQL Rules: Databricks",
|
|
71
|
+
description: "Databricks-specific SQL conventions for Coalesce node SQL",
|
|
72
|
+
mimeType: "text/markdown",
|
|
73
|
+
},
|
|
74
|
+
[RESOURCES.SQL_BIGQUERY]: {
|
|
75
|
+
name: "SQL Rules: BigQuery",
|
|
76
|
+
description: "BigQuery-specific SQL conventions for Coalesce node SQL",
|
|
77
|
+
mimeType: "text/markdown",
|
|
78
|
+
},
|
|
79
|
+
[RESOURCES.DATA_ENGINEERING_PRINCIPLES]: {
|
|
80
|
+
name: "Data Engineering Principles",
|
|
81
|
+
description: "Data engineering best practices for node type selection, layered architecture, methodology detection, materialization strategies, and dependency management",
|
|
82
|
+
mimeType: "text/markdown",
|
|
83
|
+
},
|
|
84
|
+
[RESOURCES.STORAGE_MAPPINGS]: {
|
|
85
|
+
name: "Storage Locations and References",
|
|
86
|
+
description: "Storage location concepts, {{ ref() }} syntax, and reference patterns in Coalesce SQL",
|
|
87
|
+
mimeType: "text/markdown",
|
|
88
|
+
},
|
|
89
|
+
[RESOURCES.TOOL_USAGE]: {
|
|
90
|
+
name: "Tool Usage Patterns",
|
|
91
|
+
description: "Best practices for tool batching, parallelization, SQL conversion, and node operations",
|
|
92
|
+
mimeType: "text/markdown",
|
|
93
|
+
},
|
|
94
|
+
[RESOURCES.ID_DISCOVERY]: {
|
|
95
|
+
name: "ID Discovery",
|
|
96
|
+
description: "How to resolve project, workspace, environment, job, run, node, and org IDs before calling Coalesce tools",
|
|
97
|
+
mimeType: "text/markdown",
|
|
98
|
+
},
|
|
99
|
+
[RESOURCES.NODE_CREATION_DECISION_TREE]: {
|
|
100
|
+
name: "Node Creation Decision Tree",
|
|
101
|
+
description: "How to choose between predecessor-based creation, updates, and full replacements for workspace nodes",
|
|
102
|
+
mimeType: "text/markdown",
|
|
103
|
+
},
|
|
104
|
+
[RESOURCES.NODE_PAYLOADS]: {
|
|
105
|
+
name: "Node Payloads",
|
|
106
|
+
description: "Practical guidance for working with workspace node bodies, including top-level fields, metadata, config, and array-replacement risks",
|
|
107
|
+
mimeType: "text/markdown",
|
|
108
|
+
},
|
|
109
|
+
[RESOURCES.HYDRATED_METADATA]: {
|
|
110
|
+
name: "Hydrated Metadata",
|
|
111
|
+
description: "Practical summary of Coalesce hydrated metadata structures for advanced node payload editing",
|
|
112
|
+
mimeType: "text/markdown",
|
|
113
|
+
},
|
|
114
|
+
[RESOURCES.RUN_OPERATIONS]: {
|
|
115
|
+
name: "Run Operations",
|
|
116
|
+
description: "Guidance for starting, retrying, polling, diagnosing, and canceling Coalesce runs",
|
|
117
|
+
mimeType: "text/markdown",
|
|
118
|
+
},
|
|
119
|
+
[RESOURCES.NODE_TYPE_CORPUS]: {
|
|
120
|
+
name: "Node Type Corpus",
|
|
121
|
+
description: "Node type discovery, corpus search, metadata patterns (consult BEFORE creating or editing nodes)",
|
|
122
|
+
mimeType: "text/markdown",
|
|
123
|
+
},
|
|
124
|
+
[RESOURCES.AGGREGATION_PATTERNS]: {
|
|
125
|
+
name: "Aggregation Patterns",
|
|
126
|
+
description: "Automatic JOIN ON generation, GROUP BY detection, datatype inference, and patterns for converting joins to aggregations",
|
|
127
|
+
mimeType: "text/markdown",
|
|
128
|
+
},
|
|
129
|
+
[RESOURCES.INTELLIGENT_NODE_CONFIGURATION]: {
|
|
130
|
+
name: "Intelligent Node Configuration",
|
|
131
|
+
description: "How intelligent config completion works for workspace nodes, including schema resolution, intelligence rules, and automatic field detection",
|
|
132
|
+
mimeType: "text/markdown",
|
|
133
|
+
},
|
|
134
|
+
[RESOURCES.PIPELINE_WORKFLOWS]: {
|
|
135
|
+
name: "Pipeline Workflows",
|
|
136
|
+
description: "Building pipelines end-to-end: node type selection, multi-node sequences, incremental setup, and pipeline execution",
|
|
137
|
+
mimeType: "text/markdown",
|
|
138
|
+
},
|
|
139
|
+
[RESOURCES.NODE_OPERATIONS]: {
|
|
140
|
+
name: "Node Operations",
|
|
141
|
+
description: "Editing existing nodes: join conditions, column operations, config fields, rename safety, SQL-to-graph conversion, and debugging",
|
|
142
|
+
mimeType: "text/markdown",
|
|
143
|
+
},
|
|
144
|
+
[RESOURCES.NODE_TYPE_SELECTION_GUIDE]: {
|
|
145
|
+
name: "Node Type Selection Guide",
|
|
146
|
+
description: "When to use each Coalesce node type: Stage/Work for general transforms, Dimension/Fact only for dimensional modeling, and when to avoid Dynamic Tables, Incremental Loads, and other specialized patterns",
|
|
147
|
+
mimeType: "text/markdown",
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
/**
|
|
151
|
+
* Read a resource content file
|
|
152
|
+
*/
|
|
153
|
+
function readResourceContent(relativePath) {
|
|
154
|
+
const fullPath = join(__dirname, relativePath);
|
|
155
|
+
return readFileSync(fullPath, "utf-8");
|
|
156
|
+
}
|
|
157
|
+
function listCacheFilePaths(directory) {
|
|
158
|
+
if (!existsSync(directory)) {
|
|
159
|
+
return [];
|
|
160
|
+
}
|
|
161
|
+
const entries = readdirSync(directory, { withFileTypes: true });
|
|
162
|
+
const filePaths = [];
|
|
163
|
+
for (const entry of entries) {
|
|
164
|
+
const entryPath = join(directory, entry.name);
|
|
165
|
+
if (entry.isDirectory()) {
|
|
166
|
+
filePaths.push(...listCacheFilePaths(entryPath));
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
if (entry.isFile()) {
|
|
170
|
+
filePaths.push(entryPath);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return filePaths.sort();
|
|
174
|
+
}
|
|
175
|
+
function listCacheResources(baseDir) {
|
|
176
|
+
const cacheDir = getCacheDir(baseDir);
|
|
177
|
+
return listCacheFilePaths(cacheDir).flatMap((filePath) => {
|
|
178
|
+
const uri = buildCacheResourceUri(filePath, baseDir);
|
|
179
|
+
if (!uri) {
|
|
180
|
+
return [];
|
|
181
|
+
}
|
|
182
|
+
return [
|
|
183
|
+
{
|
|
184
|
+
uri,
|
|
185
|
+
name: basename(filePath),
|
|
186
|
+
description: "Cached Coalesce MCP artifact stored on disk and exposed through MCP resources.",
|
|
187
|
+
mimeType: getCacheResourceMimeType(filePath),
|
|
188
|
+
},
|
|
189
|
+
];
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Register all Coalesce context resources with the MCP server
|
|
194
|
+
*/
|
|
195
|
+
export function registerResources(server) {
|
|
196
|
+
for (const [uri, metadata] of Object.entries(RESOURCE_METADATA)) {
|
|
197
|
+
server.resource(metadata.name, uri, {
|
|
198
|
+
description: metadata.description,
|
|
199
|
+
mimeType: metadata.mimeType,
|
|
200
|
+
}, async (resourceUri) => {
|
|
201
|
+
const filePath = RESOURCE_FILES[uri];
|
|
202
|
+
if (!filePath) {
|
|
203
|
+
throw new Error(`Unknown resource: ${uri}`);
|
|
204
|
+
}
|
|
205
|
+
try {
|
|
206
|
+
const content = readResourceContent(filePath);
|
|
207
|
+
return {
|
|
208
|
+
contents: [
|
|
209
|
+
{
|
|
210
|
+
uri: resourceUri.toString(),
|
|
211
|
+
mimeType: metadata.mimeType,
|
|
212
|
+
text: content,
|
|
213
|
+
},
|
|
214
|
+
],
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
catch (error) {
|
|
218
|
+
throw new Error(`Failed to read resource ${uri}: ${error instanceof Error ? error.message : String(error)}`);
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
server.resource("Coalesce Cache Artifact", new ResourceTemplate("coalesce://cache/{cacheKey}", {
|
|
223
|
+
list: async () => ({
|
|
224
|
+
resources: listCacheResources(),
|
|
225
|
+
}),
|
|
226
|
+
complete: {
|
|
227
|
+
cacheKey: async (value) => listCacheResources()
|
|
228
|
+
.map((resource) => resource.uri.split("/").pop() ?? "")
|
|
229
|
+
.filter((cacheKey) => cacheKey.startsWith(value))
|
|
230
|
+
.slice(0, 50),
|
|
231
|
+
},
|
|
232
|
+
}), {
|
|
233
|
+
description: "Dynamic resources for cached tool responses, cache snapshots, and pipeline summaries.",
|
|
234
|
+
}, async (resourceUri) => {
|
|
235
|
+
const resolved = resolveCacheResourceUri(resourceUri.toString());
|
|
236
|
+
if (!resolved) {
|
|
237
|
+
throw new Error(`Unknown cache resource: ${resourceUri.toString()}`);
|
|
238
|
+
}
|
|
239
|
+
try {
|
|
240
|
+
return {
|
|
241
|
+
contents: [
|
|
242
|
+
{
|
|
243
|
+
uri: resourceUri.toString(),
|
|
244
|
+
mimeType: getCacheResourceMimeType(resolved.filePath),
|
|
245
|
+
text: readFileSync(resolved.filePath, "utf8"),
|
|
246
|
+
},
|
|
247
|
+
],
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
catch (error) {
|
|
251
|
+
throw new Error(`Failed to read cache resource ${resourceUri.toString()}: ${error instanceof Error ? error.message : String(error)}`);
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
}
|