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.
Files changed (134) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +304 -0
  3. package/dist/cache-dir.d.ts +26 -0
  4. package/dist/cache-dir.js +106 -0
  5. package/dist/client.d.ts +25 -0
  6. package/dist/client.js +212 -0
  7. package/dist/coalesce/api/environments.d.ts +20 -0
  8. package/dist/coalesce/api/environments.js +15 -0
  9. package/dist/coalesce/api/git-accounts.d.ts +21 -0
  10. package/dist/coalesce/api/git-accounts.js +21 -0
  11. package/dist/coalesce/api/jobs.d.ts +25 -0
  12. package/dist/coalesce/api/jobs.js +21 -0
  13. package/dist/coalesce/api/nodes.d.ts +29 -0
  14. package/dist/coalesce/api/nodes.js +33 -0
  15. package/dist/coalesce/api/projects.d.ts +22 -0
  16. package/dist/coalesce/api/projects.js +25 -0
  17. package/dist/coalesce/api/runs.d.ts +19 -0
  18. package/dist/coalesce/api/runs.js +34 -0
  19. package/dist/coalesce/api/subgraphs.d.ts +20 -0
  20. package/dist/coalesce/api/subgraphs.js +17 -0
  21. package/dist/coalesce/api/users.d.ts +30 -0
  22. package/dist/coalesce/api/users.js +31 -0
  23. package/dist/coalesce/types.d.ts +298 -0
  24. package/dist/coalesce/types.js +746 -0
  25. package/dist/generated/.gitkeep +0 -0
  26. package/dist/generated/node-type-corpus.json +42656 -0
  27. package/dist/index.d.ts +2 -0
  28. package/dist/index.js +10 -0
  29. package/dist/mcp/cache.d.ts +3 -0
  30. package/dist/mcp/cache.js +137 -0
  31. package/dist/mcp/environments.d.ts +3 -0
  32. package/dist/mcp/environments.js +61 -0
  33. package/dist/mcp/git-accounts.d.ts +3 -0
  34. package/dist/mcp/git-accounts.js +70 -0
  35. package/dist/mcp/jobs.d.ts +3 -0
  36. package/dist/mcp/jobs.js +77 -0
  37. package/dist/mcp/node-type-corpus.d.ts +3 -0
  38. package/dist/mcp/node-type-corpus.js +173 -0
  39. package/dist/mcp/nodes.d.ts +3 -0
  40. package/dist/mcp/nodes.js +341 -0
  41. package/dist/mcp/pipelines.d.ts +3 -0
  42. package/dist/mcp/pipelines.js +342 -0
  43. package/dist/mcp/projects.d.ts +3 -0
  44. package/dist/mcp/projects.js +70 -0
  45. package/dist/mcp/repo-node-types.d.ts +135 -0
  46. package/dist/mcp/repo-node-types.js +387 -0
  47. package/dist/mcp/runs.d.ts +3 -0
  48. package/dist/mcp/runs.js +92 -0
  49. package/dist/mcp/subgraphs.d.ts +3 -0
  50. package/dist/mcp/subgraphs.js +60 -0
  51. package/dist/mcp/users.d.ts +3 -0
  52. package/dist/mcp/users.js +107 -0
  53. package/dist/prompts/index.d.ts +2 -0
  54. package/dist/prompts/index.js +58 -0
  55. package/dist/resources/context/aggregation-patterns.md +145 -0
  56. package/dist/resources/context/data-engineering-principles.md +183 -0
  57. package/dist/resources/context/hydrated-metadata.md +92 -0
  58. package/dist/resources/context/id-discovery.md +64 -0
  59. package/dist/resources/context/intelligent-node-configuration.md +162 -0
  60. package/dist/resources/context/node-creation-decision-tree.md +156 -0
  61. package/dist/resources/context/node-operations.md +316 -0
  62. package/dist/resources/context/node-payloads.md +114 -0
  63. package/dist/resources/context/node-type-corpus.md +166 -0
  64. package/dist/resources/context/node-type-selection-guide.md +96 -0
  65. package/dist/resources/context/overview.md +135 -0
  66. package/dist/resources/context/pipeline-workflows.md +355 -0
  67. package/dist/resources/context/run-operations.md +55 -0
  68. package/dist/resources/context/sql-bigquery.md +41 -0
  69. package/dist/resources/context/sql-databricks.md +40 -0
  70. package/dist/resources/context/sql-platform-selection.md +70 -0
  71. package/dist/resources/context/sql-snowflake.md +43 -0
  72. package/dist/resources/context/storage-mappings.md +49 -0
  73. package/dist/resources/context/tool-usage.md +98 -0
  74. package/dist/resources/index.d.ts +5 -0
  75. package/dist/resources/index.js +254 -0
  76. package/dist/schemas/node-payloads.d.ts +5019 -0
  77. package/dist/schemas/node-payloads.js +147 -0
  78. package/dist/server.d.ts +7 -0
  79. package/dist/server.js +63 -0
  80. package/dist/services/cache/snapshots.d.ts +108 -0
  81. package/dist/services/cache/snapshots.js +275 -0
  82. package/dist/services/config/context-analyzer.d.ts +14 -0
  83. package/dist/services/config/context-analyzer.js +76 -0
  84. package/dist/services/config/field-classifier.d.ts +23 -0
  85. package/dist/services/config/field-classifier.js +47 -0
  86. package/dist/services/config/intelligent.d.ts +55 -0
  87. package/dist/services/config/intelligent.js +306 -0
  88. package/dist/services/config/rules.d.ts +6 -0
  89. package/dist/services/config/rules.js +44 -0
  90. package/dist/services/config/schema-resolver.d.ts +18 -0
  91. package/dist/services/config/schema-resolver.js +80 -0
  92. package/dist/services/corpus/loader.d.ts +56 -0
  93. package/dist/services/corpus/loader.js +25 -0
  94. package/dist/services/corpus/search.d.ts +49 -0
  95. package/dist/services/corpus/search.js +69 -0
  96. package/dist/services/corpus/templates.d.ts +4 -0
  97. package/dist/services/corpus/templates.js +11 -0
  98. package/dist/services/pipelines/execution.d.ts +20 -0
  99. package/dist/services/pipelines/execution.js +290 -0
  100. package/dist/services/pipelines/node-type-intent.d.ts +96 -0
  101. package/dist/services/pipelines/node-type-intent.js +356 -0
  102. package/dist/services/pipelines/node-type-selection.d.ts +66 -0
  103. package/dist/services/pipelines/node-type-selection.js +758 -0
  104. package/dist/services/pipelines/planning.d.ts +543 -0
  105. package/dist/services/pipelines/planning.js +1839 -0
  106. package/dist/services/policies/sql-override.d.ts +7 -0
  107. package/dist/services/policies/sql-override.js +109 -0
  108. package/dist/services/repo/operations.d.ts +6 -0
  109. package/dist/services/repo/operations.js +10 -0
  110. package/dist/services/repo/parser.d.ts +70 -0
  111. package/dist/services/repo/parser.js +365 -0
  112. package/dist/services/repo/path.d.ts +2 -0
  113. package/dist/services/repo/path.js +58 -0
  114. package/dist/services/templates/nodes.d.ts +50 -0
  115. package/dist/services/templates/nodes.js +336 -0
  116. package/dist/services/workspace/analysis.d.ts +56 -0
  117. package/dist/services/workspace/analysis.js +151 -0
  118. package/dist/services/workspace/mutations.d.ts +150 -0
  119. package/dist/services/workspace/mutations.js +1718 -0
  120. package/dist/utils.d.ts +5 -0
  121. package/dist/utils.js +7 -0
  122. package/dist/workflows/get-environment-overview.d.ts +9 -0
  123. package/dist/workflows/get-environment-overview.js +23 -0
  124. package/dist/workflows/get-run-details.d.ts +10 -0
  125. package/dist/workflows/get-run-details.js +28 -0
  126. package/dist/workflows/progress.d.ts +20 -0
  127. package/dist/workflows/progress.js +54 -0
  128. package/dist/workflows/retry-and-wait.d.ts +13 -0
  129. package/dist/workflows/retry-and-wait.js +139 -0
  130. package/dist/workflows/run-and-wait.d.ts +13 -0
  131. package/dist/workflows/run-and-wait.js +141 -0
  132. package/dist/workflows/run-status.d.ts +10 -0
  133. package/dist/workflows/run-status.js +27 -0
  134. package/package.json +34 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jesse Marshall
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,304 @@
1
+ # coalesce-transform-mcp
2
+
3
+ **Disclaimer:** This is a sample project provided as-is for reference.
4
+
5
+ MCP server for the Coalesce Transform API. Lets MCP-compatible AI assistants handle supported Coalesce workflows such as managing environments, nodes, jobs, and subgraphs, triggering runs, and selected project, user, and git-account operations from an editor or CLI.
6
+
7
+ ## Requirements
8
+
9
+ - [Node.js](https://nodejs.org/) >= 18.0.0 (includes npm)
10
+ - A [Coalesce](https://coalesce.io/) account with at least one workspace
11
+ - A Coalesce access token (generated from the Deploy tab in your workspace; see [Coalesce API docs](https://docs.coalesce.io/docs/api/authentication))
12
+ - An MCP-compatible AI client (Claude Code, Claude Desktop, Cursor, Windsurf, etc.)
13
+ - **For run tools only:** A Snowflake account with key pair authentication configured
14
+
15
+ ## Installation
16
+
17
+ ### 1. Clone and Build
18
+
19
+ ```bash
20
+ git clone https://github.com/jessemarshall/coalesce-transform-mcp.git
21
+ cd coalesce-transform-mcp
22
+ npm install
23
+ npm run build
24
+ ```
25
+
26
+ ### 2. Set Environment Variables
27
+
28
+ Add your credentials to your shell profile (`~/.zshrc` or `~/.bashrc`):
29
+
30
+ ```bash
31
+ # Coalesce API (required)
32
+ export COALESCE_ACCESS_TOKEN="your-token-here"
33
+ export COALESCE_BASE_URL="https://app.coalescesoftware.io"
34
+ export COALESCE_ORG_ID="your-org-id" # Optional: used as fallback by cancel-run
35
+ export COALESCE_REPO_PATH="/path/to/local/coalesce-repo" # Optional: fallback for repo-backed node-type tools and pipeline planning
36
+
37
+ # Snowflake Key Pair Auth (required for `start-run`, `retry-run`, `run-and-wait`, and `retry-and-wait`)
38
+ export SNOWFLAKE_USERNAME="your-snowflake-username"
39
+ export SNOWFLAKE_KEY_PAIR_KEY="/path/to/your/snowflake_key.pem"
40
+ export SNOWFLAKE_KEY_PAIR_PASS="your-key-passphrase" # Only needed for encrypted keys
41
+ export SNOWFLAKE_WAREHOUSE="your-warehouse"
42
+ export SNOWFLAKE_ROLE="your-role"
43
+ ```
44
+
45
+ Then reload your shell:
46
+
47
+ ```bash
48
+ source ~/.zshrc
49
+ ```
50
+
51
+ ### 3. Add the MCP Server to Your Client
52
+
53
+ Add the following to your client's MCP configuration file, replacing `/absolute/path/to/coalesce-transform-mcp` with the path where you cloned the repo:
54
+
55
+ | Client | Config file location |
56
+ |--------|---------------------|
57
+ | Claude Code | `.mcp.json` in your project root (or `~/.claude.json` for global) |
58
+ | Claude Desktop (macOS) | `~/Library/Application Support/Claude/claude_desktop_config.json` |
59
+ | Cursor | `.cursor/mcp.json` in your project root |
60
+ | Windsurf | `~/.codeium/windsurf/mcp_config.json` |
61
+
62
+ ```json
63
+ {
64
+ "coalesce-transform": {
65
+ "command": "node",
66
+ "args": ["/absolute/path/to/coalesce-transform-mcp/dist/index.js"],
67
+ "env": {
68
+ "COALESCE_ACCESS_TOKEN": "${COALESCE_ACCESS_TOKEN}",
69
+ "COALESCE_BASE_URL": "${COALESCE_BASE_URL}",
70
+ "COALESCE_REPO_PATH": "${COALESCE_REPO_PATH}",
71
+ "SNOWFLAKE_USERNAME": "${SNOWFLAKE_USERNAME}",
72
+ "SNOWFLAKE_KEY_PAIR_KEY": "${SNOWFLAKE_KEY_PAIR_KEY}",
73
+ "SNOWFLAKE_KEY_PAIR_PASS": "${SNOWFLAKE_KEY_PAIR_PASS}",
74
+ "SNOWFLAKE_WAREHOUSE": "${SNOWFLAKE_WAREHOUSE}",
75
+ "SNOWFLAKE_ROLE": "${SNOWFLAKE_ROLE}"
76
+ }
77
+ }
78
+ }
79
+ ```
80
+
81
+ The `${VAR}` syntax pulls values from your shell environment, keeping credentials out of your config files. Pass through `COALESCE_ORG_ID` if you want the `cancel-run` fallback, and `COALESCE_REPO_PATH` if you want repo-backed tools and pipeline planning to default to a local repo path.
82
+
83
+ > **Never hardcode credentials in config files that are tracked by git.** Use environment variable references (`${VAR}`) instead.
84
+
85
+ ## Environment Variable Reference
86
+
87
+ ### Coalesce (required at startup)
88
+
89
+ | Variable | Description | Example |
90
+ |----------|-------------|---------|
91
+ | `COALESCE_ACCESS_TOKEN` | Bearer token from Coalesce Deploy tab | `eyJhbG...` |
92
+ | `COALESCE_BASE_URL` | Region-specific base URL (see [Region Base URLs](#region-base-urls)) | `https://app.coalescesoftware.io` |
93
+
94
+ ### Coalesce (optional)
95
+
96
+ | Variable | Used By | Description |
97
+ |----------|---------|-------------|
98
+ | `COALESCE_ORG_ID` | `cancel-run` | Optional fallback Org ID when `orgID` is not passed to the tool |
99
+ | `COALESCE_REPO_PATH` | Repo-backed node-type tools, `plan-pipeline`, `create-pipeline-from-sql` | Optional fallback local repo path when `repoPath` is not passed explicitly. Point this at the repo root that contains `nodeTypes/`, `nodes/`, and usually `packages/`. |
100
+ | `COALESCE_MCP_AUTO_CACHE_MAX_BYTES` | All JSON-returning tools/workflows | Pretty-printed JSON size threshold in bytes before the full response is automatically written to disk and only cache metadata is returned inline. Defaults to `32768`. |
101
+ | `COALESCE_MCP_MAX_REQUEST_BODY_BYTES` | All API-calling tools | Maximum serialized JSON body size in bytes for outbound API requests. Rejects oversized payloads before they leave the process. Defaults to `524288` (512 KB). |
102
+
103
+ ### Snowflake (required for run tools: `start-run`, `retry-run`, `run-and-wait`, `retry-and-wait`)
104
+
105
+ These are validated lazily: the server starts without them, but the run-triggering tools will error if they are missing.
106
+
107
+ | Variable | Required | Description |
108
+ |----------|----------|-------------|
109
+ | `SNOWFLAKE_USERNAME` | Yes | Snowflake account username |
110
+ | `SNOWFLAKE_KEY_PAIR_KEY` | Yes | File path to PEM-encoded private key for Snowflake auth |
111
+ | `SNOWFLAKE_KEY_PAIR_PASS` | No | Password to decrypt an encrypted private key |
112
+ | `SNOWFLAKE_WAREHOUSE` | Yes | Snowflake compute warehouse |
113
+ | `SNOWFLAKE_ROLE` | Yes | Snowflake user role |
114
+
115
+ ## Region Base URLs
116
+
117
+ | Region | URL |
118
+ |--------|-----|
119
+ | US (default) | `https://app.coalescesoftware.io` |
120
+ | EU (west-3) | `https://app.eu.coalescesoftware.io` |
121
+ | EU (west-2) | `https://app.eu-west-2.aws.coalescesoftware.io` |
122
+ | Canada | `https://app.northamerica-northeast1.gcp.coalescesoftware.io` |
123
+ | Australia | `https://app.australia-southeast1.gcp.coalescesoftware.io` |
124
+
125
+ ## Tool Reference
126
+
127
+ ⚠️ = Destructive operation
128
+
129
+ ### API Tools
130
+
131
+ Coalesce Platform Tools: manage workspaces, environments, projects, runs, and other platform resources.
132
+
133
+ #### Environments
134
+
135
+ - `list-environments` - List all available environments
136
+ - `get-environment` - Get details of a specific environment
137
+ - `create-environment` - Create a new environment within a project
138
+ - `delete-environment` - Delete an environment ⚠️
139
+
140
+ #### Nodes
141
+
142
+ - `list-environment-nodes` - List nodes in an environment
143
+ - `list-workspace-nodes` - List nodes in a workspace
144
+ - `get-environment-node` - Get a specific environment node
145
+ - `get-workspace-node` - Get a specific workspace node
146
+ - `set-workspace-node` - Replace a workspace node with a full body
147
+ - `update-workspace-node` - Safely update selected fields of a workspace node
148
+ - `delete-workspace-node` - Delete a node from a workspace ⚠️
149
+
150
+ #### Jobs
151
+
152
+ - `list-jobs` - List all jobs for an environment
153
+ - `create-workspace-job` - Create a job in a workspace with node include/exclude selectors
154
+ - `get-job` - Get details of a specific job (via environment)
155
+ - `update-workspace-job` - Update a job's name and node selectors
156
+ - `delete-workspace-job` - Delete a job ⚠️
157
+
158
+ #### Subgraphs
159
+
160
+ - `get-workspace-subgraph` - Get details of a specific subgraph
161
+ - `create-workspace-subgraph` - Create a subgraph to group nodes visually
162
+ - `update-workspace-subgraph` - Update a subgraph's name and node membership
163
+ - `delete-workspace-subgraph` - Delete a subgraph (nodes are NOT deleted) ⚠️
164
+
165
+ #### Runs
166
+
167
+ - `list-runs` - List runs with optional filters
168
+ - `get-run` - Get details of a specific run
169
+ - `get-run-results` - Get results of a completed run
170
+ - `start-run` - Start a new run; requires Snowflake Key Pair auth (credentials from env vars)
171
+ - `run-status` - Check status of a running job
172
+ - `retry-run` - Retry a failed run; requires Snowflake Key Pair auth (credentials from env vars)
173
+ - `cancel-run` - Cancel a running job (requires `runID` and `environmentID`; `orgID` may come from `COALESCE_ORG_ID`) ⚠️
174
+
175
+ #### Projects
176
+
177
+ - `list-projects` - List all projects
178
+ - `get-project` - Get project details
179
+ - `create-project` - Create a new project
180
+ - `update-project` - Update a project
181
+ - `delete-project` - Delete a project ⚠️
182
+
183
+ #### Git Accounts
184
+
185
+ - `list-git-accounts` - List all git accounts
186
+ - `get-git-account` - Get git account details
187
+ - `create-git-account` - Create a new git account
188
+ - `update-git-account` - Update a git account
189
+ - `delete-git-account` - Delete a git account ⚠️
190
+
191
+ #### Users
192
+
193
+ - `list-org-users` - List all organization users
194
+ - `get-user-roles` - Get roles for a specific user
195
+ - `list-user-roles` - List all user roles
196
+ - `set-org-role` - Set organization role for a user
197
+ - `set-project-role` - Set project role for a user
198
+ - `delete-project-role` - Remove project role from a user ⚠️
199
+ - `set-env-role` - Set environment role for a user
200
+ - `delete-env-role` - Remove environment role from a user ⚠️
201
+
202
+ ### Intelligent Tools
203
+
204
+ Custom logic built on top of the API: pipeline planning, config completion, join analysis, workspace analysis, and more.
205
+
206
+ #### Node Creation and Configuration
207
+
208
+ - `create-workspace-node-from-scratch` - Create a workspace node with no predecessors, apply fields to the requested completion level, and run automatic config completion
209
+ - `create-workspace-node-from-predecessor` - Create a node from predecessor nodes, verify column coverage, suggest join columns, and run automatic config completion
210
+ - `replace-workspace-node-columns` - Replace `metadata.columns` wholesale and optionally apply additional changes for complex column rewrites
211
+ - `convert-join-to-aggregation` - Convert a join-style node into an aggregated fact-style node with generated JOIN/GROUP BY analysis
212
+ - `apply-join-condition` - Auto-generate and write a FROM/JOIN/ON clause for a multi-predecessor node
213
+ - `complete-node-configuration` - Intelligently complete a node's configuration by analyzing context and applying best-practice rules
214
+ - `list-workspace-node-types` - List distinct node types observed in current workspace nodes
215
+ - `analyze-workspace-patterns` - Analyze workspace nodes to detect package adoption, pipeline layers, methodology, and generate recommendations
216
+
217
+ #### Pipeline Planning and Execution
218
+
219
+ - `plan-pipeline` - Plan a pipeline from SQL or a natural-language goal without mutating the workspace; ranks best-fit node types from the local repo
220
+ - `create-pipeline-from-plan` - Execute an approved pipeline plan using predecessor-based creation
221
+ - `create-pipeline-from-sql` - Plan and create a pipeline directly from SQL
222
+
223
+ #### Repo-Backed Node Types and Templates
224
+
225
+ - `list-repo-packages` - Inspect a committed local Coalesce repo and list package aliases plus enabled node-type coverage from `packages/*.yml`
226
+ - `list-repo-node-types` - List exact resolvable committed node-type identifiers from `nodeTypes/`, optionally scoped to one package alias or currently in-use types
227
+ - `get-repo-node-type-definition` - Resolve one exact committed node type from a local repo and return its outer definition plus raw and parsed `metadata.nodeMetadataSpec`
228
+ - `generate-set-workspace-node-template` - Generate a YAML-friendly `set-workspace-node` body template from either a raw definition object or an exact committed repo definition resolved by `repoPath` or `COALESCE_REPO_PATH`
229
+
230
+ #### Node Type Corpus
231
+
232
+ - `search-node-type-variants` - Search the committed node-type corpus snapshot by normalized family, package, primitive, or support status
233
+ - `get-node-type-variant` - Load one exact node-type corpus variant by variant key
234
+ - `generate-set-workspace-node-template-from-variant` - Generate a `set-workspace-node` body template from a committed corpus variant without needing the original external source repo at runtime; partial variants are rejected unless `allowPartial=true`
235
+
236
+ #### Cache and Snapshots
237
+
238
+ - `cache-workspace-nodes` - Fetch every page of workspace nodes, write the full snapshot to `coalesce_transform_mcp_data_cache/nodes/`, and return only cache metadata
239
+ - `cache-environment-nodes` - Fetch every page of environment nodes, write the full snapshot to `coalesce_transform_mcp_data_cache/nodes/`, and return only cache metadata
240
+ - `cache-runs` - Fetch every page of run results, write the full snapshot to `coalesce_transform_mcp_data_cache/runs/`, and return only cache metadata
241
+ - `cache-org-users` - Fetch every page of organization users, write the full snapshot to `coalesce_transform_mcp_data_cache/users/`, and return only cache metadata
242
+ - `clear_coalesce_transform_mcp_data_cache` - Delete all cached snapshots, auto-cached responses, and plan summaries under `coalesce_transform_mcp_data_cache/` ⚠️
243
+
244
+ #### Workflows
245
+
246
+ - `run-and-wait` - Start a run and poll until completion; requires Snowflake Key Pair auth
247
+ - `retry-and-wait` - Retry a failed run and poll until completion; requires Snowflake Key Pair auth
248
+ - `get-run-details` - Get run metadata and results in one call
249
+ - `get-environment-overview` - Get environment details with full node list
250
+
251
+ ## Automatic Large-Response Caching
252
+
253
+ Large JSON tool and workflow responses are auto-cached to `coalesce_transform_mcp_data_cache/auto-cache/`.
254
+
255
+ - If the pretty-printed JSON response is at or below the inline threshold, the full payload is returned inline.
256
+ - If it exceeds the threshold, the server writes the full JSON response to `coalesce_transform_mcp_data_cache/auto-cache/` and returns compact metadata with an MCP `resourceUri` plus a `resource_link` you can read through the client.
257
+ - The default threshold is `32768` bytes and can be overridden with `COALESCE_MCP_AUTO_CACHE_MAX_BYTES`.
258
+ - Explicit cache tools such as `cache-workspace-nodes` are still the better choice when you already know you want a reusable snapshot under `coalesce_transform_mcp_data_cache/`.
259
+
260
+ ## Prompt Surface
261
+
262
+ The server also exposes reusable MCP prompts for high-value workflows:
263
+
264
+ - `coalesce-start-here` - ID discovery and safe first steps before mutations
265
+ - `safe-pipeline-planning` - planner-first pipeline review and approval flow
266
+ - `run-operations-guide` - choosing the right run helper and interpreting statuses
267
+ - `large-result-handling` - working with cached responses and `coalesce://cache/...` resources
268
+
269
+ ## Repo-Backed Workflow
270
+
271
+ Use repo-backed discovery, template generation, and pipeline planning when you have a local clone of your Coalesce repo. Set `COALESCE_REPO_PATH` to the repo root (the directory containing `nodeTypes/`, `nodes/`, and usually `packages/`) or pass `repoPath` explicitly on individual tool calls.
272
+
273
+ Notes:
274
+
275
+ - `repoPath` is supported on repo-backed discovery/template tools and pipeline planning.
276
+ - `COALESCE_REPO_PATH` is an optional fallback for those repo-backed tools when `repoPath` is omitted.
277
+ - The MCP does not clone repos, fetch branches, or install packages.
278
+ - If the committed repo does not contain the definition, fall back to the corpus tools.
279
+
280
+ ## Large Collection Workflow
281
+
282
+ When a list response would be too large for chat context, or you want a reusable artifact on disk:
283
+
284
+ 1. Use the matching cache tool instead of the inline list result:
285
+ - `cache-workspace-nodes`
286
+ - `cache-environment-nodes`
287
+ - `cache-runs`
288
+ - `cache-org-users`
289
+ 2. Read the returned `fileUri` or `metaUri` resource through MCP, or follow the returned `resource_link` content blocks.
290
+ 3. Use inline list tools for smaller exploratory reads and targeted follow-up calls.
291
+
292
+ ## Operational Guardrails
293
+
294
+ - SQL override is intentionally disallowed in this project. Repo and corpus template generation strips `overrideSQLToggle`, and node write helpers reject `overrideSQL` and `override.*` fields.
295
+
296
+ ## Helpful Coalesce Docs
297
+
298
+ - [Coalesce Docs](https://docs.coalesce.io/docs) - General product documentation, concepts, and platform guidance.
299
+ - [Coalesce API Docs](https://docs.coalesce.io/docs/api/authentication) - Authentication, endpoints, and request/response reference for the API.
300
+ - [Coalesce Marketplace Docs](https://docs.coalesce.io/docs/marketplace) - Packages, marketplace-managed node types, and template authoring context.
301
+
302
+ ## License
303
+
304
+ MIT
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Root directory name for all MCP cache data.
3
+ * Deliberately distinctive to avoid collisions when the server runs from a project root.
4
+ */
5
+ export declare const CACHE_DIR_NAME = "coalesce_transform_mcp_data_cache";
6
+ export declare const CACHE_RESOURCE_URI_PREFIX = "coalesce://cache/";
7
+ export declare function getCacheDir(baseDir?: string): string;
8
+ export type CacheResourceLink = {
9
+ type: "resource_link";
10
+ uri: string;
11
+ name: string;
12
+ mimeType?: string;
13
+ description?: string;
14
+ };
15
+ export declare function getCacheRelativePath(filePath: string, baseDir?: string): string | null;
16
+ export declare function buildCacheResourceUri(filePath: string, baseDir?: string): string | null;
17
+ export declare function resolveCacheResourceUri(uri: string, baseDir?: string): {
18
+ filePath: string;
19
+ relativePath: string;
20
+ } | null;
21
+ export declare function getCacheResourceMimeType(filePath: string): string;
22
+ export declare function buildCacheResourceLink(filePath: string, options?: {
23
+ baseDir?: string;
24
+ name?: string;
25
+ description?: string;
26
+ }): CacheResourceLink | null;
@@ -0,0 +1,106 @@
1
+ import { basename, extname, isAbsolute, join, relative, resolve } from "node:path";
2
+ /**
3
+ * Root directory name for all MCP cache data.
4
+ * Deliberately distinctive to avoid collisions when the server runs from a project root.
5
+ */
6
+ export const CACHE_DIR_NAME = "coalesce_transform_mcp_data_cache";
7
+ export const CACHE_RESOURCE_URI_PREFIX = "coalesce://cache/";
8
+ export function getCacheDir(baseDir) {
9
+ return join(baseDir ?? process.cwd(), CACHE_DIR_NAME);
10
+ }
11
+ function normalizeRelativeCachePath(relativePath) {
12
+ const normalized = relativePath.replace(/\\/g, "/");
13
+ if (!normalized || normalized.startsWith("/") || normalized.includes("\0")) {
14
+ return null;
15
+ }
16
+ const segments = normalized.split("/");
17
+ if (segments.some((segment) => segment.length === 0 || segment === "." || segment === "..")) {
18
+ return null;
19
+ }
20
+ return normalized;
21
+ }
22
+ export function getCacheRelativePath(filePath, baseDir) {
23
+ const cacheDir = resolve(getCacheDir(baseDir));
24
+ const resolvedFilePath = resolve(filePath);
25
+ const relativePath = relative(cacheDir, resolvedFilePath);
26
+ if (!relativePath ||
27
+ relativePath.startsWith("..") ||
28
+ isAbsolute(relativePath)) {
29
+ return null;
30
+ }
31
+ return normalizeRelativeCachePath(relativePath);
32
+ }
33
+ export function buildCacheResourceUri(filePath, baseDir) {
34
+ const relativePath = getCacheRelativePath(filePath, baseDir);
35
+ if (!relativePath) {
36
+ return null;
37
+ }
38
+ const cacheKey = Buffer.from(relativePath, "utf8").toString("base64url");
39
+ return `${CACHE_RESOURCE_URI_PREFIX}${cacheKey}`;
40
+ }
41
+ export function resolveCacheResourceUri(uri, baseDir) {
42
+ let parsedUri;
43
+ try {
44
+ parsedUri = new URL(uri);
45
+ }
46
+ catch {
47
+ return null;
48
+ }
49
+ if (parsedUri.protocol !== "coalesce:" || parsedUri.host !== "cache") {
50
+ return null;
51
+ }
52
+ const cacheKey = parsedUri.pathname.replace(/^\/+/, "");
53
+ if (!cacheKey) {
54
+ return null;
55
+ }
56
+ let relativePath;
57
+ try {
58
+ relativePath = Buffer.from(cacheKey, "base64url").toString("utf8");
59
+ }
60
+ catch {
61
+ return null;
62
+ }
63
+ const normalizedRelativePath = normalizeRelativeCachePath(relativePath);
64
+ if (!normalizedRelativePath) {
65
+ return null;
66
+ }
67
+ const filePath = join(getCacheDir(baseDir), ...normalizedRelativePath.split("/").filter(Boolean));
68
+ const resolvedFilePath = resolve(filePath);
69
+ const resolvedCacheDir = resolve(getCacheDir(baseDir));
70
+ const relativeToCache = relative(resolvedCacheDir, resolvedFilePath);
71
+ if (relativeToCache.startsWith("..") ||
72
+ isAbsolute(relativeToCache)) {
73
+ return null;
74
+ }
75
+ return {
76
+ filePath: resolvedFilePath,
77
+ relativePath: normalizedRelativePath,
78
+ };
79
+ }
80
+ export function getCacheResourceMimeType(filePath) {
81
+ switch (extname(filePath).toLowerCase()) {
82
+ case ".json":
83
+ return "application/json";
84
+ case ".ndjson":
85
+ return "application/x-ndjson";
86
+ case ".md":
87
+ return "text/markdown";
88
+ case ".txt":
89
+ return "text/plain";
90
+ default:
91
+ return "text/plain";
92
+ }
93
+ }
94
+ export function buildCacheResourceLink(filePath, options = {}) {
95
+ const uri = buildCacheResourceUri(filePath, options.baseDir);
96
+ if (!uri) {
97
+ return null;
98
+ }
99
+ return {
100
+ type: "resource_link",
101
+ uri,
102
+ name: options.name ?? basename(filePath),
103
+ mimeType: getCacheResourceMimeType(filePath),
104
+ ...(options.description ? { description: options.description } : {}),
105
+ };
106
+ }
@@ -0,0 +1,25 @@
1
+ export interface ClientConfig {
2
+ accessToken: string;
3
+ baseUrl: string;
4
+ requestTimeoutMs?: number;
5
+ }
6
+ export interface RequestOptions {
7
+ timeoutMs?: number;
8
+ }
9
+ export declare function validateConfig(): ClientConfig;
10
+ export declare class CoalesceApiError extends Error {
11
+ status: number;
12
+ detail?: unknown | undefined;
13
+ constructor(message: string, status: number, detail?: unknown | undefined);
14
+ }
15
+ export interface QueryParams {
16
+ [key: string]: string | number | boolean | undefined;
17
+ }
18
+ export declare function createClient(config: ClientConfig): {
19
+ get(path: string, params?: QueryParams, options?: RequestOptions): Promise<unknown>;
20
+ post(path: string, body?: unknown, params?: QueryParams, options?: RequestOptions): Promise<unknown>;
21
+ put(path: string, body?: unknown, params?: QueryParams, options?: RequestOptions): Promise<unknown>;
22
+ patch(path: string, body?: unknown, params?: QueryParams, options?: RequestOptions): Promise<unknown>;
23
+ delete(path: string, params?: QueryParams, options?: RequestOptions): Promise<unknown>;
24
+ };
25
+ export type CoalesceClient = ReturnType<typeof createClient>;