@burdenoff/mcp-libs 2026.627.3 → 2026.627.5

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 (61) hide show
  1. package/dist/modules/cosmicintersection/index.cjs +1984 -0
  2. package/dist/modules/cosmicintersection/index.cjs.map +1 -0
  3. package/dist/modules/cosmicintersection/index.d.cts +8 -0
  4. package/dist/modules/cosmicintersection/index.d.ts +8 -0
  5. package/dist/modules/cosmicintersection/index.js +1923 -0
  6. package/dist/modules/cosmicintersection/index.js.map +1 -0
  7. package/dist/modules/ecoimpacthub/index.cjs +2042 -0
  8. package/dist/modules/ecoimpacthub/index.cjs.map +1 -0
  9. package/dist/modules/ecoimpacthub/index.d.cts +8 -0
  10. package/dist/modules/ecoimpacthub/index.d.ts +8 -0
  11. package/dist/modules/ecoimpacthub/index.js +1981 -0
  12. package/dist/modules/ecoimpacthub/index.js.map +1 -0
  13. package/dist/modules/govcitizenhub/index.cjs +1686 -0
  14. package/dist/modules/govcitizenhub/index.cjs.map +1 -0
  15. package/dist/modules/govcitizenhub/index.d.cts +8 -0
  16. package/dist/modules/govcitizenhub/index.d.ts +8 -0
  17. package/dist/modules/govcitizenhub/index.js +1625 -0
  18. package/dist/modules/govcitizenhub/index.js.map +1 -0
  19. package/dist/modules/intelwatchtower/index.cjs +1919 -0
  20. package/dist/modules/intelwatchtower/index.cjs.map +1 -0
  21. package/dist/modules/intelwatchtower/index.d.cts +8 -0
  22. package/dist/modules/intelwatchtower/index.d.ts +8 -0
  23. package/dist/modules/intelwatchtower/index.js +1858 -0
  24. package/dist/modules/intelwatchtower/index.js.map +1 -0
  25. package/dist/modules/manufacturedops/index.cjs +1884 -0
  26. package/dist/modules/manufacturedops/index.cjs.map +1 -0
  27. package/dist/modules/manufacturedops/index.d.cts +8 -0
  28. package/dist/modules/manufacturedops/index.d.ts +8 -0
  29. package/dist/modules/manufacturedops/index.js +1823 -0
  30. package/dist/modules/manufacturedops/index.js.map +1 -0
  31. package/dist/modules/mybodyshield/index.cjs +1834 -0
  32. package/dist/modules/mybodyshield/index.cjs.map +1 -0
  33. package/dist/modules/mybodyshield/index.d.cts +8 -0
  34. package/dist/modules/mybodyshield/index.d.ts +8 -0
  35. package/dist/modules/mybodyshield/index.js +1773 -0
  36. package/dist/modules/mybodyshield/index.js.map +1 -0
  37. package/dist/modules/semanticfed/index.cjs +1846 -0
  38. package/dist/modules/semanticfed/index.cjs.map +1 -0
  39. package/dist/modules/semanticfed/index.d.cts +8 -0
  40. package/dist/modules/semanticfed/index.d.ts +8 -0
  41. package/dist/modules/semanticfed/index.js +1785 -0
  42. package/dist/modules/semanticfed/index.js.map +1 -0
  43. package/dist/modules/technospam/index.cjs +1962 -0
  44. package/dist/modules/technospam/index.cjs.map +1 -0
  45. package/dist/modules/technospam/index.d.cts +8 -0
  46. package/dist/modules/technospam/index.d.ts +8 -0
  47. package/dist/modules/technospam/index.js +1901 -0
  48. package/dist/modules/technospam/index.js.map +1 -0
  49. package/dist/modules/theculturepost/index.cjs +1587 -0
  50. package/dist/modules/theculturepost/index.cjs.map +1 -0
  51. package/dist/modules/theculturepost/index.d.cts +8 -0
  52. package/dist/modules/theculturepost/index.d.ts +8 -0
  53. package/dist/modules/theculturepost/index.js +1526 -0
  54. package/dist/modules/theculturepost/index.js.map +1 -0
  55. package/dist/modules/theglobalfuel/index.cjs +1678 -0
  56. package/dist/modules/theglobalfuel/index.cjs.map +1 -0
  57. package/dist/modules/theglobalfuel/index.d.cts +8 -0
  58. package/dist/modules/theglobalfuel/index.d.ts +8 -0
  59. package/dist/modules/theglobalfuel/index.js +1617 -0
  60. package/dist/modules/theglobalfuel/index.js.map +1 -0
  61. package/package.json +1 -1
@@ -0,0 +1,1984 @@
1
+ 'use strict';
2
+
3
+ var zod = require('zod');
4
+ require('graphql-request');
5
+ require('cross-fetch');
6
+ require('@modelcontextprotocol/sdk/server/mcp.js');
7
+ require('@modelcontextprotocol/sdk/types.js');
8
+
9
+ // src/modules/cosmicintersection/tools/sources.ts
10
+
11
+ // src/core/errors.ts
12
+ var McpInternalError = class extends Error {
13
+ cause;
14
+ constructor(message, cause) {
15
+ super(message);
16
+ this.name = "McpInternalError";
17
+ this.cause = cause;
18
+ }
19
+ };
20
+
21
+ // src/core/result.ts
22
+ function jsonResult(data, structured) {
23
+ const result = {
24
+ content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
25
+ };
26
+ return result;
27
+ }
28
+ function errorResult(message, hint) {
29
+ const text = hint ? `${message}
30
+
31
+ Hint: ${hint}` : message;
32
+ return { content: [{ type: "text", text }], isError: true };
33
+ }
34
+
35
+ // src/core/tool-name.ts
36
+ var MAX_TOOL_NAME_LENGTH = 63;
37
+ function assertSafeName(name, kind) {
38
+ if (name.length > MAX_TOOL_NAME_LENGTH) {
39
+ throw new McpInternalError(
40
+ `Tool name '${name}' exceeds ${MAX_TOOL_NAME_LENGTH} characters (some MCP clients truncate at 64).`
41
+ );
42
+ }
43
+ return name;
44
+ }
45
+ function mcpToolName(productName, ...parts) {
46
+ if (!productName) {
47
+ throw new McpInternalError("mcpToolName: productName is required");
48
+ }
49
+ const name = [productName, ...parts].filter(Boolean).join("_");
50
+ return assertSafeName(name);
51
+ }
52
+ function mcpResourceUri(productName, ...parts) {
53
+ if (!productName) {
54
+ throw new McpInternalError("mcpResourceUri: productName is required");
55
+ }
56
+ return `${productName}://${parts.filter(Boolean).join("/")}`;
57
+ }
58
+ function mcpPromptName(productName, ...parts) {
59
+ if (!productName) {
60
+ throw new McpInternalError("mcpPromptName: productName is required");
61
+ }
62
+ return [productName, ...parts].filter(Boolean).join("-");
63
+ }
64
+
65
+ // src/modules/cosmicintersection/operations.ts
66
+ var SOURCE_FIELDS = `
67
+ id name description type status endpoint config tags
68
+ lastSyncedAt createdAt updatedAt workspaceId
69
+ `;
70
+ var DATASET_FIELDS = `
71
+ id name description status accessLevel format collectionId sourceId
72
+ coverage rowCount sizeBytes version ingestedAt lineageCaptured tags
73
+ createdAt updatedAt workspaceId
74
+ `;
75
+ var SCHEMA_FIELD_FIELDS = `
76
+ id datasetId name fieldType description nullable position provenance unit
77
+ createdAt updatedAt workspaceId
78
+ `;
79
+ var COLLECTION_FIELDS = `
80
+ id name slug description isPublic tags createdAt updatedAt workspaceId
81
+ `;
82
+ var PIPELINE_FIELDS = `
83
+ id name description status trigger schedule definition version lastRunAt
84
+ tags createdAt updatedAt workspaceId
85
+ `;
86
+ var STEP_FIELDS = `
87
+ id runId name kind status position inputs outputs logsRef durationMs
88
+ startedAt finishedAt errorMessage createdAt updatedAt workspaceId
89
+ `;
90
+ var RUN_FIELDS = `
91
+ id pipelineId runNumber status params metrics datasetId triggeredBy
92
+ durationMs startedAt finishedAt errorMessage createdAt updatedAt workspaceId
93
+ `;
94
+ var NOTEBOOK_FIELDS = `
95
+ id title description status runtime environment datasetIds isShared
96
+ shareSlug tags createdAt updatedAt workspaceId
97
+ `;
98
+ var ANALYSIS_FIELDS = `
99
+ id title status method aiAssisted datasetId notebookId results
100
+ errorMessage startedAt finishedAt createdAt updatedAt workspaceId
101
+ `;
102
+ var RELEASE_FIELDS = `
103
+ id title version status abstract authors license doi datasetIds
104
+ notebookId publishedAt createdAt updatedAt workspaceId
105
+ `;
106
+ var GRANT_FIELDS = `
107
+ id datasetId granteeId status scopes reason grantedAt expiresAt
108
+ revokedAt createdAt updatedAt workspaceId
109
+ `;
110
+ var GET_SOURCE = `
111
+ query CosmicintersectionGetSource($id: ID!) {
112
+ cosSource(id: $id) {
113
+ ${SOURCE_FIELDS}
114
+ datasets { id name status accessLevel }
115
+ }
116
+ }
117
+ `;
118
+ var LIST_SOURCES = `
119
+ query CosmicintersectionListSources(
120
+ $status: CosSourceStatus
121
+ $type: CosSourceType
122
+ $pagination: PaginationInput
123
+ ) {
124
+ cosListSources(status: $status, type: $type, pagination: $pagination) {
125
+ items { ${SOURCE_FIELDS} }
126
+ pageInfo { cursor hasMore }
127
+ }
128
+ }
129
+ `;
130
+ var CREATE_SOURCE = `
131
+ mutation CosmicintersectionCreateSource($input: CosCreateSourceInput!) {
132
+ cosCreateSource(input: $input) {
133
+ ${SOURCE_FIELDS}
134
+ }
135
+ }
136
+ `;
137
+ var UPDATE_SOURCE = `
138
+ mutation CosmicintersectionUpdateSource($id: ID!, $input: CosUpdateSourceInput!) {
139
+ cosUpdateSource(id: $id, input: $input) {
140
+ ${SOURCE_FIELDS}
141
+ }
142
+ }
143
+ `;
144
+ var ARCHIVE_SOURCE = `
145
+ mutation CosmicintersectionArchiveSource($id: ID!) {
146
+ cosArchiveSource(id: $id)
147
+ }
148
+ `;
149
+ var MARK_SOURCE_SYNCED = `
150
+ mutation CosmicintersectionMarkSourceSynced($id: ID!) {
151
+ cosMarkSourceSynced(id: $id) {
152
+ ${SOURCE_FIELDS}
153
+ }
154
+ }
155
+ `;
156
+ var GET_DATASET = `
157
+ query CosmicintersectionGetDataset($id: ID!) {
158
+ cosDataset(id: $id) {
159
+ ${DATASET_FIELDS}
160
+ collection { id name slug }
161
+ source { id name type status }
162
+ schemaFields { ${SCHEMA_FIELD_FIELDS} }
163
+ }
164
+ }
165
+ `;
166
+ var LIST_DATASETS = `
167
+ query CosmicintersectionListDatasets(
168
+ $collectionId: ID
169
+ $sourceId: ID
170
+ $status: CosDatasetStatus
171
+ $pagination: PaginationInput
172
+ ) {
173
+ cosListDatasets(
174
+ collectionId: $collectionId
175
+ sourceId: $sourceId
176
+ status: $status
177
+ pagination: $pagination
178
+ ) {
179
+ items { ${DATASET_FIELDS} }
180
+ pageInfo { cursor hasMore }
181
+ }
182
+ }
183
+ `;
184
+ var CREATE_DATASET = `
185
+ mutation CosmicintersectionCreateDataset($input: CosCreateDatasetInput!) {
186
+ cosCreateDataset(input: $input) {
187
+ ${DATASET_FIELDS}
188
+ }
189
+ }
190
+ `;
191
+ var UPDATE_DATASET = `
192
+ mutation CosmicintersectionUpdateDataset($id: ID!, $input: CosUpdateDatasetInput!) {
193
+ cosUpdateDataset(id: $id, input: $input) {
194
+ ${DATASET_FIELDS}
195
+ }
196
+ }
197
+ `;
198
+ var ARCHIVE_DATASET = `
199
+ mutation CosmicintersectionArchiveDataset($id: ID!) {
200
+ cosArchiveDataset(id: $id)
201
+ }
202
+ `;
203
+ var PUBLISH_DATASET = `
204
+ mutation CosmicintersectionPublishDataset($id: ID!) {
205
+ cosPublishDataset(id: $id) {
206
+ ${DATASET_FIELDS}
207
+ }
208
+ }
209
+ `;
210
+ var LIST_SCHEMA_FIELDS = `
211
+ query CosmicintersectionListSchemaFields($datasetId: ID!) {
212
+ cosListSchemaFields(datasetId: $datasetId) {
213
+ ${SCHEMA_FIELD_FIELDS}
214
+ }
215
+ }
216
+ `;
217
+ var ADD_SCHEMA_FIELD = `
218
+ mutation CosmicintersectionAddSchemaField($input: CosAddSchemaFieldInput!) {
219
+ cosAddSchemaField(input: $input) {
220
+ ${SCHEMA_FIELD_FIELDS}
221
+ }
222
+ }
223
+ `;
224
+ var LIST_COLLECTIONS = `
225
+ query CosmicintersectionListCollections {
226
+ cosListCollections {
227
+ ${COLLECTION_FIELDS}
228
+ datasets { id name status accessLevel }
229
+ }
230
+ }
231
+ `;
232
+ var CREATE_COLLECTION = `
233
+ mutation CosmicintersectionCreateCollection($input: CosCreateCollectionInput!) {
234
+ cosCreateCollection(input: $input) {
235
+ ${COLLECTION_FIELDS}
236
+ }
237
+ }
238
+ `;
239
+ var GET_PIPELINE = `
240
+ query CosmicintersectionGetPipeline($id: ID!) {
241
+ cosPipeline(id: $id) {
242
+ ${PIPELINE_FIELDS}
243
+ runs { id runNumber status startedAt finishedAt }
244
+ }
245
+ }
246
+ `;
247
+ var LIST_PIPELINES = `
248
+ query CosmicintersectionListPipelines(
249
+ $status: CosPipelineStatus
250
+ $pagination: PaginationInput
251
+ ) {
252
+ cosListPipelines(status: $status, pagination: $pagination) {
253
+ items { ${PIPELINE_FIELDS} }
254
+ pageInfo { cursor hasMore }
255
+ }
256
+ }
257
+ `;
258
+ var CREATE_PIPELINE = `
259
+ mutation CosmicintersectionCreatePipeline($input: CosCreatePipelineInput!) {
260
+ cosCreatePipeline(input: $input) {
261
+ ${PIPELINE_FIELDS}
262
+ }
263
+ }
264
+ `;
265
+ var UPDATE_PIPELINE = `
266
+ mutation CosmicintersectionUpdatePipeline($id: ID!, $input: CosUpdatePipelineInput!) {
267
+ cosUpdatePipeline(id: $id, input: $input) {
268
+ ${PIPELINE_FIELDS}
269
+ }
270
+ }
271
+ `;
272
+ var ARCHIVE_PIPELINE = `
273
+ mutation CosmicintersectionArchivePipeline($id: ID!) {
274
+ cosArchivePipeline(id: $id)
275
+ }
276
+ `;
277
+ var GET_RUN = `
278
+ query CosmicintersectionGetRun($id: ID!) {
279
+ cosRun(id: $id) {
280
+ ${RUN_FIELDS}
281
+ pipeline { id name status }
282
+ steps { ${STEP_FIELDS} }
283
+ }
284
+ }
285
+ `;
286
+ var LIST_RUNS = `
287
+ query CosmicintersectionListRuns(
288
+ $pipelineId: ID
289
+ $status: CosRunStatus
290
+ $pagination: PaginationInput
291
+ ) {
292
+ cosListRuns(pipelineId: $pipelineId, status: $status, pagination: $pagination) {
293
+ items { ${RUN_FIELDS} }
294
+ pageInfo { cursor hasMore }
295
+ }
296
+ }
297
+ `;
298
+ var START_RUN = `
299
+ mutation CosmicintersectionStartRun($input: CosStartRunInput!) {
300
+ cosStartRun(input: $input) {
301
+ ${RUN_FIELDS}
302
+ }
303
+ }
304
+ `;
305
+ var TRANSITION_RUN = `
306
+ mutation CosmicintersectionTransitionRun($id: ID!, $status: CosRunStatus!) {
307
+ cosTransitionRun(id: $id, status: $status) {
308
+ ${RUN_FIELDS}
309
+ }
310
+ }
311
+ `;
312
+ var LIST_RUN_STEPS = `
313
+ query CosmicintersectionListRunSteps($runId: ID!) {
314
+ cosListRunSteps(runId: $runId) {
315
+ ${STEP_FIELDS}
316
+ }
317
+ }
318
+ `;
319
+ var ADD_RUN_STEP = `
320
+ mutation CosmicintersectionAddRunStep($input: CosAddRunStepInput!) {
321
+ cosAddRunStep(input: $input) {
322
+ ${STEP_FIELDS}
323
+ }
324
+ }
325
+ `;
326
+ var GET_NOTEBOOK = `
327
+ query CosmicintersectionGetNotebook($id: ID!) {
328
+ cosNotebook(id: $id) {
329
+ ${NOTEBOOK_FIELDS}
330
+ analyses { ${ANALYSIS_FIELDS} }
331
+ releases { id title version status }
332
+ }
333
+ }
334
+ `;
335
+ var LIST_NOTEBOOKS = `
336
+ query CosmicintersectionListNotebooks(
337
+ $status: CosNotebookStatus
338
+ $pagination: PaginationInput
339
+ ) {
340
+ cosListNotebooks(status: $status, pagination: $pagination) {
341
+ items { ${NOTEBOOK_FIELDS} }
342
+ pageInfo { cursor hasMore }
343
+ }
344
+ }
345
+ `;
346
+ var CREATE_NOTEBOOK = `
347
+ mutation CosmicintersectionCreateNotebook($input: CosCreateNotebookInput!) {
348
+ cosCreateNotebook(input: $input) {
349
+ ${NOTEBOOK_FIELDS}
350
+ }
351
+ }
352
+ `;
353
+ var UPDATE_NOTEBOOK = `
354
+ mutation CosmicintersectionUpdateNotebook($id: ID!, $input: CosUpdateNotebookInput!) {
355
+ cosUpdateNotebook(id: $id, input: $input) {
356
+ ${NOTEBOOK_FIELDS}
357
+ }
358
+ }
359
+ `;
360
+ var ARCHIVE_NOTEBOOK = `
361
+ mutation CosmicintersectionArchiveNotebook($id: ID!) {
362
+ cosArchiveNotebook(id: $id)
363
+ }
364
+ `;
365
+ var LIST_ANALYSES = `
366
+ query CosmicintersectionListAnalyses(
367
+ $datasetId: ID
368
+ $notebookId: ID
369
+ $status: CosAnalysisStatus
370
+ ) {
371
+ cosListAnalyses(datasetId: $datasetId, notebookId: $notebookId, status: $status) {
372
+ ${ANALYSIS_FIELDS}
373
+ }
374
+ }
375
+ `;
376
+ var RUN_ANALYSIS = `
377
+ mutation CosmicintersectionRunAnalysis($input: CosRunAnalysisInput!) {
378
+ cosRunAnalysis(input: $input) {
379
+ ${ANALYSIS_FIELDS}
380
+ }
381
+ }
382
+ `;
383
+ var COMPLETE_ANALYSIS = `
384
+ mutation CosmicintersectionCompleteAnalysis(
385
+ $id: ID!
386
+ $status: CosAnalysisStatus!
387
+ $results: JSON
388
+ $outputFileId: ID
389
+ ) {
390
+ cosCompleteAnalysis(
391
+ id: $id
392
+ status: $status
393
+ results: $results
394
+ outputFileId: $outputFileId
395
+ ) {
396
+ ${ANALYSIS_FIELDS}
397
+ }
398
+ }
399
+ `;
400
+ var LIST_RELEASES = `
401
+ query CosmicintersectionListReleases(
402
+ $status: CosReleaseStatus
403
+ $pagination: PaginationInput
404
+ ) {
405
+ cosListReleases(status: $status, pagination: $pagination) {
406
+ items { ${RELEASE_FIELDS} }
407
+ pageInfo { cursor hasMore }
408
+ }
409
+ }
410
+ `;
411
+ var CREATE_RELEASE = `
412
+ mutation CosmicintersectionCreateRelease($input: CosCreateReleaseInput!) {
413
+ cosCreateRelease(input: $input) {
414
+ ${RELEASE_FIELDS}
415
+ }
416
+ }
417
+ `;
418
+ var PUBLISH_RELEASE = `
419
+ mutation CosmicintersectionPublishRelease($id: ID!, $doi: String) {
420
+ cosPublishRelease(id: $id, doi: $doi) {
421
+ ${RELEASE_FIELDS}
422
+ }
423
+ }
424
+ `;
425
+ var LIST_ACCESS_GRANTS = `
426
+ query CosmicintersectionListAccessGrants($datasetId: ID, $status: CosGrantStatus) {
427
+ cosListAccessGrants(datasetId: $datasetId, status: $status) {
428
+ ${GRANT_FIELDS}
429
+ }
430
+ }
431
+ `;
432
+ var GRANT_ACCESS = `
433
+ mutation CosmicintersectionGrantAccess($input: CosGrantAccessInput!) {
434
+ cosGrantAccess(input: $input) {
435
+ ${GRANT_FIELDS}
436
+ }
437
+ }
438
+ `;
439
+ var REVOKE_ACCESS = `
440
+ mutation CosmicintersectionRevokeAccess($id: ID!) {
441
+ cosRevokeAccess(id: $id) {
442
+ ${GRANT_FIELDS}
443
+ }
444
+ }
445
+ `;
446
+ var HEALTH = `
447
+ query CosmicintersectionHealth {
448
+ cosHealth
449
+ }
450
+ `;
451
+ var CosSourceTypeEnum = zod.z.enum([
452
+ "API",
453
+ "ARCHIVE",
454
+ "FILE_DROP",
455
+ "GROUND_SENSOR",
456
+ "SATELLITE",
457
+ "SIMULATION",
458
+ "STREAM",
459
+ "TELESCOPE"
460
+ ]).describe("Kind of upstream data source / connector");
461
+ var CosSourceStatusEnum = zod.z.enum(["CONFIGURING", "CONNECTED", "DEGRADED", "DISABLED", "ERROR", "SYNCING"]).describe("Lifecycle/connectivity status of a source");
462
+ var CosDatasetStatusEnum = zod.z.enum(["ARCHIVED", "AVAILABLE", "DEPRECATED", "DRAFT", "INGESTING"]).describe("Lifecycle status of a dataset");
463
+ var CosAccessLevelEnum = zod.z.enum(["EMBARGOED", "PUBLIC", "RESTRICTED", "WORKSPACE"]).describe("Visibility/access level of a dataset");
464
+ var CosFieldTypeEnum = zod.z.enum([
465
+ "BOOLEAN",
466
+ "COORDINATE",
467
+ "FLOAT",
468
+ "GEOMETRY",
469
+ "IMAGE_REF",
470
+ "INTEGER",
471
+ "JSON",
472
+ "SPECTRUM",
473
+ "STRING",
474
+ "TIMESTAMP"
475
+ ]).describe("Logical type of a dataset schema field");
476
+ var CosPipelineStatusEnum = zod.z.enum(["ACTIVE", "ARCHIVED", "DRAFT", "PAUSED"]).describe("Lifecycle status of a processing pipeline");
477
+ var CosPipelineTriggerEnum = zod.z.enum(["MANUAL", "ON_INGEST", "SCHEDULED", "WEBHOOK"]).describe("How a pipeline is triggered");
478
+ var CosRunStatusEnum = zod.z.enum(["CANCELLED", "FAILED", "QUEUED", "RUNNING", "SUCCEEDED"]).describe("Lifecycle status of a pipeline run or step");
479
+ var CosStepKindEnum = zod.z.enum(["ANALYZE", "CALIBRATE", "EXPORT", "INGEST", "NOTIFY", "TRANSFORM"]).describe("Kind of work a run step performs");
480
+ var CosNotebookStatusEnum = zod.z.enum(["ARCHIVED", "DRAFT", "PUBLISHED", "RUNNING"]).describe("Lifecycle status of a research notebook");
481
+ var CosAnalysisStatusEnum = zod.z.enum(["COMPLETED", "FAILED", "PENDING", "RUNNING"]).describe("Lifecycle status of an analysis run");
482
+ var CosReleaseStatusEnum = zod.z.enum(["DRAFT", "PUBLISHED", "RETRACTED", "UNDER_REVIEW"]).describe("Lifecycle status of a citable release");
483
+ var CosGrantStatusEnum = zod.z.enum(["ACTIVE", "EXPIRED", "PENDING", "REVOKED"]).describe("Status of a dataset access grant");
484
+ var JsonObject = zod.z.record(zod.z.string(), zod.z.unknown());
485
+
486
+ // src/modules/cosmicintersection/tools/sources.ts
487
+ function registerSourceTools(server, ctx, track) {
488
+ server.registerTool(
489
+ track(mcpToolName(ctx.productName, "sources_get")),
490
+ {
491
+ title: "Get Source",
492
+ description: "Fetch a single Cosmicintersection data source by ID, including the datasets ingested from it.",
493
+ inputSchema: { id: zod.z.string().describe("Source ID") }
494
+ },
495
+ async ({ id }) => {
496
+ try {
497
+ const data = await ctx.gql.workspace.request(GET_SOURCE, { id });
498
+ if (!data.cosSource) return errorResult(`Source ${id} not found`);
499
+ return jsonResult(data.cosSource);
500
+ } catch (error) {
501
+ ctx.logger.error("cosmicintersection sources_get failed", { error: String(error) });
502
+ return errorResult(
503
+ `Failed to get source: ${error instanceof Error ? error.message : String(error)}`
504
+ );
505
+ }
506
+ }
507
+ );
508
+ server.registerTool(
509
+ track(mcpToolName(ctx.productName, "sources_list")),
510
+ {
511
+ title: "List Sources",
512
+ description: "List data sources in the bound workspace with optional type/status filters and pagination (returns a connection: { items, pageInfo }).",
513
+ inputSchema: {
514
+ type: CosSourceTypeEnum.optional().describe("Filter by source type"),
515
+ status: CosSourceStatusEnum.optional().describe("Filter by connectivity status"),
516
+ limit: zod.z.number().int().optional().describe("Page size (default 50)"),
517
+ offset: zod.z.number().int().optional().describe("Pagination offset (default 0)"),
518
+ cursor: zod.z.string().optional().describe("Opaque pagination cursor")
519
+ }
520
+ },
521
+ async ({ type, status, limit, offset, cursor }) => {
522
+ try {
523
+ const pagination = {};
524
+ if (limit !== void 0) pagination.limit = limit;
525
+ if (offset !== void 0) pagination.offset = offset;
526
+ if (cursor !== void 0) pagination.cursor = cursor;
527
+ const data = await ctx.gql.workspace.request(LIST_SOURCES, {
528
+ type,
529
+ status,
530
+ pagination: Object.keys(pagination).length > 0 ? pagination : void 0
531
+ });
532
+ return jsonResult(data.cosListSources);
533
+ } catch (error) {
534
+ ctx.logger.error("cosmicintersection sources_list failed", { error: String(error) });
535
+ return errorResult(
536
+ `Failed to list sources: ${error instanceof Error ? error.message : String(error)}`
537
+ );
538
+ }
539
+ }
540
+ );
541
+ server.registerTool(
542
+ track(mcpToolName(ctx.productName, "sources_create")),
543
+ {
544
+ title: "Create Source",
545
+ description: "Register a new data source / connector. Defaults: type=ARCHIVE, status=CONFIGURING.",
546
+ inputSchema: {
547
+ name: zod.z.string().min(1).describe("Source display name"),
548
+ type: CosSourceTypeEnum.optional().describe("Source type (default ARCHIVE)"),
549
+ status: CosSourceStatusEnum.optional().describe("Initial status (default CONFIGURING)"),
550
+ description: zod.z.string().optional().describe("Source description"),
551
+ endpoint: zod.z.string().optional().describe("Connection endpoint / URL"),
552
+ credentialRef: zod.z.string().optional().describe("Reference to a stored credential"),
553
+ config: JsonObject.optional().describe("Connector configuration JSON"),
554
+ tags: zod.z.array(zod.z.string()).optional().describe("Free-form tags")
555
+ }
556
+ },
557
+ async ({ name, type, status, description, endpoint, credentialRef, config, tags }) => {
558
+ try {
559
+ const input = { name };
560
+ if (type !== void 0) input.type = type;
561
+ if (status !== void 0) input.status = status;
562
+ if (description !== void 0) input.description = description;
563
+ if (endpoint !== void 0) input.endpoint = endpoint;
564
+ if (credentialRef !== void 0) input.credentialRef = credentialRef;
565
+ if (config !== void 0) input.config = config;
566
+ if (tags !== void 0) input.tags = tags;
567
+ const data = await ctx.gql.workspace.request(CREATE_SOURCE, { input });
568
+ return jsonResult(data.cosCreateSource);
569
+ } catch (error) {
570
+ ctx.logger.error("cosmicintersection sources_create failed", { error: String(error) });
571
+ return errorResult(
572
+ `Failed to create source: ${error instanceof Error ? error.message : String(error)}`
573
+ );
574
+ }
575
+ }
576
+ );
577
+ server.registerTool(
578
+ track(mcpToolName(ctx.productName, "sources_update")),
579
+ {
580
+ title: "Update Source",
581
+ description: "Update a data source. At least one mutable field must be provided.",
582
+ inputSchema: {
583
+ id: zod.z.string().describe("Source ID"),
584
+ name: zod.z.string().optional().describe("Updated display name"),
585
+ type: CosSourceTypeEnum.optional().describe("Updated source type"),
586
+ status: CosSourceStatusEnum.optional().describe("Updated status"),
587
+ description: zod.z.string().optional().describe("Updated description"),
588
+ endpoint: zod.z.string().optional().describe("Updated endpoint"),
589
+ credentialRef: zod.z.string().optional().describe("Updated credential reference"),
590
+ config: JsonObject.optional().describe("Updated connector configuration JSON"),
591
+ tags: zod.z.array(zod.z.string()).optional().describe("Updated tags")
592
+ }
593
+ },
594
+ async ({ id, name, type, status, description, endpoint, credentialRef, config, tags }) => {
595
+ try {
596
+ const input = {};
597
+ if (name !== void 0) input.name = name;
598
+ if (type !== void 0) input.type = type;
599
+ if (status !== void 0) input.status = status;
600
+ if (description !== void 0) input.description = description;
601
+ if (endpoint !== void 0) input.endpoint = endpoint;
602
+ if (credentialRef !== void 0) input.credentialRef = credentialRef;
603
+ if (config !== void 0) input.config = config;
604
+ if (tags !== void 0) input.tags = tags;
605
+ if (Object.keys(input).length === 0) {
606
+ return errorResult(
607
+ "No updates specified \u2014 provide at least one of name/type/status/description/endpoint/credentialRef/config/tags"
608
+ );
609
+ }
610
+ const data = await ctx.gql.workspace.request(UPDATE_SOURCE, { id, input });
611
+ return jsonResult(data.cosUpdateSource);
612
+ } catch (error) {
613
+ ctx.logger.error("cosmicintersection sources_update failed", { error: String(error) });
614
+ return errorResult(
615
+ `Failed to update source: ${error instanceof Error ? error.message : String(error)}`
616
+ );
617
+ }
618
+ }
619
+ );
620
+ server.registerTool(
621
+ track(mcpToolName(ctx.productName, "sources_archive")),
622
+ {
623
+ title: "Archive Source",
624
+ description: "Archive (soft-delete) a data source. Returns true on success.",
625
+ inputSchema: { id: zod.z.string().describe("Source ID") }
626
+ },
627
+ async ({ id }) => {
628
+ try {
629
+ const data = await ctx.gql.workspace.request(
630
+ ARCHIVE_SOURCE,
631
+ { id }
632
+ );
633
+ return jsonResult({ archived: data.cosArchiveSource });
634
+ } catch (error) {
635
+ ctx.logger.error("cosmicintersection sources_archive failed", { error: String(error) });
636
+ return errorResult(
637
+ `Failed to archive source: ${error instanceof Error ? error.message : String(error)}`
638
+ );
639
+ }
640
+ }
641
+ );
642
+ server.registerTool(
643
+ track(mcpToolName(ctx.productName, "sources_mark_synced")),
644
+ {
645
+ title: "Mark Source Synced",
646
+ description: "Record a successful sync for a source (sets status CONNECTED + lastSyncedAt).",
647
+ inputSchema: { id: zod.z.string().describe("Source ID") }
648
+ },
649
+ async ({ id }) => {
650
+ try {
651
+ const data = await ctx.gql.workspace.request(MARK_SOURCE_SYNCED, { id });
652
+ return jsonResult(data.cosMarkSourceSynced);
653
+ } catch (error) {
654
+ ctx.logger.error("cosmicintersection sources_mark_synced failed", {
655
+ error: String(error)
656
+ });
657
+ return errorResult(
658
+ `Failed to mark source synced: ${error instanceof Error ? error.message : String(error)}`
659
+ );
660
+ }
661
+ }
662
+ );
663
+ }
664
+ function registerDatasetTools(server, ctx, track) {
665
+ server.registerTool(
666
+ track(mcpToolName(ctx.productName, "datasets_get")),
667
+ {
668
+ title: "Get Dataset",
669
+ description: "Fetch a single dataset by ID, including its collection, source, and schema fields.",
670
+ inputSchema: { id: zod.z.string().describe("Dataset ID") }
671
+ },
672
+ async ({ id }) => {
673
+ try {
674
+ const data = await ctx.gql.workspace.request(GET_DATASET, { id });
675
+ if (!data.cosDataset) return errorResult(`Dataset ${id} not found`);
676
+ return jsonResult(data.cosDataset);
677
+ } catch (error) {
678
+ ctx.logger.error("cosmicintersection datasets_get failed", { error: String(error) });
679
+ return errorResult(
680
+ `Failed to get dataset: ${error instanceof Error ? error.message : String(error)}`
681
+ );
682
+ }
683
+ }
684
+ );
685
+ server.registerTool(
686
+ track(mcpToolName(ctx.productName, "datasets_list")),
687
+ {
688
+ title: "List Datasets",
689
+ description: "List datasets in the bound workspace with optional collection/source/status filters and pagination (returns a connection: { items, pageInfo }).",
690
+ inputSchema: {
691
+ collectionId: zod.z.string().optional().describe("Filter by collection ID"),
692
+ sourceId: zod.z.string().optional().describe("Filter by source ID"),
693
+ status: CosDatasetStatusEnum.optional().describe("Filter by lifecycle status"),
694
+ limit: zod.z.number().int().optional().describe("Page size (default 50)"),
695
+ offset: zod.z.number().int().optional().describe("Pagination offset (default 0)"),
696
+ cursor: zod.z.string().optional().describe("Opaque pagination cursor")
697
+ }
698
+ },
699
+ async ({ collectionId, sourceId, status, limit, offset, cursor }) => {
700
+ try {
701
+ const pagination = {};
702
+ if (limit !== void 0) pagination.limit = limit;
703
+ if (offset !== void 0) pagination.offset = offset;
704
+ if (cursor !== void 0) pagination.cursor = cursor;
705
+ const data = await ctx.gql.workspace.request(LIST_DATASETS, {
706
+ collectionId,
707
+ sourceId,
708
+ status,
709
+ pagination: Object.keys(pagination).length > 0 ? pagination : void 0
710
+ });
711
+ return jsonResult(data.cosListDatasets);
712
+ } catch (error) {
713
+ ctx.logger.error("cosmicintersection datasets_list failed", { error: String(error) });
714
+ return errorResult(
715
+ `Failed to list datasets: ${error instanceof Error ? error.message : String(error)}`
716
+ );
717
+ }
718
+ }
719
+ );
720
+ server.registerTool(
721
+ track(mcpToolName(ctx.productName, "datasets_create")),
722
+ {
723
+ title: "Create Dataset",
724
+ description: "Register a new dataset in the catalog. Defaults: accessLevel=WORKSPACE, status=DRAFT. Reference a wspace-files-svc File via fileId for the raw artifact.",
725
+ inputSchema: {
726
+ name: zod.z.string().min(1).describe("Dataset name"),
727
+ accessLevel: CosAccessLevelEnum.optional().describe("Access level (default WORKSPACE)"),
728
+ status: CosDatasetStatusEnum.optional().describe("Initial status (default DRAFT)"),
729
+ description: zod.z.string().optional().describe("Dataset description"),
730
+ collectionId: zod.z.string().optional().describe("Parent collection ID"),
731
+ sourceId: zod.z.string().optional().describe("Originating source ID"),
732
+ fileId: zod.z.string().optional().describe("wspace-files-svc File ID for the raw artifact"),
733
+ format: zod.z.string().optional().describe("Data format (e.g. csv, parquet, fits)"),
734
+ coverage: JsonObject.optional().describe("Spatial/temporal coverage JSON"),
735
+ tags: zod.z.array(zod.z.string()).optional().describe("Free-form tags")
736
+ }
737
+ },
738
+ async ({
739
+ name,
740
+ accessLevel,
741
+ status,
742
+ description,
743
+ collectionId,
744
+ sourceId,
745
+ fileId,
746
+ format,
747
+ coverage,
748
+ tags
749
+ }) => {
750
+ try {
751
+ const input = { name };
752
+ if (accessLevel !== void 0) input.accessLevel = accessLevel;
753
+ if (status !== void 0) input.status = status;
754
+ if (description !== void 0) input.description = description;
755
+ if (collectionId !== void 0) input.collectionId = collectionId;
756
+ if (sourceId !== void 0) input.sourceId = sourceId;
757
+ if (fileId !== void 0) input.fileId = fileId;
758
+ if (format !== void 0) input.format = format;
759
+ if (coverage !== void 0) input.coverage = coverage;
760
+ if (tags !== void 0) input.tags = tags;
761
+ const data = await ctx.gql.workspace.request(CREATE_DATASET, { input });
762
+ return jsonResult(data.cosCreateDataset);
763
+ } catch (error) {
764
+ ctx.logger.error("cosmicintersection datasets_create failed", { error: String(error) });
765
+ return errorResult(
766
+ `Failed to create dataset: ${error instanceof Error ? error.message : String(error)}`
767
+ );
768
+ }
769
+ }
770
+ );
771
+ server.registerTool(
772
+ track(mcpToolName(ctx.productName, "datasets_update")),
773
+ {
774
+ title: "Update Dataset",
775
+ description: "Update a dataset. At least one mutable field must be provided.",
776
+ inputSchema: {
777
+ id: zod.z.string().describe("Dataset ID"),
778
+ name: zod.z.string().optional().describe("Updated name"),
779
+ accessLevel: CosAccessLevelEnum.optional().describe("Updated access level"),
780
+ description: zod.z.string().optional().describe("Updated description"),
781
+ collectionId: zod.z.string().optional().describe("Updated collection ID"),
782
+ format: zod.z.string().optional().describe("Updated data format"),
783
+ coverage: JsonObject.optional().describe("Updated coverage JSON"),
784
+ tags: zod.z.array(zod.z.string()).optional().describe("Updated tags")
785
+ }
786
+ },
787
+ async ({ id, name, accessLevel, description, collectionId, format, coverage, tags }) => {
788
+ try {
789
+ const input = {};
790
+ if (name !== void 0) input.name = name;
791
+ if (accessLevel !== void 0) input.accessLevel = accessLevel;
792
+ if (description !== void 0) input.description = description;
793
+ if (collectionId !== void 0) input.collectionId = collectionId;
794
+ if (format !== void 0) input.format = format;
795
+ if (coverage !== void 0) input.coverage = coverage;
796
+ if (tags !== void 0) input.tags = tags;
797
+ if (Object.keys(input).length === 0) {
798
+ return errorResult(
799
+ "No updates specified \u2014 provide at least one of name/accessLevel/description/collectionId/format/coverage/tags"
800
+ );
801
+ }
802
+ const data = await ctx.gql.workspace.request(UPDATE_DATASET, { id, input });
803
+ return jsonResult(data.cosUpdateDataset);
804
+ } catch (error) {
805
+ ctx.logger.error("cosmicintersection datasets_update failed", { error: String(error) });
806
+ return errorResult(
807
+ `Failed to update dataset: ${error instanceof Error ? error.message : String(error)}`
808
+ );
809
+ }
810
+ }
811
+ );
812
+ server.registerTool(
813
+ track(mcpToolName(ctx.productName, "datasets_archive")),
814
+ {
815
+ title: "Archive Dataset",
816
+ description: "Archive (soft-delete) a dataset. Returns true on success.",
817
+ inputSchema: { id: zod.z.string().describe("Dataset ID") }
818
+ },
819
+ async ({ id }) => {
820
+ try {
821
+ const data = await ctx.gql.workspace.request(
822
+ ARCHIVE_DATASET,
823
+ { id }
824
+ );
825
+ return jsonResult({ archived: data.cosArchiveDataset });
826
+ } catch (error) {
827
+ ctx.logger.error("cosmicintersection datasets_archive failed", { error: String(error) });
828
+ return errorResult(
829
+ `Failed to archive dataset: ${error instanceof Error ? error.message : String(error)}`
830
+ );
831
+ }
832
+ }
833
+ );
834
+ server.registerTool(
835
+ track(mcpToolName(ctx.productName, "datasets_publish")),
836
+ {
837
+ title: "Publish Dataset",
838
+ description: "Mark a dataset AVAILABLE once ingestion completes (sets ingestedAt).",
839
+ inputSchema: { id: zod.z.string().describe("Dataset ID") }
840
+ },
841
+ async ({ id }) => {
842
+ try {
843
+ const data = await ctx.gql.workspace.request(PUBLISH_DATASET, { id });
844
+ return jsonResult(data.cosPublishDataset);
845
+ } catch (error) {
846
+ ctx.logger.error("cosmicintersection datasets_publish failed", { error: String(error) });
847
+ return errorResult(
848
+ `Failed to publish dataset: ${error instanceof Error ? error.message : String(error)}`
849
+ );
850
+ }
851
+ }
852
+ );
853
+ server.registerTool(
854
+ track(mcpToolName(ctx.productName, "datasets_fields_list")),
855
+ {
856
+ title: "List Schema Fields",
857
+ description: "List the schema fields (columns) of a dataset.",
858
+ inputSchema: { datasetId: zod.z.string().describe("Dataset ID") }
859
+ },
860
+ async ({ datasetId }) => {
861
+ try {
862
+ const data = await ctx.gql.workspace.request(LIST_SCHEMA_FIELDS, { datasetId });
863
+ return jsonResult(data.cosListSchemaFields);
864
+ } catch (error) {
865
+ ctx.logger.error("cosmicintersection datasets_fields_list failed", {
866
+ error: String(error)
867
+ });
868
+ return errorResult(
869
+ `Failed to list schema fields: ${error instanceof Error ? error.message : String(error)}`
870
+ );
871
+ }
872
+ }
873
+ );
874
+ server.registerTool(
875
+ track(mcpToolName(ctx.productName, "datasets_fields_add")),
876
+ {
877
+ title: "Add Schema Field",
878
+ description: "Add a schema field (column) to a dataset. Defaults: fieldType=STRING, nullable=true.",
879
+ inputSchema: {
880
+ datasetId: zod.z.string().describe("Dataset ID"),
881
+ name: zod.z.string().min(1).describe("Field name"),
882
+ fieldType: CosFieldTypeEnum.optional().describe("Field logical type (default STRING)"),
883
+ description: zod.z.string().optional().describe("Field description"),
884
+ nullable: zod.z.boolean().optional().describe("Whether the field is nullable (default true)"),
885
+ position: zod.z.number().int().optional().describe("Ordinal position in the schema"),
886
+ provenance: zod.z.string().optional().describe("Provenance / derivation note"),
887
+ unit: zod.z.string().optional().describe("Physical unit (e.g. arcsec, Jy)")
888
+ }
889
+ },
890
+ async ({ datasetId, name, fieldType, description, nullable, position, provenance, unit }) => {
891
+ try {
892
+ const input = { datasetId, name };
893
+ if (fieldType !== void 0) input.fieldType = fieldType;
894
+ if (description !== void 0) input.description = description;
895
+ if (nullable !== void 0) input.nullable = nullable;
896
+ if (position !== void 0) input.position = position;
897
+ if (provenance !== void 0) input.provenance = provenance;
898
+ if (unit !== void 0) input.unit = unit;
899
+ const data = await ctx.gql.workspace.request(ADD_SCHEMA_FIELD, { input });
900
+ return jsonResult(data.cosAddSchemaField);
901
+ } catch (error) {
902
+ ctx.logger.error("cosmicintersection datasets_fields_add failed", {
903
+ error: String(error)
904
+ });
905
+ return errorResult(
906
+ `Failed to add schema field: ${error instanceof Error ? error.message : String(error)}`
907
+ );
908
+ }
909
+ }
910
+ );
911
+ }
912
+ function registerCollectionTools(server, ctx, track) {
913
+ server.registerTool(
914
+ track(mcpToolName(ctx.productName, "collections_list")),
915
+ {
916
+ title: "List Collections",
917
+ description: "List all dataset collections in the bound workspace, with their datasets.",
918
+ inputSchema: {}
919
+ },
920
+ async () => {
921
+ try {
922
+ const data = await ctx.gql.workspace.request(LIST_COLLECTIONS, {});
923
+ return jsonResult(data.cosListCollections);
924
+ } catch (error) {
925
+ ctx.logger.error("cosmicintersection collections_list failed", { error: String(error) });
926
+ return errorResult(
927
+ `Failed to list collections: ${error instanceof Error ? error.message : String(error)}`
928
+ );
929
+ }
930
+ }
931
+ );
932
+ server.registerTool(
933
+ track(mcpToolName(ctx.productName, "collections_create")),
934
+ {
935
+ title: "Create Collection",
936
+ description: "Create a dataset collection. Defaults: isPublic=false.",
937
+ inputSchema: {
938
+ name: zod.z.string().min(1).describe("Collection name"),
939
+ slug: zod.z.string().optional().describe("URL slug, unique within the workspace"),
940
+ description: zod.z.string().optional().describe("Collection description"),
941
+ isPublic: zod.z.boolean().optional().describe("Whether the collection is public (default false)"),
942
+ tags: zod.z.array(zod.z.string()).optional().describe("Free-form tags")
943
+ }
944
+ },
945
+ async ({ name, slug, description, isPublic, tags }) => {
946
+ try {
947
+ const input = { name };
948
+ if (slug !== void 0) input.slug = slug;
949
+ if (description !== void 0) input.description = description;
950
+ if (isPublic !== void 0) input.isPublic = isPublic;
951
+ if (tags !== void 0) input.tags = tags;
952
+ const data = await ctx.gql.workspace.request(CREATE_COLLECTION, { input });
953
+ return jsonResult(data.cosCreateCollection);
954
+ } catch (error) {
955
+ ctx.logger.error("cosmicintersection collections_create failed", { error: String(error) });
956
+ return errorResult(
957
+ `Failed to create collection: ${error instanceof Error ? error.message : String(error)}`
958
+ );
959
+ }
960
+ }
961
+ );
962
+ }
963
+ function registerPipelineTools(server, ctx, track) {
964
+ server.registerTool(
965
+ track(mcpToolName(ctx.productName, "pipelines_get")),
966
+ {
967
+ title: "Get Pipeline",
968
+ description: "Fetch a single processing pipeline by ID, including its recent runs.",
969
+ inputSchema: { id: zod.z.string().describe("Pipeline ID") }
970
+ },
971
+ async ({ id }) => {
972
+ try {
973
+ const data = await ctx.gql.workspace.request(GET_PIPELINE, { id });
974
+ if (!data.cosPipeline) return errorResult(`Pipeline ${id} not found`);
975
+ return jsonResult(data.cosPipeline);
976
+ } catch (error) {
977
+ ctx.logger.error("cosmicintersection pipelines_get failed", { error: String(error) });
978
+ return errorResult(
979
+ `Failed to get pipeline: ${error instanceof Error ? error.message : String(error)}`
980
+ );
981
+ }
982
+ }
983
+ );
984
+ server.registerTool(
985
+ track(mcpToolName(ctx.productName, "pipelines_list")),
986
+ {
987
+ title: "List Pipelines",
988
+ description: "List processing pipelines with optional status filter and pagination (returns a connection: { items, pageInfo }).",
989
+ inputSchema: {
990
+ status: CosPipelineStatusEnum.optional().describe("Filter by lifecycle status"),
991
+ limit: zod.z.number().int().optional().describe("Page size (default 50)"),
992
+ offset: zod.z.number().int().optional().describe("Pagination offset (default 0)"),
993
+ cursor: zod.z.string().optional().describe("Opaque pagination cursor")
994
+ }
995
+ },
996
+ async ({ status, limit, offset, cursor }) => {
997
+ try {
998
+ const pagination = {};
999
+ if (limit !== void 0) pagination.limit = limit;
1000
+ if (offset !== void 0) pagination.offset = offset;
1001
+ if (cursor !== void 0) pagination.cursor = cursor;
1002
+ const data = await ctx.gql.workspace.request(LIST_PIPELINES, {
1003
+ status,
1004
+ pagination: Object.keys(pagination).length > 0 ? pagination : void 0
1005
+ });
1006
+ return jsonResult(data.cosListPipelines);
1007
+ } catch (error) {
1008
+ ctx.logger.error("cosmicintersection pipelines_list failed", { error: String(error) });
1009
+ return errorResult(
1010
+ `Failed to list pipelines: ${error instanceof Error ? error.message : String(error)}`
1011
+ );
1012
+ }
1013
+ }
1014
+ );
1015
+ server.registerTool(
1016
+ track(mcpToolName(ctx.productName, "pipelines_create")),
1017
+ {
1018
+ title: "Create Pipeline",
1019
+ description: "Create a processing pipeline. Defaults: trigger=MANUAL.",
1020
+ inputSchema: {
1021
+ name: zod.z.string().min(1).describe("Pipeline name"),
1022
+ trigger: CosPipelineTriggerEnum.optional().describe("Trigger mode (default MANUAL)"),
1023
+ description: zod.z.string().optional().describe("Pipeline description"),
1024
+ definition: JsonObject.optional().describe("Pipeline definition JSON (steps/graph)"),
1025
+ schedule: zod.z.string().optional().describe("Cron schedule (when trigger=SCHEDULED)"),
1026
+ tags: zod.z.array(zod.z.string()).optional().describe("Free-form tags")
1027
+ }
1028
+ },
1029
+ async ({ name, trigger, description, definition, schedule, tags }) => {
1030
+ try {
1031
+ const input = { name };
1032
+ if (trigger !== void 0) input.trigger = trigger;
1033
+ if (description !== void 0) input.description = description;
1034
+ if (definition !== void 0) input.definition = definition;
1035
+ if (schedule !== void 0) input.schedule = schedule;
1036
+ if (tags !== void 0) input.tags = tags;
1037
+ const data = await ctx.gql.workspace.request(CREATE_PIPELINE, { input });
1038
+ return jsonResult(data.cosCreatePipeline);
1039
+ } catch (error) {
1040
+ ctx.logger.error("cosmicintersection pipelines_create failed", { error: String(error) });
1041
+ return errorResult(
1042
+ `Failed to create pipeline: ${error instanceof Error ? error.message : String(error)}`
1043
+ );
1044
+ }
1045
+ }
1046
+ );
1047
+ server.registerTool(
1048
+ track(mcpToolName(ctx.productName, "pipelines_update")),
1049
+ {
1050
+ title: "Update Pipeline",
1051
+ description: "Update a pipeline. At least one mutable field must be provided.",
1052
+ inputSchema: {
1053
+ id: zod.z.string().describe("Pipeline ID"),
1054
+ name: zod.z.string().optional().describe("Updated name"),
1055
+ status: CosPipelineStatusEnum.optional().describe("Updated lifecycle status"),
1056
+ trigger: CosPipelineTriggerEnum.optional().describe("Updated trigger mode"),
1057
+ description: zod.z.string().optional().describe("Updated description"),
1058
+ definition: JsonObject.optional().describe("Updated definition JSON"),
1059
+ schedule: zod.z.string().optional().describe("Updated cron schedule"),
1060
+ tags: zod.z.array(zod.z.string()).optional().describe("Updated tags")
1061
+ }
1062
+ },
1063
+ async ({ id, name, status, trigger, description, definition, schedule, tags }) => {
1064
+ try {
1065
+ const input = {};
1066
+ if (name !== void 0) input.name = name;
1067
+ if (status !== void 0) input.status = status;
1068
+ if (trigger !== void 0) input.trigger = trigger;
1069
+ if (description !== void 0) input.description = description;
1070
+ if (definition !== void 0) input.definition = definition;
1071
+ if (schedule !== void 0) input.schedule = schedule;
1072
+ if (tags !== void 0) input.tags = tags;
1073
+ if (Object.keys(input).length === 0) {
1074
+ return errorResult(
1075
+ "No updates specified \u2014 provide at least one of name/status/trigger/description/definition/schedule/tags"
1076
+ );
1077
+ }
1078
+ const data = await ctx.gql.workspace.request(UPDATE_PIPELINE, { id, input });
1079
+ return jsonResult(data.cosUpdatePipeline);
1080
+ } catch (error) {
1081
+ ctx.logger.error("cosmicintersection pipelines_update failed", { error: String(error) });
1082
+ return errorResult(
1083
+ `Failed to update pipeline: ${error instanceof Error ? error.message : String(error)}`
1084
+ );
1085
+ }
1086
+ }
1087
+ );
1088
+ server.registerTool(
1089
+ track(mcpToolName(ctx.productName, "pipelines_archive")),
1090
+ {
1091
+ title: "Archive Pipeline",
1092
+ description: "Archive (soft-delete) a pipeline. Returns true on success.",
1093
+ inputSchema: { id: zod.z.string().describe("Pipeline ID") }
1094
+ },
1095
+ async ({ id }) => {
1096
+ try {
1097
+ const data = await ctx.gql.workspace.request(
1098
+ ARCHIVE_PIPELINE,
1099
+ { id }
1100
+ );
1101
+ return jsonResult({ archived: data.cosArchivePipeline });
1102
+ } catch (error) {
1103
+ ctx.logger.error("cosmicintersection pipelines_archive failed", { error: String(error) });
1104
+ return errorResult(
1105
+ `Failed to archive pipeline: ${error instanceof Error ? error.message : String(error)}`
1106
+ );
1107
+ }
1108
+ }
1109
+ );
1110
+ }
1111
+ function registerRunTools(server, ctx, track) {
1112
+ server.registerTool(
1113
+ track(mcpToolName(ctx.productName, "runs_get")),
1114
+ {
1115
+ title: "Get Run",
1116
+ description: "Fetch a single pipeline run by ID, including its pipeline and steps.",
1117
+ inputSchema: { id: zod.z.string().describe("Run ID") }
1118
+ },
1119
+ async ({ id }) => {
1120
+ try {
1121
+ const data = await ctx.gql.workspace.request(GET_RUN, { id });
1122
+ if (!data.cosRun) return errorResult(`Run ${id} not found`);
1123
+ return jsonResult(data.cosRun);
1124
+ } catch (error) {
1125
+ ctx.logger.error("cosmicintersection runs_get failed", { error: String(error) });
1126
+ return errorResult(
1127
+ `Failed to get run: ${error instanceof Error ? error.message : String(error)}`
1128
+ );
1129
+ }
1130
+ }
1131
+ );
1132
+ server.registerTool(
1133
+ track(mcpToolName(ctx.productName, "runs_list")),
1134
+ {
1135
+ title: "List Runs",
1136
+ description: "List pipeline runs with optional pipeline/status filters and pagination (returns a connection: { items, pageInfo }).",
1137
+ inputSchema: {
1138
+ pipelineId: zod.z.string().optional().describe("Filter by pipeline ID"),
1139
+ status: CosRunStatusEnum.optional().describe("Filter by run status"),
1140
+ limit: zod.z.number().int().optional().describe("Page size (default 50)"),
1141
+ offset: zod.z.number().int().optional().describe("Pagination offset (default 0)"),
1142
+ cursor: zod.z.string().optional().describe("Opaque pagination cursor")
1143
+ }
1144
+ },
1145
+ async ({ pipelineId, status, limit, offset, cursor }) => {
1146
+ try {
1147
+ const pagination = {};
1148
+ if (limit !== void 0) pagination.limit = limit;
1149
+ if (offset !== void 0) pagination.offset = offset;
1150
+ if (cursor !== void 0) pagination.cursor = cursor;
1151
+ const data = await ctx.gql.workspace.request(LIST_RUNS, {
1152
+ pipelineId,
1153
+ status,
1154
+ pagination: Object.keys(pagination).length > 0 ? pagination : void 0
1155
+ });
1156
+ return jsonResult(data.cosListRuns);
1157
+ } catch (error) {
1158
+ ctx.logger.error("cosmicintersection runs_list failed", { error: String(error) });
1159
+ return errorResult(
1160
+ `Failed to list runs: ${error instanceof Error ? error.message : String(error)}`
1161
+ );
1162
+ }
1163
+ }
1164
+ );
1165
+ server.registerTool(
1166
+ track(mcpToolName(ctx.productName, "runs_start")),
1167
+ {
1168
+ title: "Start Run",
1169
+ description: "Queue a new run of a pipeline (assigns the next run number).",
1170
+ inputSchema: {
1171
+ pipelineId: zod.z.string().describe("Pipeline ID to run"),
1172
+ datasetId: zod.z.string().optional().describe("Input dataset ID"),
1173
+ params: JsonObject.optional().describe("Run parameters JSON")
1174
+ }
1175
+ },
1176
+ async ({ pipelineId, datasetId, params }) => {
1177
+ try {
1178
+ const input = { pipelineId };
1179
+ if (datasetId !== void 0) input.datasetId = datasetId;
1180
+ if (params !== void 0) input.params = params;
1181
+ const data = await ctx.gql.workspace.request(START_RUN, { input });
1182
+ return jsonResult(data.cosStartRun);
1183
+ } catch (error) {
1184
+ ctx.logger.error("cosmicintersection runs_start failed", { error: String(error) });
1185
+ return errorResult(
1186
+ `Failed to start run: ${error instanceof Error ? error.message : String(error)}`
1187
+ );
1188
+ }
1189
+ }
1190
+ );
1191
+ server.registerTool(
1192
+ track(mcpToolName(ctx.productName, "runs_transition")),
1193
+ {
1194
+ title: "Transition Run",
1195
+ description: "Advance a run through its lifecycle (validated transitions): QUEUED \u2192 RUNNING \u2192 SUCCEEDED/FAILED/CANCELLED.",
1196
+ inputSchema: {
1197
+ id: zod.z.string().describe("Run ID"),
1198
+ status: CosRunStatusEnum.describe("Target run status")
1199
+ }
1200
+ },
1201
+ async ({ id, status }) => {
1202
+ try {
1203
+ const data = await ctx.gql.workspace.request(TRANSITION_RUN, { id, status });
1204
+ return jsonResult(data.cosTransitionRun);
1205
+ } catch (error) {
1206
+ ctx.logger.error("cosmicintersection runs_transition failed", { error: String(error) });
1207
+ return errorResult(
1208
+ `Failed to transition run: ${error instanceof Error ? error.message : String(error)}`
1209
+ );
1210
+ }
1211
+ }
1212
+ );
1213
+ server.registerTool(
1214
+ track(mcpToolName(ctx.productName, "runs_steps_list")),
1215
+ {
1216
+ title: "List Run Steps",
1217
+ description: "List the steps of a pipeline run, in order.",
1218
+ inputSchema: { runId: zod.z.string().describe("Run ID") }
1219
+ },
1220
+ async ({ runId }) => {
1221
+ try {
1222
+ const data = await ctx.gql.workspace.request(LIST_RUN_STEPS, { runId });
1223
+ return jsonResult(data.cosListRunSteps);
1224
+ } catch (error) {
1225
+ ctx.logger.error("cosmicintersection runs_steps_list failed", { error: String(error) });
1226
+ return errorResult(
1227
+ `Failed to list run steps: ${error instanceof Error ? error.message : String(error)}`
1228
+ );
1229
+ }
1230
+ }
1231
+ );
1232
+ server.registerTool(
1233
+ track(mcpToolName(ctx.productName, "runs_steps_add")),
1234
+ {
1235
+ title: "Add Run Step",
1236
+ description: "Append a step to a run. Defaults: kind=TRANSFORM.",
1237
+ inputSchema: {
1238
+ runId: zod.z.string().describe("Run ID"),
1239
+ name: zod.z.string().min(1).describe("Step name"),
1240
+ kind: CosStepKindEnum.optional().describe("Step kind (default TRANSFORM)"),
1241
+ inputs: JsonObject.optional().describe("Step inputs JSON"),
1242
+ position: zod.z.number().int().optional().describe("Ordinal position in the run")
1243
+ }
1244
+ },
1245
+ async ({ runId, name, kind, inputs, position }) => {
1246
+ try {
1247
+ const input = { runId, name };
1248
+ if (kind !== void 0) input.kind = kind;
1249
+ if (inputs !== void 0) input.inputs = inputs;
1250
+ if (position !== void 0) input.position = position;
1251
+ const data = await ctx.gql.workspace.request(ADD_RUN_STEP, { input });
1252
+ return jsonResult(data.cosAddRunStep);
1253
+ } catch (error) {
1254
+ ctx.logger.error("cosmicintersection runs_steps_add failed", { error: String(error) });
1255
+ return errorResult(
1256
+ `Failed to add run step: ${error instanceof Error ? error.message : String(error)}`
1257
+ );
1258
+ }
1259
+ }
1260
+ );
1261
+ }
1262
+ function registerNotebookTools(server, ctx, track) {
1263
+ server.registerTool(
1264
+ track(mcpToolName(ctx.productName, "notebooks_get")),
1265
+ {
1266
+ title: "Get Notebook",
1267
+ description: "Fetch a single research notebook by ID, including its analyses and releases.",
1268
+ inputSchema: { id: zod.z.string().describe("Notebook ID") }
1269
+ },
1270
+ async ({ id }) => {
1271
+ try {
1272
+ const data = await ctx.gql.workspace.request(GET_NOTEBOOK, { id });
1273
+ if (!data.cosNotebook) return errorResult(`Notebook ${id} not found`);
1274
+ return jsonResult(data.cosNotebook);
1275
+ } catch (error) {
1276
+ ctx.logger.error("cosmicintersection notebooks_get failed", { error: String(error) });
1277
+ return errorResult(
1278
+ `Failed to get notebook: ${error instanceof Error ? error.message : String(error)}`
1279
+ );
1280
+ }
1281
+ }
1282
+ );
1283
+ server.registerTool(
1284
+ track(mcpToolName(ctx.productName, "notebooks_list")),
1285
+ {
1286
+ title: "List Notebooks",
1287
+ description: "List research notebooks with optional status filter and pagination (returns a connection: { items, pageInfo }).",
1288
+ inputSchema: {
1289
+ status: CosNotebookStatusEnum.optional().describe("Filter by lifecycle status"),
1290
+ limit: zod.z.number().int().optional().describe("Page size (default 50)"),
1291
+ offset: zod.z.number().int().optional().describe("Pagination offset (default 0)"),
1292
+ cursor: zod.z.string().optional().describe("Opaque pagination cursor")
1293
+ }
1294
+ },
1295
+ async ({ status, limit, offset, cursor }) => {
1296
+ try {
1297
+ const pagination = {};
1298
+ if (limit !== void 0) pagination.limit = limit;
1299
+ if (offset !== void 0) pagination.offset = offset;
1300
+ if (cursor !== void 0) pagination.cursor = cursor;
1301
+ const data = await ctx.gql.workspace.request(LIST_NOTEBOOKS, {
1302
+ status,
1303
+ pagination: Object.keys(pagination).length > 0 ? pagination : void 0
1304
+ });
1305
+ return jsonResult(data.cosListNotebooks);
1306
+ } catch (error) {
1307
+ ctx.logger.error("cosmicintersection notebooks_list failed", { error: String(error) });
1308
+ return errorResult(
1309
+ `Failed to list notebooks: ${error instanceof Error ? error.message : String(error)}`
1310
+ );
1311
+ }
1312
+ }
1313
+ );
1314
+ server.registerTool(
1315
+ track(mcpToolName(ctx.productName, "notebooks_create")),
1316
+ {
1317
+ title: "Create Notebook",
1318
+ description: "Create a research notebook. Reference a wspace-files-svc File via fileId for the notebook document.",
1319
+ inputSchema: {
1320
+ title: zod.z.string().min(1).describe("Notebook title"),
1321
+ description: zod.z.string().optional().describe("Notebook description"),
1322
+ runtime: zod.z.string().optional().describe("Runtime (e.g. python3.11, julia)"),
1323
+ environment: JsonObject.optional().describe("Environment / dependency JSON"),
1324
+ datasetIds: zod.z.array(zod.z.string()).optional().describe("Dataset IDs referenced by the notebook"),
1325
+ fileId: zod.z.string().optional().describe("wspace-files-svc File ID for the notebook document"),
1326
+ tags: zod.z.array(zod.z.string()).optional().describe("Free-form tags")
1327
+ }
1328
+ },
1329
+ async ({ title, description, runtime, environment, datasetIds, fileId, tags }) => {
1330
+ try {
1331
+ const input = { title };
1332
+ if (description !== void 0) input.description = description;
1333
+ if (runtime !== void 0) input.runtime = runtime;
1334
+ if (environment !== void 0) input.environment = environment;
1335
+ if (datasetIds !== void 0) input.datasetIds = datasetIds;
1336
+ if (fileId !== void 0) input.fileId = fileId;
1337
+ if (tags !== void 0) input.tags = tags;
1338
+ const data = await ctx.gql.workspace.request(CREATE_NOTEBOOK, { input });
1339
+ return jsonResult(data.cosCreateNotebook);
1340
+ } catch (error) {
1341
+ ctx.logger.error("cosmicintersection notebooks_create failed", { error: String(error) });
1342
+ return errorResult(
1343
+ `Failed to create notebook: ${error instanceof Error ? error.message : String(error)}`
1344
+ );
1345
+ }
1346
+ }
1347
+ );
1348
+ server.registerTool(
1349
+ track(mcpToolName(ctx.productName, "notebooks_update")),
1350
+ {
1351
+ title: "Update Notebook",
1352
+ description: "Update a research notebook. At least one mutable field must be provided.",
1353
+ inputSchema: {
1354
+ id: zod.z.string().describe("Notebook ID"),
1355
+ title: zod.z.string().optional().describe("Updated title"),
1356
+ description: zod.z.string().optional().describe("Updated description"),
1357
+ status: CosNotebookStatusEnum.optional().describe("Updated lifecycle status"),
1358
+ runtime: zod.z.string().optional().describe("Updated runtime"),
1359
+ environment: JsonObject.optional().describe("Updated environment JSON"),
1360
+ datasetIds: zod.z.array(zod.z.string()).optional().describe("Updated dataset IDs"),
1361
+ isShared: zod.z.boolean().optional().describe("Whether the notebook is shared"),
1362
+ shareSlug: zod.z.string().optional().describe("Public share slug"),
1363
+ tags: zod.z.array(zod.z.string()).optional().describe("Updated tags")
1364
+ }
1365
+ },
1366
+ async ({
1367
+ id,
1368
+ title,
1369
+ description,
1370
+ status,
1371
+ runtime,
1372
+ environment,
1373
+ datasetIds,
1374
+ isShared,
1375
+ shareSlug,
1376
+ tags
1377
+ }) => {
1378
+ try {
1379
+ const input = {};
1380
+ if (title !== void 0) input.title = title;
1381
+ if (description !== void 0) input.description = description;
1382
+ if (status !== void 0) input.status = status;
1383
+ if (runtime !== void 0) input.runtime = runtime;
1384
+ if (environment !== void 0) input.environment = environment;
1385
+ if (datasetIds !== void 0) input.datasetIds = datasetIds;
1386
+ if (isShared !== void 0) input.isShared = isShared;
1387
+ if (shareSlug !== void 0) input.shareSlug = shareSlug;
1388
+ if (tags !== void 0) input.tags = tags;
1389
+ if (Object.keys(input).length === 0) {
1390
+ return errorResult(
1391
+ "No updates specified \u2014 provide at least one of title/description/status/runtime/environment/datasetIds/isShared/shareSlug/tags"
1392
+ );
1393
+ }
1394
+ const data = await ctx.gql.workspace.request(UPDATE_NOTEBOOK, { id, input });
1395
+ return jsonResult(data.cosUpdateNotebook);
1396
+ } catch (error) {
1397
+ ctx.logger.error("cosmicintersection notebooks_update failed", { error: String(error) });
1398
+ return errorResult(
1399
+ `Failed to update notebook: ${error instanceof Error ? error.message : String(error)}`
1400
+ );
1401
+ }
1402
+ }
1403
+ );
1404
+ server.registerTool(
1405
+ track(mcpToolName(ctx.productName, "notebooks_archive")),
1406
+ {
1407
+ title: "Archive Notebook",
1408
+ description: "Archive (soft-delete) a research notebook. Returns true on success.",
1409
+ inputSchema: { id: zod.z.string().describe("Notebook ID") }
1410
+ },
1411
+ async ({ id }) => {
1412
+ try {
1413
+ const data = await ctx.gql.workspace.request(
1414
+ ARCHIVE_NOTEBOOK,
1415
+ { id }
1416
+ );
1417
+ return jsonResult({ archived: data.cosArchiveNotebook });
1418
+ } catch (error) {
1419
+ ctx.logger.error("cosmicintersection notebooks_archive failed", { error: String(error) });
1420
+ return errorResult(
1421
+ `Failed to archive notebook: ${error instanceof Error ? error.message : String(error)}`
1422
+ );
1423
+ }
1424
+ }
1425
+ );
1426
+ }
1427
+ function registerAnalysisTools(server, ctx, track) {
1428
+ server.registerTool(
1429
+ track(mcpToolName(ctx.productName, "analyses_list")),
1430
+ {
1431
+ title: "List Analyses",
1432
+ description: "List analyses, optionally filtered by dataset, notebook, and/or status.",
1433
+ inputSchema: {
1434
+ datasetId: zod.z.string().optional().describe("Filter by dataset ID"),
1435
+ notebookId: zod.z.string().optional().describe("Filter by notebook ID"),
1436
+ status: CosAnalysisStatusEnum.optional().describe("Filter by analysis status")
1437
+ }
1438
+ },
1439
+ async ({ datasetId, notebookId, status }) => {
1440
+ try {
1441
+ const data = await ctx.gql.workspace.request(LIST_ANALYSES, { datasetId, notebookId, status });
1442
+ return jsonResult(data.cosListAnalyses);
1443
+ } catch (error) {
1444
+ ctx.logger.error("cosmicintersection analyses_list failed", { error: String(error) });
1445
+ return errorResult(
1446
+ `Failed to list analyses: ${error instanceof Error ? error.message : String(error)}`
1447
+ );
1448
+ }
1449
+ }
1450
+ );
1451
+ server.registerTool(
1452
+ track(mcpToolName(ctx.productName, "analyses_run")),
1453
+ {
1454
+ title: "Run Analysis",
1455
+ description: "Queue a new analysis run. Defaults: aiAssisted=false.",
1456
+ inputSchema: {
1457
+ title: zod.z.string().min(1).describe("Analysis title"),
1458
+ method: zod.z.string().optional().describe("Analysis method / algorithm"),
1459
+ datasetId: zod.z.string().optional().describe("Input dataset ID"),
1460
+ notebookId: zod.z.string().optional().describe("Source notebook ID"),
1461
+ aiAssisted: zod.z.boolean().optional().describe("Whether AI-assisted (default false)")
1462
+ }
1463
+ },
1464
+ async ({ title, method, datasetId, notebookId, aiAssisted }) => {
1465
+ try {
1466
+ const input = { title };
1467
+ if (method !== void 0) input.method = method;
1468
+ if (datasetId !== void 0) input.datasetId = datasetId;
1469
+ if (notebookId !== void 0) input.notebookId = notebookId;
1470
+ if (aiAssisted !== void 0) input.aiAssisted = aiAssisted;
1471
+ const data = await ctx.gql.workspace.request(RUN_ANALYSIS, { input });
1472
+ return jsonResult(data.cosRunAnalysis);
1473
+ } catch (error) {
1474
+ ctx.logger.error("cosmicintersection analyses_run failed", { error: String(error) });
1475
+ return errorResult(
1476
+ `Failed to run analysis: ${error instanceof Error ? error.message : String(error)}`
1477
+ );
1478
+ }
1479
+ }
1480
+ );
1481
+ server.registerTool(
1482
+ track(mcpToolName(ctx.productName, "analyses_complete")),
1483
+ {
1484
+ title: "Complete Analysis",
1485
+ description: "Record the terminal outcome of an analysis run (COMPLETED / FAILED), optionally attaching results JSON and a rendered output File.",
1486
+ inputSchema: {
1487
+ id: zod.z.string().describe("Analysis ID"),
1488
+ status: CosAnalysisStatusEnum.describe("Terminal status (COMPLETED or FAILED)"),
1489
+ results: JsonObject.optional().describe("Analysis results JSON"),
1490
+ outputFileId: zod.z.string().optional().describe("wspace-files-svc File ID of the rendered visualization")
1491
+ }
1492
+ },
1493
+ async ({ id, status, results, outputFileId }) => {
1494
+ try {
1495
+ const data = await ctx.gql.workspace.request(COMPLETE_ANALYSIS, { id, status, results, outputFileId });
1496
+ return jsonResult(data.cosCompleteAnalysis);
1497
+ } catch (error) {
1498
+ ctx.logger.error("cosmicintersection analyses_complete failed", { error: String(error) });
1499
+ return errorResult(
1500
+ `Failed to complete analysis: ${error instanceof Error ? error.message : String(error)}`
1501
+ );
1502
+ }
1503
+ }
1504
+ );
1505
+ }
1506
+ function registerReleaseTools(server, ctx, track) {
1507
+ server.registerTool(
1508
+ track(mcpToolName(ctx.productName, "releases_list")),
1509
+ {
1510
+ title: "List Releases",
1511
+ description: "List citable releases with optional status filter and pagination (returns a connection: { items, pageInfo }).",
1512
+ inputSchema: {
1513
+ status: CosReleaseStatusEnum.optional().describe("Filter by lifecycle status"),
1514
+ limit: zod.z.number().int().optional().describe("Page size (default 50)"),
1515
+ offset: zod.z.number().int().optional().describe("Pagination offset (default 0)"),
1516
+ cursor: zod.z.string().optional().describe("Opaque pagination cursor")
1517
+ }
1518
+ },
1519
+ async ({ status, limit, offset, cursor }) => {
1520
+ try {
1521
+ const pagination = {};
1522
+ if (limit !== void 0) pagination.limit = limit;
1523
+ if (offset !== void 0) pagination.offset = offset;
1524
+ if (cursor !== void 0) pagination.cursor = cursor;
1525
+ const data = await ctx.gql.workspace.request(LIST_RELEASES, {
1526
+ status,
1527
+ pagination: Object.keys(pagination).length > 0 ? pagination : void 0
1528
+ });
1529
+ return jsonResult(data.cosListReleases);
1530
+ } catch (error) {
1531
+ ctx.logger.error("cosmicintersection releases_list failed", { error: String(error) });
1532
+ return errorResult(
1533
+ `Failed to list releases: ${error instanceof Error ? error.message : String(error)}`
1534
+ );
1535
+ }
1536
+ }
1537
+ );
1538
+ server.registerTool(
1539
+ track(mcpToolName(ctx.productName, "releases_create")),
1540
+ {
1541
+ title: "Create Release",
1542
+ description: "Draft a citable release bundling datasets and/or a notebook for publication.",
1543
+ inputSchema: {
1544
+ title: zod.z.string().min(1).describe("Release title"),
1545
+ version: zod.z.string().optional().describe("Version string (e.g. 1.0.0)"),
1546
+ abstract: zod.z.string().optional().describe("Abstract / summary"),
1547
+ authors: zod.z.array(zod.z.string()).optional().describe("Author names"),
1548
+ license: zod.z.string().optional().describe("License (e.g. CC-BY-4.0)"),
1549
+ notebookId: zod.z.string().optional().describe("Source notebook ID"),
1550
+ datasetIds: zod.z.array(zod.z.string()).optional().describe("Bundled dataset IDs")
1551
+ }
1552
+ },
1553
+ async ({ title, version, abstract, authors, license, notebookId, datasetIds }) => {
1554
+ try {
1555
+ const input = { title };
1556
+ if (version !== void 0) input.version = version;
1557
+ if (abstract !== void 0) input.abstract = abstract;
1558
+ if (authors !== void 0) input.authors = authors;
1559
+ if (license !== void 0) input.license = license;
1560
+ if (notebookId !== void 0) input.notebookId = notebookId;
1561
+ if (datasetIds !== void 0) input.datasetIds = datasetIds;
1562
+ const data = await ctx.gql.workspace.request(CREATE_RELEASE, { input });
1563
+ return jsonResult(data.cosCreateRelease);
1564
+ } catch (error) {
1565
+ ctx.logger.error("cosmicintersection releases_create failed", { error: String(error) });
1566
+ return errorResult(
1567
+ `Failed to create release: ${error instanceof Error ? error.message : String(error)}`
1568
+ );
1569
+ }
1570
+ }
1571
+ );
1572
+ server.registerTool(
1573
+ track(mcpToolName(ctx.productName, "releases_publish")),
1574
+ {
1575
+ title: "Publish Release",
1576
+ description: "Publish a citable release and stamp it with a DOI.",
1577
+ inputSchema: {
1578
+ id: zod.z.string().describe("Release ID"),
1579
+ doi: zod.z.string().optional().describe("DOI to stamp the release with")
1580
+ }
1581
+ },
1582
+ async ({ id, doi }) => {
1583
+ try {
1584
+ const data = await ctx.gql.workspace.request(PUBLISH_RELEASE, { id, doi });
1585
+ return jsonResult(data.cosPublishRelease);
1586
+ } catch (error) {
1587
+ ctx.logger.error("cosmicintersection releases_publish failed", { error: String(error) });
1588
+ return errorResult(
1589
+ `Failed to publish release: ${error instanceof Error ? error.message : String(error)}`
1590
+ );
1591
+ }
1592
+ }
1593
+ );
1594
+ }
1595
+ function registerGrantTools(server, ctx, track) {
1596
+ server.registerTool(
1597
+ track(mcpToolName(ctx.productName, "grants_list")),
1598
+ {
1599
+ title: "List Access Grants",
1600
+ description: "List dataset access grants, optionally filtered by dataset and/or status.",
1601
+ inputSchema: {
1602
+ datasetId: zod.z.string().optional().describe("Filter by dataset ID"),
1603
+ status: CosGrantStatusEnum.optional().describe("Filter by grant status")
1604
+ }
1605
+ },
1606
+ async ({ datasetId, status }) => {
1607
+ try {
1608
+ const data = await ctx.gql.workspace.request(LIST_ACCESS_GRANTS, { datasetId, status });
1609
+ return jsonResult(data.cosListAccessGrants);
1610
+ } catch (error) {
1611
+ ctx.logger.error("cosmicintersection grants_list failed", { error: String(error) });
1612
+ return errorResult(
1613
+ `Failed to list access grants: ${error instanceof Error ? error.message : String(error)}`
1614
+ );
1615
+ }
1616
+ }
1617
+ );
1618
+ server.registerTool(
1619
+ track(mcpToolName(ctx.productName, "grants_grant")),
1620
+ {
1621
+ title: "Grant Dataset Access",
1622
+ description: "Grant a user (grantee) scoped access to a dataset, optionally with an expiry and reason.",
1623
+ inputSchema: {
1624
+ datasetId: zod.z.string().describe("Dataset ID"),
1625
+ granteeId: zod.z.string().describe("User ID of the grantee"),
1626
+ scopes: zod.z.array(zod.z.string()).optional().describe("Granted scopes (e.g. read, download)"),
1627
+ reason: zod.z.string().optional().describe("Reason for the grant"),
1628
+ expiresAt: zod.z.string().optional().describe("Expiry timestamp (ISO 8601 DateTime)")
1629
+ }
1630
+ },
1631
+ async ({ datasetId, granteeId, scopes, reason, expiresAt }) => {
1632
+ try {
1633
+ const input = { datasetId, granteeId };
1634
+ if (scopes !== void 0) input.scopes = scopes;
1635
+ if (reason !== void 0) input.reason = reason;
1636
+ if (expiresAt !== void 0) input.expiresAt = expiresAt;
1637
+ const data = await ctx.gql.workspace.request(GRANT_ACCESS, { input });
1638
+ return jsonResult(data.cosGrantAccess);
1639
+ } catch (error) {
1640
+ ctx.logger.error("cosmicintersection grants_grant failed", { error: String(error) });
1641
+ return errorResult(
1642
+ `Failed to grant access: ${error instanceof Error ? error.message : String(error)}`
1643
+ );
1644
+ }
1645
+ }
1646
+ );
1647
+ server.registerTool(
1648
+ track(mcpToolName(ctx.productName, "grants_revoke")),
1649
+ {
1650
+ title: "Revoke Dataset Access",
1651
+ description: "Revoke a dataset access grant (sets status REVOKED + revokedAt).",
1652
+ inputSchema: { id: zod.z.string().describe("Access grant ID") }
1653
+ },
1654
+ async ({ id }) => {
1655
+ try {
1656
+ const data = await ctx.gql.workspace.request(REVOKE_ACCESS, { id });
1657
+ return jsonResult(data.cosRevokeAccess);
1658
+ } catch (error) {
1659
+ ctx.logger.error("cosmicintersection grants_revoke failed", { error: String(error) });
1660
+ return errorResult(
1661
+ `Failed to revoke access: ${error instanceof Error ? error.message : String(error)}`
1662
+ );
1663
+ }
1664
+ }
1665
+ );
1666
+ }
1667
+
1668
+ // src/modules/cosmicintersection/tools/health.ts
1669
+ function registerHealthTools(server, ctx, track) {
1670
+ server.registerTool(
1671
+ track(mcpToolName(ctx.productName, "health")),
1672
+ {
1673
+ title: "Cosmicintersection Health Check",
1674
+ description: "Public health probe for the Cosmicintersection subgraph (cosHealth). Requires no authentication.",
1675
+ inputSchema: {}
1676
+ },
1677
+ async () => {
1678
+ try {
1679
+ const data = await ctx.gql.workspace.request(HEALTH, {});
1680
+ return jsonResult({ ok: true, status: data.cosHealth });
1681
+ } catch (error) {
1682
+ ctx.logger.error("cosmicintersection health failed", { error: String(error) });
1683
+ return errorResult(
1684
+ `Cosmicintersection health check failed: ${error instanceof Error ? error.message : String(error)}`
1685
+ );
1686
+ }
1687
+ }
1688
+ );
1689
+ }
1690
+
1691
+ // src/modules/cosmicintersection/resources.ts
1692
+ function registerCosmicintersectionResources(server, ctx, track) {
1693
+ const schemaUri = track(mcpResourceUri(ctx.productName, "schema"));
1694
+ const datasetsUri = track(mcpResourceUri(ctx.productName, "datasets"));
1695
+ const collectionsUri = track(mcpResourceUri(ctx.productName, "collections"));
1696
+ const pipelinesUri = track(mcpResourceUri(ctx.productName, "pipelines"));
1697
+ server.registerResource(
1698
+ "cosmicintersection-schema",
1699
+ schemaUri,
1700
+ {
1701
+ title: "Cosmicintersection Domain Schema",
1702
+ description: "Overview of the Cosmicintersection data-platform domain \u2014 entities, enums, and the per-entity tool surface.",
1703
+ mimeType: "text/plain"
1704
+ },
1705
+ async () => {
1706
+ ctx.logger.debug(`Resource ${schemaUri} requested`);
1707
+ const schema = `# Cosmicintersection Domain (Overview)
1708
+
1709
+ The unified data platform for space & science: data sources & connectors, the
1710
+ dataset catalog (with schema / provenance), processing pipelines & runs (with
1711
+ captured lineage), and reproducible research (notebooks, analyses, citable
1712
+ releases, access grants).
1713
+
1714
+ ## Entities
1715
+ - CosSource \u2014 an upstream data source / connector (telescope, satellite, archive, API, \u2026)
1716
+ - CosDataset (+CosSchemaField) \u2014 a cataloged dataset and its schema fields
1717
+ - CosCollection \u2014 a named grouping of datasets
1718
+ - CosPipeline \u2014 a processing pipeline
1719
+ - CosPipelineRun (+CosPipelineStep) \u2014 a run of a pipeline and its steps
1720
+ - CosNotebook \u2014 a research notebook (references a wspace-files-svc File document)
1721
+ - CosAnalysis \u2014 an analysis run against a dataset/notebook
1722
+ - CosRelease \u2014 a citable, DOI-stamped research release
1723
+ - CosDataAccessGrant \u2014 a scoped access grant to a dataset
1724
+
1725
+ ## Enums
1726
+ - CosSourceType: API, ARCHIVE, FILE_DROP, GROUND_SENSOR, SATELLITE, SIMULATION, STREAM, TELESCOPE
1727
+ - CosSourceStatus: CONFIGURING, CONNECTED, DEGRADED, DISABLED, ERROR, SYNCING
1728
+ - CosDatasetStatus: ARCHIVED, AVAILABLE, DEPRECATED, DRAFT, INGESTING
1729
+ - CosAccessLevel: EMBARGOED, PUBLIC, RESTRICTED, WORKSPACE
1730
+ - CosFieldType: BOOLEAN, COORDINATE, FLOAT, GEOMETRY, IMAGE_REF, INTEGER, JSON, SPECTRUM, STRING, TIMESTAMP
1731
+ - CosPipelineStatus: ACTIVE, ARCHIVED, DRAFT, PAUSED
1732
+ - CosPipelineTrigger: MANUAL, ON_INGEST, SCHEDULED, WEBHOOK
1733
+ - CosRunStatus: CANCELLED, FAILED, QUEUED, RUNNING, SUCCEEDED
1734
+ - CosStepKind: ANALYZE, CALIBRATE, EXPORT, INGEST, NOTIFY, TRANSFORM
1735
+ - CosNotebookStatus: ARCHIVED, DRAFT, PUBLISHED, RUNNING
1736
+ - CosAnalysisStatus: COMPLETED, FAILED, PENDING, RUNNING
1737
+ - CosReleaseStatus: DRAFT, PUBLISHED, RETRACTED, UNDER_REVIEW
1738
+ - CosGrantStatus: ACTIVE, EXPIRED, PENDING, REVOKED
1739
+
1740
+ ## Tool groups
1741
+ sources, datasets (+fields), collections, pipelines, runs (+steps), notebooks,
1742
+ analyses, releases, grants, health. All run against the WORKSPACE gateway
1743
+ (workspace-scoped) except the public health probe.
1744
+ `;
1745
+ return {
1746
+ contents: [{ uri: schemaUri, text: schema, mimeType: "text/plain" }]
1747
+ };
1748
+ }
1749
+ );
1750
+ server.registerResource(
1751
+ "cosmicintersection-datasets",
1752
+ datasetsUri,
1753
+ {
1754
+ title: "Cosmicintersection Dataset Catalog",
1755
+ description: "The first 50 datasets in the bound workspace.",
1756
+ mimeType: "application/json"
1757
+ },
1758
+ async () => {
1759
+ ctx.logger.debug(`Resource ${datasetsUri} requested`);
1760
+ try {
1761
+ const data = await ctx.gql.workspace.request(LIST_DATASETS, {
1762
+ pagination: { limit: 50, offset: 0 }
1763
+ });
1764
+ return {
1765
+ contents: [
1766
+ {
1767
+ uri: datasetsUri,
1768
+ text: JSON.stringify(data.cosListDatasets, null, 2),
1769
+ mimeType: "application/json"
1770
+ }
1771
+ ]
1772
+ };
1773
+ } catch (error) {
1774
+ return {
1775
+ contents: [
1776
+ {
1777
+ uri: datasetsUri,
1778
+ text: JSON.stringify({
1779
+ error: error instanceof Error ? error.message : String(error)
1780
+ }),
1781
+ mimeType: "application/json"
1782
+ }
1783
+ ]
1784
+ };
1785
+ }
1786
+ }
1787
+ );
1788
+ server.registerResource(
1789
+ "cosmicintersection-collections",
1790
+ collectionsUri,
1791
+ {
1792
+ title: "Cosmicintersection Collections",
1793
+ description: "All dataset collections in the bound workspace.",
1794
+ mimeType: "application/json"
1795
+ },
1796
+ async () => {
1797
+ ctx.logger.debug(`Resource ${collectionsUri} requested`);
1798
+ try {
1799
+ const data = await ctx.gql.workspace.request(
1800
+ LIST_COLLECTIONS,
1801
+ {}
1802
+ );
1803
+ return {
1804
+ contents: [
1805
+ {
1806
+ uri: collectionsUri,
1807
+ text: JSON.stringify(data.cosListCollections, null, 2),
1808
+ mimeType: "application/json"
1809
+ }
1810
+ ]
1811
+ };
1812
+ } catch (error) {
1813
+ return {
1814
+ contents: [
1815
+ {
1816
+ uri: collectionsUri,
1817
+ text: JSON.stringify({
1818
+ error: error instanceof Error ? error.message : String(error)
1819
+ }),
1820
+ mimeType: "application/json"
1821
+ }
1822
+ ]
1823
+ };
1824
+ }
1825
+ }
1826
+ );
1827
+ server.registerResource(
1828
+ "cosmicintersection-pipelines",
1829
+ pipelinesUri,
1830
+ {
1831
+ title: "Cosmicintersection Pipelines",
1832
+ description: "The first 50 processing pipelines in the bound workspace.",
1833
+ mimeType: "application/json"
1834
+ },
1835
+ async () => {
1836
+ ctx.logger.debug(`Resource ${pipelinesUri} requested`);
1837
+ try {
1838
+ const data = await ctx.gql.workspace.request(
1839
+ LIST_PIPELINES,
1840
+ { pagination: { limit: 50, offset: 0 } }
1841
+ );
1842
+ return {
1843
+ contents: [
1844
+ {
1845
+ uri: pipelinesUri,
1846
+ text: JSON.stringify(data.cosListPipelines, null, 2),
1847
+ mimeType: "application/json"
1848
+ }
1849
+ ]
1850
+ };
1851
+ } catch (error) {
1852
+ return {
1853
+ contents: [
1854
+ {
1855
+ uri: pipelinesUri,
1856
+ text: JSON.stringify({
1857
+ error: error instanceof Error ? error.message : String(error)
1858
+ }),
1859
+ mimeType: "application/json"
1860
+ }
1861
+ ]
1862
+ };
1863
+ }
1864
+ }
1865
+ );
1866
+ }
1867
+ function registerCosmicintersectionPrompts(server, ctx, track) {
1868
+ const p = ctx.productName;
1869
+ const onboardingName = track(mcpPromptName(p, "dataset-onboarding"));
1870
+ const researchName = track(mcpPromptName(p, "research-publication"));
1871
+ server.registerPrompt(
1872
+ onboardingName,
1873
+ {
1874
+ title: "Dataset Onboarding",
1875
+ description: "Guide for onboarding new data into Cosmicintersection end to end: register a source, catalog a dataset, declare its schema, and publish it.",
1876
+ argsSchema: {
1877
+ sourceName: zod.z.string().optional().describe("Data source name"),
1878
+ datasetName: zod.z.string().optional().describe("Dataset name")
1879
+ }
1880
+ },
1881
+ ({ sourceName, datasetName }) => {
1882
+ ctx.logger.debug(`Prompt ${onboardingName} called`, { sourceName, datasetName });
1883
+ const sourceNote = sourceName ? `Use the source name "${sourceName}".` : "Ask the user for the source name.";
1884
+ const datasetNote = datasetName ? `Use the dataset name "${datasetName}".` : "Ask the user for the dataset name.";
1885
+ return {
1886
+ messages: [
1887
+ {
1888
+ role: "user",
1889
+ content: {
1890
+ type: "text",
1891
+ text: `Help me onboard new data into Cosmicintersection.
1892
+
1893
+ 1. **Register Source**: Use ${p}_sources_create. ${sourceNote} Pick a CosSourceType (TELESCOPE, SATELLITE, ARCHIVE, API, \u2026) and set an endpoint/config if applicable.
1894
+ 2. **(Optional) Collection**: Use ${p}_collections_create (or ${p}_collections_list) to group related datasets.
1895
+ 3. **Catalog Dataset**: Use ${p}_datasets_create. ${datasetNote} Link sourceId (and collectionId), set accessLevel and format, and reference the raw artifact File via fileId.
1896
+ 4. **Declare Schema**: Use ${p}_datasets_fields_add for each column \u2014 set fieldType (FLOAT, COORDINATE, SPECTRUM, TIMESTAMP, \u2026), nullable, unit, and provenance.
1897
+ 5. **Mark Synced**: Use ${p}_sources_mark_synced once the source connection is verified.
1898
+ 6. **Publish**: Use ${p}_datasets_publish to mark the dataset AVAILABLE once ingestion completes.
1899
+
1900
+ Show results at each step and confirm before publishing.`
1901
+ }
1902
+ }
1903
+ ]
1904
+ };
1905
+ }
1906
+ );
1907
+ server.registerPrompt(
1908
+ researchName,
1909
+ {
1910
+ title: "Research Publication",
1911
+ description: "Reproducible-research workflow: build a pipeline, run it, analyze the output in a notebook, and cut a citable DOI-stamped release.",
1912
+ argsSchema: {
1913
+ notebookId: zod.z.string().optional().describe("Notebook ID to work from")
1914
+ }
1915
+ },
1916
+ ({ notebookId }) => {
1917
+ ctx.logger.debug(`Prompt ${researchName} called`, { notebookId });
1918
+ const notebookNote = notebookId ? `Work from notebook "${notebookId}".` : `First list notebooks with ${p}_notebooks_list (or create one with ${p}_notebooks_create) and pick one.`;
1919
+ return {
1920
+ messages: [
1921
+ {
1922
+ role: "user",
1923
+ content: {
1924
+ type: "text",
1925
+ text: `Run a reproducible-research publication workflow. ${notebookNote}
1926
+
1927
+ 1. **Pipeline**: Use ${p}_pipelines_list / ${p}_pipelines_create to set up the processing pipeline (definition + trigger).
1928
+ 2. **Run**: Use ${p}_runs_start to queue a run, ${p}_runs_steps_add to append steps, and ${p}_runs_transition to advance it (QUEUED \u2192 RUNNING \u2192 SUCCEEDED).
1929
+ 3. **Analyze**: Use ${p}_analyses_run against the resulting dataset/notebook, then ${p}_analyses_complete with the results and an output File.
1930
+ 4. **Release**: Use ${p}_releases_create to bundle datasets + notebook, then ${p}_releases_publish to stamp a DOI.
1931
+ 5. **(Optional) Share Access**: Use ${p}_grants_grant to give collaborators scoped access to the underlying datasets.
1932
+
1933
+ Summarize lineage (source \u2192 dataset \u2192 run \u2192 analysis \u2192 release) at the end.`
1934
+ }
1935
+ }
1936
+ ]
1937
+ };
1938
+ }
1939
+ );
1940
+ }
1941
+
1942
+ // src/modules/cosmicintersection/index.ts
1943
+ var cosmicintersectionModule = {
1944
+ id: "cosmicintersection",
1945
+ version: "0.0.1",
1946
+ displayName: "Cosmicintersection",
1947
+ dependsOn: ["auth"],
1948
+ capabilities: { tools: {}, resources: {}, prompts: {} },
1949
+ register(server, ctx) {
1950
+ const tools = [];
1951
+ const resources = [];
1952
+ const prompts = [];
1953
+ const trackTool = (n) => {
1954
+ tools.push(n);
1955
+ return n;
1956
+ };
1957
+ const trackResource = (uri) => {
1958
+ resources.push(uri);
1959
+ return uri;
1960
+ };
1961
+ const trackPrompt = (n) => {
1962
+ prompts.push(n);
1963
+ return n;
1964
+ };
1965
+ registerSourceTools(server, ctx, trackTool);
1966
+ registerDatasetTools(server, ctx, trackTool);
1967
+ registerCollectionTools(server, ctx, trackTool);
1968
+ registerPipelineTools(server, ctx, trackTool);
1969
+ registerRunTools(server, ctx, trackTool);
1970
+ registerNotebookTools(server, ctx, trackTool);
1971
+ registerAnalysisTools(server, ctx, trackTool);
1972
+ registerReleaseTools(server, ctx, trackTool);
1973
+ registerGrantTools(server, ctx, trackTool);
1974
+ registerHealthTools(server, ctx, trackTool);
1975
+ registerCosmicintersectionResources(server, ctx, trackResource);
1976
+ registerCosmicintersectionPrompts(server, ctx, trackPrompt);
1977
+ return { tools, resources, prompts };
1978
+ }
1979
+ };
1980
+ var cosmicintersection_default = cosmicintersectionModule;
1981
+
1982
+ module.exports = cosmicintersection_default;
1983
+ //# sourceMappingURL=index.cjs.map
1984
+ //# sourceMappingURL=index.cjs.map