@transcend-io/mcp-server-inventory 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +92 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +17 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/graphql-hWIhKdeR.mjs +557 -0
- package/dist/graphql-hWIhKdeR.mjs.map +1 -0
- package/dist/index.d.mts +83 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +2 -0
- package/package.json +55 -0
package/README.md
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# @transcend-io/mcp-server-inventory
|
|
2
|
+
|
|
3
|
+
> **Alpha** — this package is under active development and has not yet been published to npm. APIs may change without notice.
|
|
4
|
+
|
|
5
|
+
Transcend MCP Server for data inventory management. Provides tools for managing data silos (integrations), data points, vendors, categories, and identifiers.
|
|
6
|
+
|
|
7
|
+
Requires **Node.js ≥ 22.12** (see `engines` in `package.json`).
|
|
8
|
+
|
|
9
|
+
For local runs from this repository, copy [`secret.env.example`](../../../secret.env.example) to **`secret.env`** at the repo root (gitignored) and set your API key (see **Run from the monorepo**).
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
When the package is available on npm, install the CLI globally:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install -g @transcend-io/mcp-server-inventory
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Until then, run from a checkout of this repository (see **Run from the monorepo** below).
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
# With TRANSCEND_API_KEY in the environment; from the monorepo use secret.env (see Run from the monorepo)
|
|
25
|
+
TRANSCEND_API_KEY=your-api-key transcend-mcp-inventory
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The process speaks MCP over **stdio** and is meant to be launched by an MCP client (for example Cursor or Claude Desktop), not used as an interactive shell.
|
|
29
|
+
|
|
30
|
+
### MCP client configuration
|
|
31
|
+
|
|
32
|
+
`npx` runs the package’s `transcend-mcp-inventory` binary (see `bin` in `package.json`).
|
|
33
|
+
|
|
34
|
+
```json
|
|
35
|
+
{
|
|
36
|
+
"mcpServers": {
|
|
37
|
+
"transcend-inventory": {
|
|
38
|
+
"command": "npx",
|
|
39
|
+
"args": ["-y", "@transcend-io/mcp-server-inventory"],
|
|
40
|
+
"env": {
|
|
41
|
+
"TRANSCEND_API_KEY": "your-api-key"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
When developing in this repository, reuse the same variable names from root **`secret.env`** in the `env` block, or use your client’s env-file support if it has one.
|
|
49
|
+
|
|
50
|
+
### Run from the monorepo
|
|
51
|
+
|
|
52
|
+
1. **Credentials** — From the repository root, copy [`secret.env.example`](../../../secret.env.example) to **`secret.env`** and set `TRANSCEND_API_KEY` (and optional URL overrides).
|
|
53
|
+
|
|
54
|
+
2. **Build and run** — `node ./dist/cli.mjs` matches the `transcend-mcp-inventory` `bin` (use `node` because `pnpm exec transcend-mcp-inventory` may not resolve this package’s own binary in a pnpm workspace):
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# from the repository root
|
|
58
|
+
pnpm exec turbo run build --filter="@transcend-io/mcp-server-inventory..."
|
|
59
|
+
set -a && source ./secret.env && set +a
|
|
60
|
+
pnpm -F @transcend-io/mcp-server-inventory exec node ./dist/cli.mjs
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**Alternative:** `./scripts/mcp-run.sh ./packages/mcp/mcp-server-inventory/dist/cli.mjs` (sources `secret.env` when present; run after build).
|
|
64
|
+
|
|
65
|
+
See [CONTRIBUTING.md](../../../CONTRIBUTING.md#mcp-servers) for workspace layout and `pnpm --filter` workflows.
|
|
66
|
+
|
|
67
|
+
### Environment variables
|
|
68
|
+
|
|
69
|
+
| Variable | Required | Default | Description |
|
|
70
|
+
| ----------------------- | -------- | ------------------------------------------ | ----------------- |
|
|
71
|
+
| `TRANSCEND_API_KEY` | Yes | — | Transcend API key |
|
|
72
|
+
| `TRANSCEND_API_URL` | No | `https://multi-tenant.sombra.transcend.io` | Sombra API URL |
|
|
73
|
+
| `TRANSCEND_GRAPHQL_URL` | No | `https://api.transcend.io` | GraphQL API URL |
|
|
74
|
+
|
|
75
|
+
**Monorepo:** keep these in root **`secret.env`** (from [`secret.env.example`](../../../secret.env.example)); see **Run from the monorepo**.
|
|
76
|
+
|
|
77
|
+
## Tools
|
|
78
|
+
|
|
79
|
+
- `inventory_list_data_silos` — List data silos (integrations)
|
|
80
|
+
- `inventory_get_data_silo` — Get data silo details
|
|
81
|
+
- `inventory_create_data_silo` — Create a data silo
|
|
82
|
+
- `inventory_update_data_silo` — Update a data silo
|
|
83
|
+
- `inventory_list_data_points` — List data points
|
|
84
|
+
- `inventory_list_sub_data_points` — List sub-data points
|
|
85
|
+
- `inventory_list_categories` — List data categories
|
|
86
|
+
- `inventory_list_identifiers` — List identifiers
|
|
87
|
+
- `inventory_list_vendors` — List vendors
|
|
88
|
+
- `inventory_analyze` — Analyze inventory data
|
|
89
|
+
|
|
90
|
+
## Related packages
|
|
91
|
+
|
|
92
|
+
Also available as part of the unified [`@transcend-io/mcp-server`](../mcp-server/README.md) which includes all domains. See the [root README](../../../README.md#mcp-servers) for the full list.
|
package/dist/cli.d.mts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
package/dist/cli.mjs
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { n as getInventoryTools, t as InventoryMixin } from "./graphql-hWIhKdeR.mjs";
|
|
3
|
+
import { TranscendRestClient, createMCPServer } from "@transcend-io/mcp-server-core";
|
|
4
|
+
//#region src/cli.ts
|
|
5
|
+
createMCPServer({
|
|
6
|
+
name: "transcend-mcp-inventory",
|
|
7
|
+
version: "1.0.0",
|
|
8
|
+
getTools: getInventoryTools,
|
|
9
|
+
createClients: (auth, sombraUrl, graphqlUrl) => ({
|
|
10
|
+
rest: new TranscendRestClient(auth, sombraUrl),
|
|
11
|
+
graphql: new InventoryMixin(auth, graphqlUrl)
|
|
12
|
+
})
|
|
13
|
+
});
|
|
14
|
+
//#endregion
|
|
15
|
+
export {};
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=cli.mjs.map
|
package/dist/cli.mjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.mjs","names":[],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { createMCPServer, TranscendRestClient } from '@transcend-io/mcp-server-core';\n\nimport { InventoryMixin } from './graphql.js';\nimport { getInventoryTools } from './tools/index.js';\n\ncreateMCPServer({\n name: 'transcend-mcp-inventory',\n version: '1.0.0',\n getTools: getInventoryTools,\n createClients: (auth, sombraUrl, graphqlUrl) => ({\n rest: new TranscendRestClient(auth, sombraUrl),\n graphql: new InventoryMixin(auth, graphqlUrl),\n }),\n});\n"],"mappings":";;;;AAMA,gBAAgB;CACd,MAAM;CACN,SAAS;CACT,UAAU;CACV,gBAAgB,MAAM,WAAW,gBAAgB;EAC/C,MAAM,IAAI,oBAAoB,MAAM,UAAU;EAC9C,SAAS,IAAI,eAAe,MAAM,WAAW;EAC9C;CACF,CAAC"}
|
|
@@ -0,0 +1,557 @@
|
|
|
1
|
+
import { EmptySchema, TranscendGraphQLBase, createListResult, createToolResult, defineTool, groupBy, z } from "@transcend-io/mcp-server-core";
|
|
2
|
+
//#region src/tools/inventory_analyze.ts
|
|
3
|
+
function createInventoryAnalyzeTool(clients) {
|
|
4
|
+
const graphql = clients.graphql;
|
|
5
|
+
return defineTool({
|
|
6
|
+
name: "inventory_analyze",
|
|
7
|
+
description: "Analyze your data inventory including data silos by type, vendor distribution, and data point coverage",
|
|
8
|
+
category: "Data Inventory",
|
|
9
|
+
readOnly: true,
|
|
10
|
+
annotations: {
|
|
11
|
+
readOnlyHint: true,
|
|
12
|
+
destructiveHint: false,
|
|
13
|
+
idempotentHint: true
|
|
14
|
+
},
|
|
15
|
+
zodSchema: EmptySchema,
|
|
16
|
+
handler: async (_args) => {
|
|
17
|
+
const [dataSilosResult, vendorsResult, identifiersResult, categoriesResult] = await Promise.all([
|
|
18
|
+
graphql.listDataSilos({ first: 100 }),
|
|
19
|
+
graphql.listVendors({ first: 100 }),
|
|
20
|
+
graphql.listIdentifiers({ first: 100 }),
|
|
21
|
+
graphql.listDataCategories({ first: 100 })
|
|
22
|
+
]);
|
|
23
|
+
const dataSilos = dataSilosResult.nodes;
|
|
24
|
+
const vendors = vendorsResult.nodes;
|
|
25
|
+
const identifiers = identifiersResult.nodes;
|
|
26
|
+
const categories = categoriesResult.nodes;
|
|
27
|
+
const liveDataSilos = dataSilos.filter((ds) => ds.isLive);
|
|
28
|
+
return createToolResult(true, {
|
|
29
|
+
summary: {
|
|
30
|
+
totalDataSilos: dataSilos.length,
|
|
31
|
+
liveDataSilos: liveDataSilos.length,
|
|
32
|
+
totalVendors: vendors.length,
|
|
33
|
+
totalIdentifiers: identifiers.length,
|
|
34
|
+
totalCategories: categories.length
|
|
35
|
+
},
|
|
36
|
+
breakdown: {
|
|
37
|
+
dataSilosByType: groupBy(dataSilos, "type"),
|
|
38
|
+
dataSilosByOuterType: groupBy(dataSilos.filter((ds) => ds.outerType), "outerType")
|
|
39
|
+
},
|
|
40
|
+
topIdentifiers: identifiers.slice(0, 10).map((id) => ({
|
|
41
|
+
name: id.name,
|
|
42
|
+
type: id.type,
|
|
43
|
+
isRequired: id.isRequiredInForm
|
|
44
|
+
})),
|
|
45
|
+
topCategories: categories.slice(0, 10).map((cat) => ({
|
|
46
|
+
name: cat.name,
|
|
47
|
+
category: cat.category
|
|
48
|
+
})),
|
|
49
|
+
recommendations: [
|
|
50
|
+
dataSilos.length === 0 ? "Add data silos to map your data landscape" : null,
|
|
51
|
+
liveDataSilos.length < dataSilos.length ? `${dataSilos.length - liveDataSilos.length} data silos are not live - consider activating them` : null,
|
|
52
|
+
vendors.length === 0 ? "Add vendors to track third-party data processors" : null
|
|
53
|
+
].filter(Boolean)
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
//#endregion
|
|
59
|
+
//#region src/tools/inventory_create_data_silo.ts
|
|
60
|
+
const CreateDataSiloSchema = z.object({ title: z.string().describe("Name/title of the data silo (must match an integrationName in the Transcend catalog, e.g. \"Salesforce\", \"Stripe\")") });
|
|
61
|
+
function createInventoryCreateDataSiloTool(clients) {
|
|
62
|
+
const graphql = clients.graphql;
|
|
63
|
+
return defineTool({
|
|
64
|
+
name: "inventory_create_data_silo",
|
|
65
|
+
description: "Create a new data silo (data system or integration). The name must match an integration name from the Transcend catalog.",
|
|
66
|
+
category: "Data Inventory",
|
|
67
|
+
readOnly: false,
|
|
68
|
+
confirmationHint: "Creates a new data silo in the inventory",
|
|
69
|
+
annotations: {
|
|
70
|
+
readOnlyHint: false,
|
|
71
|
+
destructiveHint: true,
|
|
72
|
+
idempotentHint: false
|
|
73
|
+
},
|
|
74
|
+
zodSchema: CreateDataSiloSchema,
|
|
75
|
+
handler: async ({ title }) => {
|
|
76
|
+
return createToolResult(true, {
|
|
77
|
+
dataSilo: await graphql.createDataSilo({ name: title }),
|
|
78
|
+
message: `Data silo "${title}" created successfully`
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
//#endregion
|
|
84
|
+
//#region src/tools/inventory_get_data_silo.ts
|
|
85
|
+
const GetDataSiloSchema = z.object({ data_silo_id: z.string().describe("ID of the data silo to retrieve") });
|
|
86
|
+
function createInventoryGetDataSiloTool(clients) {
|
|
87
|
+
const graphql = clients.graphql;
|
|
88
|
+
return defineTool({
|
|
89
|
+
name: "inventory_get_data_silo",
|
|
90
|
+
description: "Get detailed information about a specific data silo including its data points and identifiers",
|
|
91
|
+
category: "Data Inventory",
|
|
92
|
+
readOnly: true,
|
|
93
|
+
annotations: {
|
|
94
|
+
readOnlyHint: true,
|
|
95
|
+
destructiveHint: false,
|
|
96
|
+
idempotentHint: true
|
|
97
|
+
},
|
|
98
|
+
zodSchema: GetDataSiloSchema,
|
|
99
|
+
handler: async ({ data_silo_id }) => {
|
|
100
|
+
return createToolResult(true, await graphql.getDataSilo(data_silo_id));
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
//#endregion
|
|
105
|
+
//#region src/tools/inventory_list_categories.ts
|
|
106
|
+
const ListCategoriesSchema = z.object({
|
|
107
|
+
limit: z.coerce.number().min(1).max(100).optional().default(50).describe("Results per page (1-100, default: 50)"),
|
|
108
|
+
cursor: z.string().optional().describe("Pagination cursor from previous response (where supported)")
|
|
109
|
+
});
|
|
110
|
+
function createInventoryListCategoriesTool(clients) {
|
|
111
|
+
const graphql = clients.graphql;
|
|
112
|
+
return defineTool({
|
|
113
|
+
name: "inventory_list_categories",
|
|
114
|
+
description: "List all data categories (PII types) configured in your organization. Note: API does not support cursor pagination (max ~100 results).",
|
|
115
|
+
category: "Data Inventory",
|
|
116
|
+
readOnly: true,
|
|
117
|
+
annotations: {
|
|
118
|
+
readOnlyHint: true,
|
|
119
|
+
destructiveHint: false,
|
|
120
|
+
idempotentHint: true
|
|
121
|
+
},
|
|
122
|
+
zodSchema: ListCategoriesSchema,
|
|
123
|
+
handler: async ({ limit, cursor }) => {
|
|
124
|
+
const result = await graphql.listDataCategories({
|
|
125
|
+
first: limit,
|
|
126
|
+
after: cursor
|
|
127
|
+
});
|
|
128
|
+
return createListResult(result.nodes, {
|
|
129
|
+
totalCount: result.totalCount,
|
|
130
|
+
hasNextPage: result.pageInfo?.hasNextPage
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
//#endregion
|
|
136
|
+
//#region src/tools/inventory_list_data_points.ts
|
|
137
|
+
const ListDataPointsSchema = z.object({
|
|
138
|
+
limit: z.coerce.number().min(1).max(100).optional().default(50).describe("Results per page (1-100, default: 50)"),
|
|
139
|
+
cursor: z.string().optional().describe("Pagination cursor from previous response (where supported)")
|
|
140
|
+
});
|
|
141
|
+
function createInventoryListDataPointsTool(clients) {
|
|
142
|
+
const graphql = clients.graphql;
|
|
143
|
+
return defineTool({
|
|
144
|
+
name: "inventory_list_data_points",
|
|
145
|
+
description: "List data points (collections of personal data). Note: API does not support cursor pagination or data_silo filtering (max ~100 results).",
|
|
146
|
+
category: "Data Inventory",
|
|
147
|
+
readOnly: true,
|
|
148
|
+
annotations: {
|
|
149
|
+
readOnlyHint: true,
|
|
150
|
+
destructiveHint: false,
|
|
151
|
+
idempotentHint: true
|
|
152
|
+
},
|
|
153
|
+
zodSchema: ListDataPointsSchema,
|
|
154
|
+
handler: async ({ limit, cursor }) => {
|
|
155
|
+
const result = await graphql.listDataPoints(void 0, {
|
|
156
|
+
first: limit,
|
|
157
|
+
after: cursor
|
|
158
|
+
});
|
|
159
|
+
return createListResult(result.nodes, {
|
|
160
|
+
totalCount: result.totalCount,
|
|
161
|
+
hasNextPage: result.pageInfo?.hasNextPage
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
//#endregion
|
|
167
|
+
//#region src/tools/inventory_list_data_silos.ts
|
|
168
|
+
const ListDataSilosSchema = z.object({
|
|
169
|
+
limit: z.coerce.number().min(1).max(100).optional().default(50).describe("Results per page (1-100, default: 50)"),
|
|
170
|
+
cursor: z.string().optional().describe("Pagination cursor from previous response (where supported)")
|
|
171
|
+
});
|
|
172
|
+
function createInventoryListDataSilosTool(clients) {
|
|
173
|
+
const graphql = clients.graphql;
|
|
174
|
+
return defineTool({
|
|
175
|
+
name: "inventory_list_data_silos",
|
|
176
|
+
description: "List all data silos (data systems and integrations) in your organization. Note: API does not support cursor pagination (max ~100 results).",
|
|
177
|
+
category: "Data Inventory",
|
|
178
|
+
readOnly: true,
|
|
179
|
+
annotations: {
|
|
180
|
+
readOnlyHint: true,
|
|
181
|
+
destructiveHint: false,
|
|
182
|
+
idempotentHint: true
|
|
183
|
+
},
|
|
184
|
+
zodSchema: ListDataSilosSchema,
|
|
185
|
+
handler: async ({ limit, cursor }) => {
|
|
186
|
+
const result = await graphql.listDataSilos({
|
|
187
|
+
first: limit,
|
|
188
|
+
after: cursor
|
|
189
|
+
});
|
|
190
|
+
return createListResult(result.nodes, {
|
|
191
|
+
totalCount: result.totalCount,
|
|
192
|
+
hasNextPage: result.pageInfo?.hasNextPage
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
//#endregion
|
|
198
|
+
//#region src/tools/inventory_list_identifiers.ts
|
|
199
|
+
const ListIdentifiersSchema = z.object({
|
|
200
|
+
limit: z.coerce.number().min(1).max(100).optional().default(50).describe("Results per page (1-100, default: 50)"),
|
|
201
|
+
cursor: z.string().optional().describe("Pagination cursor from previous response (where supported)")
|
|
202
|
+
});
|
|
203
|
+
function createInventoryListIdentifiersTool(clients) {
|
|
204
|
+
const graphql = clients.graphql;
|
|
205
|
+
return defineTool({
|
|
206
|
+
name: "inventory_list_identifiers",
|
|
207
|
+
description: "List all identifier types (email, user ID, etc.) configured in your organization. Note: API does not support cursor pagination (max ~100 results).",
|
|
208
|
+
category: "Data Inventory",
|
|
209
|
+
readOnly: true,
|
|
210
|
+
annotations: {
|
|
211
|
+
readOnlyHint: true,
|
|
212
|
+
destructiveHint: false,
|
|
213
|
+
idempotentHint: true
|
|
214
|
+
},
|
|
215
|
+
zodSchema: ListIdentifiersSchema,
|
|
216
|
+
handler: async ({ limit, cursor }) => {
|
|
217
|
+
const result = await graphql.listIdentifiers({
|
|
218
|
+
first: limit,
|
|
219
|
+
after: cursor
|
|
220
|
+
});
|
|
221
|
+
return createListResult(result.nodes, {
|
|
222
|
+
totalCount: result.totalCount,
|
|
223
|
+
hasNextPage: result.pageInfo?.hasNextPage
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
//#endregion
|
|
229
|
+
//#region src/tools/inventory_list_sub_data_points.ts
|
|
230
|
+
const ListSubDataPointsSchema = z.object({
|
|
231
|
+
data_point_id: z.string().describe("ID of the parent data point"),
|
|
232
|
+
limit: z.coerce.number().min(1).max(100).optional().default(50).describe("Results per page (1-100, default: 50)"),
|
|
233
|
+
offset: z.coerce.number().min(0).optional().default(0).describe("Number of results to skip (default: 0)")
|
|
234
|
+
});
|
|
235
|
+
function createInventoryListSubDataPointsTool(clients) {
|
|
236
|
+
const graphql = clients.graphql;
|
|
237
|
+
return defineTool({
|
|
238
|
+
name: "inventory_list_sub_data_points",
|
|
239
|
+
description: "List sub-data points (individual data fields) for a specific data point. Note: This feature may have limited availability.",
|
|
240
|
+
category: "Data Inventory",
|
|
241
|
+
readOnly: true,
|
|
242
|
+
annotations: {
|
|
243
|
+
readOnlyHint: true,
|
|
244
|
+
destructiveHint: false,
|
|
245
|
+
idempotentHint: true
|
|
246
|
+
},
|
|
247
|
+
zodSchema: ListSubDataPointsSchema,
|
|
248
|
+
handler: async ({ data_point_id, limit, offset }) => {
|
|
249
|
+
const result = await graphql.listSubDataPoints(data_point_id, {
|
|
250
|
+
first: limit,
|
|
251
|
+
offset
|
|
252
|
+
});
|
|
253
|
+
return createListResult(result.nodes, {
|
|
254
|
+
totalCount: result.totalCount,
|
|
255
|
+
hasNextPage: result.pageInfo?.hasNextPage
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
//#endregion
|
|
261
|
+
//#region src/tools/inventory_list_vendors.ts
|
|
262
|
+
const ListVendorsSchema = z.object({
|
|
263
|
+
limit: z.coerce.number().min(1).max(100).optional().default(50).describe("Results per page (1-100, default: 50)"),
|
|
264
|
+
cursor: z.string().optional().describe("Pagination cursor from previous response (where supported)")
|
|
265
|
+
});
|
|
266
|
+
function createInventoryListVendorsTool(clients) {
|
|
267
|
+
const graphql = clients.graphql;
|
|
268
|
+
return defineTool({
|
|
269
|
+
name: "inventory_list_vendors",
|
|
270
|
+
description: "List all vendors (third-party data processors) in your organization. Note: API does not support cursor pagination (max ~100 results).",
|
|
271
|
+
category: "Data Inventory",
|
|
272
|
+
readOnly: true,
|
|
273
|
+
annotations: {
|
|
274
|
+
readOnlyHint: true,
|
|
275
|
+
destructiveHint: false,
|
|
276
|
+
idempotentHint: true
|
|
277
|
+
},
|
|
278
|
+
zodSchema: ListVendorsSchema,
|
|
279
|
+
handler: async ({ limit, cursor }) => {
|
|
280
|
+
const result = await graphql.listVendors({
|
|
281
|
+
first: limit,
|
|
282
|
+
after: cursor
|
|
283
|
+
});
|
|
284
|
+
return createListResult(result.nodes, {
|
|
285
|
+
totalCount: result.totalCount,
|
|
286
|
+
hasNextPage: result.pageInfo?.hasNextPage
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
//#endregion
|
|
292
|
+
//#region src/tools/inventory_update_data_silo.ts
|
|
293
|
+
const UpdateDataSiloSchema = z.object({
|
|
294
|
+
data_silo_id: z.string().describe("ID of the data silo to update"),
|
|
295
|
+
title: z.string().optional().describe("New title for the data silo"),
|
|
296
|
+
description: z.string().optional().describe("New description")
|
|
297
|
+
});
|
|
298
|
+
function createInventoryUpdateDataSiloTool(clients) {
|
|
299
|
+
const graphql = clients.graphql;
|
|
300
|
+
return defineTool({
|
|
301
|
+
name: "inventory_update_data_silo",
|
|
302
|
+
description: "Update an existing data silo",
|
|
303
|
+
category: "Data Inventory",
|
|
304
|
+
readOnly: false,
|
|
305
|
+
confirmationHint: "Updates the data silo configuration",
|
|
306
|
+
annotations: {
|
|
307
|
+
readOnlyHint: false,
|
|
308
|
+
destructiveHint: false,
|
|
309
|
+
idempotentHint: true
|
|
310
|
+
},
|
|
311
|
+
zodSchema: UpdateDataSiloSchema,
|
|
312
|
+
handler: async ({ data_silo_id, title, description }) => {
|
|
313
|
+
return createToolResult(true, {
|
|
314
|
+
dataSilo: await graphql.updateDataSilo({
|
|
315
|
+
id: data_silo_id,
|
|
316
|
+
title,
|
|
317
|
+
description
|
|
318
|
+
}),
|
|
319
|
+
message: "Data silo updated successfully"
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
//#endregion
|
|
325
|
+
//#region src/tools/index.ts
|
|
326
|
+
function getInventoryTools(clients) {
|
|
327
|
+
return [
|
|
328
|
+
createInventoryListDataSilosTool(clients),
|
|
329
|
+
createInventoryGetDataSiloTool(clients),
|
|
330
|
+
createInventoryCreateDataSiloTool(clients),
|
|
331
|
+
createInventoryUpdateDataSiloTool(clients),
|
|
332
|
+
createInventoryListVendorsTool(clients),
|
|
333
|
+
createInventoryListDataPointsTool(clients),
|
|
334
|
+
createInventoryListSubDataPointsTool(clients),
|
|
335
|
+
createInventoryListIdentifiersTool(clients),
|
|
336
|
+
createInventoryListCategoriesTool(clients),
|
|
337
|
+
createInventoryAnalyzeTool(clients)
|
|
338
|
+
];
|
|
339
|
+
}
|
|
340
|
+
//#endregion
|
|
341
|
+
//#region src/graphql.ts
|
|
342
|
+
var InventoryMixin = class extends TranscendGraphQLBase {
|
|
343
|
+
async listDataSilos(options) {
|
|
344
|
+
const data = await this.makeRequest(`
|
|
345
|
+
query ListDataSilos($first: Int) {
|
|
346
|
+
dataSilos(first: $first) {
|
|
347
|
+
nodes {
|
|
348
|
+
id
|
|
349
|
+
title
|
|
350
|
+
type
|
|
351
|
+
}
|
|
352
|
+
totalCount
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
`, { first: Math.min(options?.first || 100, 100) });
|
|
356
|
+
return {
|
|
357
|
+
nodes: data.dataSilos.nodes,
|
|
358
|
+
pageInfo: {
|
|
359
|
+
hasNextPage: data.dataSilos.nodes.length < data.dataSilos.totalCount,
|
|
360
|
+
hasPreviousPage: false
|
|
361
|
+
},
|
|
362
|
+
totalCount: data.dataSilos.totalCount
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
async getDataSilo(id) {
|
|
366
|
+
return (await this.makeRequest(`
|
|
367
|
+
query GetDataSilo($id: String!) {
|
|
368
|
+
dataSilo(id: $id) {
|
|
369
|
+
id
|
|
370
|
+
title
|
|
371
|
+
type
|
|
372
|
+
description
|
|
373
|
+
link
|
|
374
|
+
isLive
|
|
375
|
+
outerType
|
|
376
|
+
createdAt
|
|
377
|
+
connectionState
|
|
378
|
+
identifiers {
|
|
379
|
+
id
|
|
380
|
+
name
|
|
381
|
+
type
|
|
382
|
+
isRequiredInForm
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
`, { id })).dataSilo;
|
|
387
|
+
}
|
|
388
|
+
async createDataSilo(input) {
|
|
389
|
+
const created = (await this.makeRequest(`
|
|
390
|
+
mutation CreateDataSilos($input: [CreateDataSilosInput!]!) {
|
|
391
|
+
createDataSilos(input: $input) {
|
|
392
|
+
dataSilos {
|
|
393
|
+
id
|
|
394
|
+
title
|
|
395
|
+
type
|
|
396
|
+
description
|
|
397
|
+
isLive
|
|
398
|
+
createdAt
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
`, { input: [input] })).createDataSilos.dataSilos[0];
|
|
403
|
+
if (!created) throw new Error("createDataSilos returned an empty array");
|
|
404
|
+
return created;
|
|
405
|
+
}
|
|
406
|
+
async updateDataSilo(input) {
|
|
407
|
+
const mutation = `
|
|
408
|
+
mutation UpdateDataSilos($input: UpdateDataSilosInput!) {
|
|
409
|
+
updateDataSilos(input: $input) {
|
|
410
|
+
dataSilos {
|
|
411
|
+
id
|
|
412
|
+
title
|
|
413
|
+
type
|
|
414
|
+
description
|
|
415
|
+
isLive
|
|
416
|
+
createdAt
|
|
417
|
+
updatedAt
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
`;
|
|
422
|
+
const wrappedInput = { dataSilos: [input] };
|
|
423
|
+
const updated = (await this.makeRequest(mutation, { input: wrappedInput })).updateDataSilos.dataSilos[0];
|
|
424
|
+
if (!updated) throw new Error("updateDataSilos returned an empty array");
|
|
425
|
+
return updated;
|
|
426
|
+
}
|
|
427
|
+
async listVendors(options) {
|
|
428
|
+
const data = await this.makeRequest(`
|
|
429
|
+
query ListVendors($first: Int) {
|
|
430
|
+
vendors(first: $first) {
|
|
431
|
+
nodes {
|
|
432
|
+
id
|
|
433
|
+
title
|
|
434
|
+
}
|
|
435
|
+
totalCount
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
`, { first: Math.min(options?.first || 100, 100) });
|
|
439
|
+
return {
|
|
440
|
+
nodes: data.vendors.nodes,
|
|
441
|
+
pageInfo: {
|
|
442
|
+
hasNextPage: data.vendors.nodes.length < data.vendors.totalCount,
|
|
443
|
+
hasPreviousPage: false
|
|
444
|
+
},
|
|
445
|
+
totalCount: data.vendors.totalCount
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
async listDataPoints(_dataSiloId, options) {
|
|
449
|
+
const data = await this.makeRequest(`
|
|
450
|
+
query ListDataPoints($first: Int) {
|
|
451
|
+
dataPoints(first: $first) {
|
|
452
|
+
nodes {
|
|
453
|
+
id
|
|
454
|
+
name
|
|
455
|
+
title {
|
|
456
|
+
defaultMessage
|
|
457
|
+
}
|
|
458
|
+
description {
|
|
459
|
+
defaultMessage
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
totalCount
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
`, { first: Math.min(options?.first || 100, 100) });
|
|
466
|
+
const points = data.dataPoints.nodes.map((dp) => ({
|
|
467
|
+
id: dp.id,
|
|
468
|
+
name: dp.name,
|
|
469
|
+
title: dp.title?.defaultMessage,
|
|
470
|
+
description: dp.description?.defaultMessage,
|
|
471
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
472
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
473
|
+
}));
|
|
474
|
+
return {
|
|
475
|
+
nodes: points,
|
|
476
|
+
pageInfo: {
|
|
477
|
+
hasNextPage: points.length < data.dataPoints.totalCount,
|
|
478
|
+
hasPreviousPage: false
|
|
479
|
+
},
|
|
480
|
+
totalCount: data.dataPoints.totalCount
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
async listSubDataPoints(dataPointId, options) {
|
|
484
|
+
const data = await this.makeRequest(`
|
|
485
|
+
query ListSubDataPoints($first: Int, $offset: Int, $filterBy: SubDataPointFiltersInput) {
|
|
486
|
+
subDataPoints(first: $first, offset: $offset, filterBy: $filterBy) {
|
|
487
|
+
nodes {
|
|
488
|
+
id
|
|
489
|
+
name
|
|
490
|
+
description
|
|
491
|
+
accessRequestVisibilityEnabled
|
|
492
|
+
}
|
|
493
|
+
totalCount
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
`, {
|
|
497
|
+
first: Math.min(options?.first || 100, 100),
|
|
498
|
+
offset: options?.offset || 0,
|
|
499
|
+
filterBy: { dataPoints: [dataPointId] }
|
|
500
|
+
});
|
|
501
|
+
return {
|
|
502
|
+
nodes: data.subDataPoints.nodes,
|
|
503
|
+
pageInfo: {
|
|
504
|
+
hasNextPage: data.subDataPoints.nodes.length < data.subDataPoints.totalCount,
|
|
505
|
+
hasPreviousPage: false
|
|
506
|
+
},
|
|
507
|
+
totalCount: data.subDataPoints.totalCount
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
async listIdentifiers(options) {
|
|
511
|
+
const data = await this.makeRequest(`
|
|
512
|
+
query ListIdentifiers($first: Int) {
|
|
513
|
+
identifiers(first: $first) {
|
|
514
|
+
nodes {
|
|
515
|
+
id
|
|
516
|
+
name
|
|
517
|
+
type
|
|
518
|
+
}
|
|
519
|
+
totalCount
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
`, { first: Math.min(options?.first || 100, 100) });
|
|
523
|
+
return {
|
|
524
|
+
nodes: data.identifiers.nodes,
|
|
525
|
+
pageInfo: {
|
|
526
|
+
hasNextPage: data.identifiers.nodes.length < data.identifiers.totalCount,
|
|
527
|
+
hasPreviousPage: false
|
|
528
|
+
},
|
|
529
|
+
totalCount: data.identifiers.totalCount
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
async listDataCategories(options) {
|
|
533
|
+
const data = await this.makeRequest(`
|
|
534
|
+
query ListDataCategories($first: Int) {
|
|
535
|
+
dataCategories(first: $first) {
|
|
536
|
+
nodes {
|
|
537
|
+
name
|
|
538
|
+
category
|
|
539
|
+
}
|
|
540
|
+
totalCount
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
`, { first: Math.min(options?.first || 100, 100) });
|
|
544
|
+
return {
|
|
545
|
+
nodes: data.dataCategories.nodes,
|
|
546
|
+
pageInfo: {
|
|
547
|
+
hasNextPage: data.dataCategories.nodes.length < data.dataCategories.totalCount,
|
|
548
|
+
hasPreviousPage: false
|
|
549
|
+
},
|
|
550
|
+
totalCount: data.dataCategories.totalCount
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
};
|
|
554
|
+
//#endregion
|
|
555
|
+
export { ListSubDataPointsSchema as a, ListDataPointsSchema as c, CreateDataSiloSchema as d, ListVendorsSchema as i, ListCategoriesSchema as l, getInventoryTools as n, ListIdentifiersSchema as o, UpdateDataSiloSchema as r, ListDataSilosSchema as s, InventoryMixin as t, GetDataSiloSchema as u };
|
|
556
|
+
|
|
557
|
+
//# sourceMappingURL=graphql-hWIhKdeR.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graphql-hWIhKdeR.mjs","names":[],"sources":["../src/tools/inventory_analyze.ts","../src/tools/inventory_create_data_silo.ts","../src/tools/inventory_get_data_silo.ts","../src/tools/inventory_list_categories.ts","../src/tools/inventory_list_data_points.ts","../src/tools/inventory_list_data_silos.ts","../src/tools/inventory_list_identifiers.ts","../src/tools/inventory_list_sub_data_points.ts","../src/tools/inventory_list_vendors.ts","../src/tools/inventory_update_data_silo.ts","../src/tools/index.ts","../src/graphql.ts"],"sourcesContent":["import {\n createToolResult,\n defineTool,\n EmptySchema,\n groupBy,\n type ToolClients,\n} from '@transcend-io/mcp-server-core';\n\nimport type { InventoryMixin } from '../graphql.js';\n\nexport function createInventoryAnalyzeTool(clients: ToolClients) {\n const graphql = clients.graphql as InventoryMixin;\n return defineTool({\n name: 'inventory_analyze',\n description:\n 'Analyze your data inventory including data silos by type, vendor distribution, and data point coverage',\n category: 'Data Inventory',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: EmptySchema,\n handler: async (_args) => {\n const [dataSilosResult, vendorsResult, identifiersResult, categoriesResult] =\n await Promise.all([\n graphql.listDataSilos({ first: 100 }),\n graphql.listVendors({ first: 100 }),\n graphql.listIdentifiers({ first: 100 }),\n graphql.listDataCategories({ first: 100 }),\n ]);\n\n const dataSilos = dataSilosResult.nodes;\n const vendors = vendorsResult.nodes;\n const identifiers = identifiersResult.nodes;\n const categories = categoriesResult.nodes;\n\n const liveDataSilos = dataSilos.filter((ds) => ds.isLive);\n\n return createToolResult(true, {\n summary: {\n totalDataSilos: dataSilos.length,\n liveDataSilos: liveDataSilos.length,\n totalVendors: vendors.length,\n totalIdentifiers: identifiers.length,\n totalCategories: categories.length,\n },\n breakdown: {\n dataSilosByType: groupBy(dataSilos, 'type'),\n dataSilosByOuterType: groupBy(\n dataSilos.filter((ds) => ds.outerType),\n 'outerType' as keyof (typeof dataSilos)[0],\n ),\n },\n topIdentifiers: identifiers.slice(0, 10).map((id) => ({\n name: id.name,\n type: id.type,\n isRequired: id.isRequiredInForm,\n })),\n topCategories: categories.slice(0, 10).map((cat) => ({\n name: cat.name,\n category: cat.category,\n })),\n recommendations: [\n dataSilos.length === 0 ? 'Add data silos to map your data landscape' : null,\n liveDataSilos.length < dataSilos.length\n ? `${dataSilos.length - liveDataSilos.length} data silos are not live - consider activating them`\n : null,\n vendors.length === 0 ? 'Add vendors to track third-party data processors' : null,\n ].filter(Boolean),\n });\n },\n });\n}\n","import { createToolResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-core';\n\nimport type { InventoryMixin } from '../graphql.js';\n\nexport const CreateDataSiloSchema = z.object({\n title: z\n .string()\n .describe(\n 'Name/title of the data silo (must match an integrationName in the Transcend catalog, e.g. \"Salesforce\", \"Stripe\")',\n ),\n});\nexport type CreateDataSiloInput = z.infer<typeof CreateDataSiloSchema>;\n\nexport function createInventoryCreateDataSiloTool(clients: ToolClients) {\n const graphql = clients.graphql as InventoryMixin;\n return defineTool({\n name: 'inventory_create_data_silo',\n description:\n 'Create a new data silo (data system or integration). The name must match an integration name from the Transcend catalog.',\n category: 'Data Inventory',\n readOnly: false,\n confirmationHint: 'Creates a new data silo in the inventory',\n annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false },\n zodSchema: CreateDataSiloSchema,\n handler: async ({ title }) => {\n const result = await graphql.createDataSilo({\n name: title,\n });\n return createToolResult(true, {\n dataSilo: result,\n message: `Data silo \"${title}\" created successfully`,\n });\n },\n });\n}\n","import { createToolResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-core';\n\nimport type { InventoryMixin } from '../graphql.js';\n\nexport const GetDataSiloSchema = z.object({\n data_silo_id: z.string().describe('ID of the data silo to retrieve'),\n});\nexport type GetDataSiloInput = z.infer<typeof GetDataSiloSchema>;\n\nexport function createInventoryGetDataSiloTool(clients: ToolClients) {\n const graphql = clients.graphql as InventoryMixin;\n return defineTool({\n name: 'inventory_get_data_silo',\n description:\n 'Get detailed information about a specific data silo including its data points and identifiers',\n category: 'Data Inventory',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: GetDataSiloSchema,\n handler: async ({ data_silo_id }) => {\n const result = await graphql.getDataSilo(data_silo_id);\n return createToolResult(true, result);\n },\n });\n}\n","import { createListResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-core';\n\nimport type { InventoryMixin } from '../graphql.js';\n\nexport const ListCategoriesSchema = z.object({\n limit: z.coerce\n .number()\n .min(1)\n .max(100)\n .optional()\n .default(50)\n .describe('Results per page (1-100, default: 50)'),\n cursor: z\n .string()\n .optional()\n .describe('Pagination cursor from previous response (where supported)'),\n});\nexport type ListCategoriesInput = z.infer<typeof ListCategoriesSchema>;\n\nexport function createInventoryListCategoriesTool(clients: ToolClients) {\n const graphql = clients.graphql as InventoryMixin;\n return defineTool({\n name: 'inventory_list_categories',\n description:\n 'List all data categories (PII types) configured in your organization. Note: API does not support cursor pagination (max ~100 results).',\n category: 'Data Inventory',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: ListCategoriesSchema,\n handler: async ({ limit, cursor }) => {\n const result = await graphql.listDataCategories({\n first: limit,\n after: cursor,\n });\n\n return createListResult(result.nodes, {\n totalCount: result.totalCount,\n hasNextPage: result.pageInfo?.hasNextPage,\n });\n },\n });\n}\n","import { createListResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-core';\n\nimport type { InventoryMixin } from '../graphql.js';\n\nexport const ListDataPointsSchema = z.object({\n limit: z.coerce\n .number()\n .min(1)\n .max(100)\n .optional()\n .default(50)\n .describe('Results per page (1-100, default: 50)'),\n cursor: z\n .string()\n .optional()\n .describe('Pagination cursor from previous response (where supported)'),\n});\nexport type ListDataPointsInput = z.infer<typeof ListDataPointsSchema>;\n\nexport function createInventoryListDataPointsTool(clients: ToolClients) {\n const graphql = clients.graphql as InventoryMixin;\n return defineTool({\n name: 'inventory_list_data_points',\n description:\n 'List data points (collections of personal data). Note: API does not support cursor pagination or data_silo filtering (max ~100 results).',\n category: 'Data Inventory',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: ListDataPointsSchema,\n handler: async ({ limit, cursor }) => {\n const result = await graphql.listDataPoints(\n undefined, // dataSiloId not supported by API\n {\n first: limit,\n after: cursor,\n },\n );\n\n return createListResult(result.nodes, {\n totalCount: result.totalCount,\n hasNextPage: result.pageInfo?.hasNextPage,\n });\n },\n });\n}\n","import { createListResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-core';\n\nimport type { InventoryMixin } from '../graphql.js';\n\nexport const ListDataSilosSchema = z.object({\n limit: z.coerce\n .number()\n .min(1)\n .max(100)\n .optional()\n .default(50)\n .describe('Results per page (1-100, default: 50)'),\n cursor: z\n .string()\n .optional()\n .describe('Pagination cursor from previous response (where supported)'),\n});\nexport type ListDataSilosInput = z.infer<typeof ListDataSilosSchema>;\n\nexport function createInventoryListDataSilosTool(clients: ToolClients) {\n const graphql = clients.graphql as InventoryMixin;\n return defineTool({\n name: 'inventory_list_data_silos',\n description:\n 'List all data silos (data systems and integrations) in your organization. Note: API does not support cursor pagination (max ~100 results).',\n category: 'Data Inventory',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: ListDataSilosSchema,\n handler: async ({ limit, cursor }) => {\n const result = await graphql.listDataSilos({\n first: limit,\n after: cursor,\n });\n\n return createListResult(result.nodes, {\n totalCount: result.totalCount,\n hasNextPage: result.pageInfo?.hasNextPage,\n });\n },\n });\n}\n","import { createListResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-core';\n\nimport type { InventoryMixin } from '../graphql.js';\n\nexport const ListIdentifiersSchema = z.object({\n limit: z.coerce\n .number()\n .min(1)\n .max(100)\n .optional()\n .default(50)\n .describe('Results per page (1-100, default: 50)'),\n cursor: z\n .string()\n .optional()\n .describe('Pagination cursor from previous response (where supported)'),\n});\nexport type ListIdentifiersInput = z.infer<typeof ListIdentifiersSchema>;\n\nexport function createInventoryListIdentifiersTool(clients: ToolClients) {\n const graphql = clients.graphql as InventoryMixin;\n return defineTool({\n name: 'inventory_list_identifiers',\n description:\n 'List all identifier types (email, user ID, etc.) configured in your organization. Note: API does not support cursor pagination (max ~100 results).',\n category: 'Data Inventory',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: ListIdentifiersSchema,\n handler: async ({ limit, cursor }) => {\n const result = await graphql.listIdentifiers({\n first: limit,\n after: cursor,\n });\n\n return createListResult(result.nodes, {\n totalCount: result.totalCount,\n hasNextPage: result.pageInfo?.hasNextPage,\n });\n },\n });\n}\n","import { createListResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-core';\n\nimport type { InventoryMixin } from '../graphql.js';\n\nexport const ListSubDataPointsSchema = z.object({\n data_point_id: z.string().describe('ID of the parent data point'),\n limit: z.coerce\n .number()\n .min(1)\n .max(100)\n .optional()\n .default(50)\n .describe('Results per page (1-100, default: 50)'),\n offset: z.coerce\n .number()\n .min(0)\n .optional()\n .default(0)\n .describe('Number of results to skip (default: 0)'),\n});\nexport type ListSubDataPointsInput = z.infer<typeof ListSubDataPointsSchema>;\n\nexport function createInventoryListSubDataPointsTool(clients: ToolClients) {\n const graphql = clients.graphql as InventoryMixin;\n return defineTool({\n name: 'inventory_list_sub_data_points',\n description:\n 'List sub-data points (individual data fields) for a specific data point. Note: This feature may have limited availability.',\n category: 'Data Inventory',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: ListSubDataPointsSchema,\n handler: async ({ data_point_id, limit, offset }) => {\n const result = await graphql.listSubDataPoints(data_point_id, {\n first: limit,\n offset,\n });\n\n return createListResult(result.nodes, {\n totalCount: result.totalCount,\n hasNextPage: result.pageInfo?.hasNextPage,\n });\n },\n });\n}\n","import { createListResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-core';\n\nimport type { InventoryMixin } from '../graphql.js';\n\nexport const ListVendorsSchema = z.object({\n limit: z.coerce\n .number()\n .min(1)\n .max(100)\n .optional()\n .default(50)\n .describe('Results per page (1-100, default: 50)'),\n cursor: z\n .string()\n .optional()\n .describe('Pagination cursor from previous response (where supported)'),\n});\nexport type ListVendorsInput = z.infer<typeof ListVendorsSchema>;\n\nexport function createInventoryListVendorsTool(clients: ToolClients) {\n const graphql = clients.graphql as InventoryMixin;\n return defineTool({\n name: 'inventory_list_vendors',\n description:\n 'List all vendors (third-party data processors) in your organization. Note: API does not support cursor pagination (max ~100 results).',\n category: 'Data Inventory',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: ListVendorsSchema,\n handler: async ({ limit, cursor }) => {\n const result = await graphql.listVendors({\n first: limit,\n after: cursor,\n });\n\n return createListResult(result.nodes, {\n totalCount: result.totalCount,\n hasNextPage: result.pageInfo?.hasNextPage,\n });\n },\n });\n}\n","import { createToolResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-core';\n\nimport type { InventoryMixin } from '../graphql.js';\n\nexport const UpdateDataSiloSchema = z.object({\n data_silo_id: z.string().describe('ID of the data silo to update'),\n title: z.string().optional().describe('New title for the data silo'),\n description: z.string().optional().describe('New description'),\n});\nexport type UpdateDataSiloInput = z.infer<typeof UpdateDataSiloSchema>;\n\nexport function createInventoryUpdateDataSiloTool(clients: ToolClients) {\n const graphql = clients.graphql as InventoryMixin;\n return defineTool({\n name: 'inventory_update_data_silo',\n description: 'Update an existing data silo',\n category: 'Data Inventory',\n readOnly: false,\n confirmationHint: 'Updates the data silo configuration',\n annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true },\n zodSchema: UpdateDataSiloSchema,\n handler: async ({ data_silo_id, title, description }) => {\n const result = await graphql.updateDataSilo({\n id: data_silo_id,\n title,\n description,\n });\n return createToolResult(true, {\n dataSilo: result,\n message: 'Data silo updated successfully',\n });\n },\n });\n}\n","import type { ToolDefinition, ToolClients } from '@transcend-io/mcp-server-core';\n\nimport { createInventoryAnalyzeTool } from './inventory_analyze.js';\nimport { createInventoryCreateDataSiloTool } from './inventory_create_data_silo.js';\nimport { createInventoryGetDataSiloTool } from './inventory_get_data_silo.js';\nimport { createInventoryListCategoriesTool } from './inventory_list_categories.js';\nimport { createInventoryListDataPointsTool } from './inventory_list_data_points.js';\nimport { createInventoryListDataSilosTool } from './inventory_list_data_silos.js';\nimport { createInventoryListIdentifiersTool } from './inventory_list_identifiers.js';\nimport { createInventoryListSubDataPointsTool } from './inventory_list_sub_data_points.js';\nimport { createInventoryListVendorsTool } from './inventory_list_vendors.js';\nimport { createInventoryUpdateDataSiloTool } from './inventory_update_data_silo.js';\n\nexport function getInventoryTools(clients: ToolClients): ToolDefinition[] {\n return [\n createInventoryListDataSilosTool(clients),\n createInventoryGetDataSiloTool(clients),\n createInventoryCreateDataSiloTool(clients),\n createInventoryUpdateDataSiloTool(clients),\n createInventoryListVendorsTool(clients),\n createInventoryListDataPointsTool(clients),\n createInventoryListSubDataPointsTool(clients),\n createInventoryListIdentifiersTool(clients),\n createInventoryListCategoriesTool(clients),\n createInventoryAnalyzeTool(clients),\n ];\n}\n","import {\n TranscendGraphQLBase,\n type DataCategory,\n type DataPoint,\n type DataSilo,\n type DataSiloCreateInput,\n type DataSiloDetails,\n type DataSiloUpdateInput,\n type Identifier,\n type ListOptions,\n type PaginatedResponse,\n type SubDataPoint,\n type Vendor,\n} from '@transcend-io/mcp-server-core';\n\nexport class InventoryMixin extends TranscendGraphQLBase {\n async listDataSilos(options?: ListOptions): Promise<PaginatedResponse<DataSilo>> {\n const query = `\n query ListDataSilos($first: Int) {\n dataSilos(first: $first) {\n nodes {\n id\n title\n type\n }\n totalCount\n }\n }\n `;\n const data = await this.makeRequest<{ dataSilos: { nodes: DataSilo[]; totalCount: number } }>(\n query,\n { first: Math.min(options?.first || 100, 100) },\n );\n return {\n nodes: data.dataSilos.nodes,\n pageInfo: {\n hasNextPage: data.dataSilos.nodes.length < data.dataSilos.totalCount,\n hasPreviousPage: false,\n },\n totalCount: data.dataSilos.totalCount,\n };\n }\n\n async getDataSilo(id: string): Promise<DataSiloDetails> {\n const query = `\n query GetDataSilo($id: String!) {\n dataSilo(id: $id) {\n id\n title\n type\n description\n link\n isLive\n outerType\n createdAt\n connectionState\n identifiers {\n id\n name\n type\n isRequiredInForm\n }\n }\n }\n `;\n const data = await this.makeRequest<{ dataSilo: DataSiloDetails }>(query, { id });\n return data.dataSilo;\n }\n\n async createDataSilo(input: DataSiloCreateInput): Promise<DataSilo> {\n const mutation = `\n mutation CreateDataSilos($input: [CreateDataSilosInput!]!) {\n createDataSilos(input: $input) {\n dataSilos {\n id\n title\n type\n description\n isLive\n createdAt\n }\n }\n }\n `;\n const data = await this.makeRequest<{ createDataSilos: { dataSilos: DataSilo[] } }>(mutation, {\n input: [input],\n });\n const created = data.createDataSilos.dataSilos[0];\n if (!created) throw new Error('createDataSilos returned an empty array');\n return created;\n }\n\n async updateDataSilo(input: DataSiloUpdateInput): Promise<DataSilo> {\n const mutation = `\n mutation UpdateDataSilos($input: UpdateDataSilosInput!) {\n updateDataSilos(input: $input) {\n dataSilos {\n id\n title\n type\n description\n isLive\n createdAt\n updatedAt\n }\n }\n }\n `;\n const wrappedInput = { dataSilos: [input] };\n const data = await this.makeRequest<{ updateDataSilos: { dataSilos: DataSilo[] } }>(mutation, {\n input: wrappedInput,\n });\n const updated = data.updateDataSilos.dataSilos[0];\n if (!updated) throw new Error('updateDataSilos returned an empty array');\n return updated;\n }\n\n async listVendors(options?: ListOptions): Promise<PaginatedResponse<Vendor>> {\n const query = `\n query ListVendors($first: Int) {\n vendors(first: $first) {\n nodes {\n id\n title\n }\n totalCount\n }\n }\n `;\n const data = await this.makeRequest<{ vendors: { nodes: Vendor[]; totalCount: number } }>(\n query,\n { first: Math.min(options?.first || 100, 100) },\n );\n return {\n nodes: data.vendors.nodes,\n pageInfo: {\n hasNextPage: data.vendors.nodes.length < data.vendors.totalCount,\n hasPreviousPage: false,\n },\n totalCount: data.vendors.totalCount,\n };\n }\n\n async listDataPoints(\n _dataSiloId?: string,\n options?: ListOptions,\n ): Promise<PaginatedResponse<DataPoint>> {\n const query = `\n query ListDataPoints($first: Int) {\n dataPoints(first: $first) {\n nodes {\n id\n name\n title {\n defaultMessage\n }\n description {\n defaultMessage\n }\n }\n totalCount\n }\n }\n `;\n const data = await this.makeRequest<{\n dataPoints: {\n nodes: Array<{\n id: string;\n name: string;\n title: { defaultMessage: string };\n description: { defaultMessage: string } | null;\n }>;\n totalCount: number;\n };\n }>(query, { first: Math.min(options?.first || 100, 100) });\n const points: DataPoint[] = data.dataPoints.nodes.map((dp) => ({\n id: dp.id,\n name: dp.name,\n title: dp.title?.defaultMessage,\n description: dp.description?.defaultMessage,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n }));\n return {\n nodes: points,\n pageInfo: { hasNextPage: points.length < data.dataPoints.totalCount, hasPreviousPage: false },\n totalCount: data.dataPoints.totalCount,\n };\n }\n\n async listSubDataPoints(\n dataPointId: string,\n options?: ListOptions,\n ): Promise<PaginatedResponse<SubDataPoint>> {\n const query = `\n query ListSubDataPoints($first: Int, $offset: Int, $filterBy: SubDataPointFiltersInput) {\n subDataPoints(first: $first, offset: $offset, filterBy: $filterBy) {\n nodes {\n id\n name\n description\n accessRequestVisibilityEnabled\n }\n totalCount\n }\n }\n `;\n const data = await this.makeRequest<{\n subDataPoints: { nodes: SubDataPoint[]; totalCount: number };\n }>(query, {\n first: Math.min(options?.first || 100, 100),\n offset: options?.offset || 0,\n filterBy: { dataPoints: [dataPointId] },\n });\n return {\n nodes: data.subDataPoints.nodes,\n pageInfo: {\n hasNextPage: data.subDataPoints.nodes.length < data.subDataPoints.totalCount,\n hasPreviousPage: false,\n },\n totalCount: data.subDataPoints.totalCount,\n };\n }\n\n async listIdentifiers(options?: ListOptions): Promise<PaginatedResponse<Identifier>> {\n const query = `\n query ListIdentifiers($first: Int) {\n identifiers(first: $first) {\n nodes {\n id\n name\n type\n }\n totalCount\n }\n }\n `;\n const data = await this.makeRequest<{\n identifiers: { nodes: Identifier[]; totalCount: number };\n }>(query, { first: Math.min(options?.first || 100, 100) });\n return {\n nodes: data.identifiers.nodes,\n pageInfo: {\n hasNextPage: data.identifiers.nodes.length < data.identifiers.totalCount,\n hasPreviousPage: false,\n },\n totalCount: data.identifiers.totalCount,\n };\n }\n\n async listDataCategories(options?: ListOptions): Promise<PaginatedResponse<DataCategory>> {\n const query = `\n query ListDataCategories($first: Int) {\n dataCategories(first: $first) {\n nodes {\n name\n category\n }\n totalCount\n }\n }\n `;\n const data = await this.makeRequest<{\n dataCategories: { nodes: DataCategory[]; totalCount: number };\n }>(query, { first: Math.min(options?.first || 100, 100) });\n return {\n nodes: data.dataCategories.nodes,\n pageInfo: {\n hasNextPage: data.dataCategories.nodes.length < data.dataCategories.totalCount,\n hasPreviousPage: false,\n },\n totalCount: data.dataCategories.totalCount,\n };\n }\n}\n"],"mappings":"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"}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { DataCategory, DataPoint, DataSilo, DataSiloCreateInput, DataSiloDetails, DataSiloUpdateInput, Identifier, ListOptions, PaginatedResponse, SubDataPoint, ToolClients, ToolDefinition, TranscendGraphQLBase, Vendor, z } from "@transcend-io/mcp-server-core";
|
|
2
|
+
|
|
3
|
+
//#region src/tools/index.d.ts
|
|
4
|
+
declare function getInventoryTools(clients: ToolClients): ToolDefinition[];
|
|
5
|
+
//#endregion
|
|
6
|
+
//#region src/graphql.d.ts
|
|
7
|
+
declare class InventoryMixin extends TranscendGraphQLBase {
|
|
8
|
+
listDataSilos(options?: ListOptions): Promise<PaginatedResponse<DataSilo>>;
|
|
9
|
+
getDataSilo(id: string): Promise<DataSiloDetails>;
|
|
10
|
+
createDataSilo(input: DataSiloCreateInput): Promise<DataSilo>;
|
|
11
|
+
updateDataSilo(input: DataSiloUpdateInput): Promise<DataSilo>;
|
|
12
|
+
listVendors(options?: ListOptions): Promise<PaginatedResponse<Vendor>>;
|
|
13
|
+
listDataPoints(_dataSiloId?: string, options?: ListOptions): Promise<PaginatedResponse<DataPoint>>;
|
|
14
|
+
listSubDataPoints(dataPointId: string, options?: ListOptions): Promise<PaginatedResponse<SubDataPoint>>;
|
|
15
|
+
listIdentifiers(options?: ListOptions): Promise<PaginatedResponse<Identifier>>;
|
|
16
|
+
listDataCategories(options?: ListOptions): Promise<PaginatedResponse<DataCategory>>;
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/tools/inventory_create_data_silo.d.ts
|
|
20
|
+
declare const CreateDataSiloSchema: z.ZodObject<{
|
|
21
|
+
title: z.ZodString;
|
|
22
|
+
}, z.core.$strip>;
|
|
23
|
+
type CreateDataSiloInput = z.infer<typeof CreateDataSiloSchema>;
|
|
24
|
+
//#endregion
|
|
25
|
+
//#region src/tools/inventory_get_data_silo.d.ts
|
|
26
|
+
declare const GetDataSiloSchema: z.ZodObject<{
|
|
27
|
+
data_silo_id: z.ZodString;
|
|
28
|
+
}, z.core.$strip>;
|
|
29
|
+
type GetDataSiloInput = z.infer<typeof GetDataSiloSchema>;
|
|
30
|
+
//#endregion
|
|
31
|
+
//#region src/tools/inventory_list_categories.d.ts
|
|
32
|
+
declare const ListCategoriesSchema: z.ZodObject<{
|
|
33
|
+
limit: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
34
|
+
cursor: z.ZodOptional<z.ZodString>;
|
|
35
|
+
}, z.core.$strip>;
|
|
36
|
+
type ListCategoriesInput = z.infer<typeof ListCategoriesSchema>;
|
|
37
|
+
//#endregion
|
|
38
|
+
//#region src/tools/inventory_list_data_points.d.ts
|
|
39
|
+
declare const ListDataPointsSchema: z.ZodObject<{
|
|
40
|
+
limit: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
41
|
+
cursor: z.ZodOptional<z.ZodString>;
|
|
42
|
+
}, z.core.$strip>;
|
|
43
|
+
type ListDataPointsInput = z.infer<typeof ListDataPointsSchema>;
|
|
44
|
+
//#endregion
|
|
45
|
+
//#region src/tools/inventory_list_data_silos.d.ts
|
|
46
|
+
declare const ListDataSilosSchema: z.ZodObject<{
|
|
47
|
+
limit: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
48
|
+
cursor: z.ZodOptional<z.ZodString>;
|
|
49
|
+
}, z.core.$strip>;
|
|
50
|
+
type ListDataSilosInput = z.infer<typeof ListDataSilosSchema>;
|
|
51
|
+
//#endregion
|
|
52
|
+
//#region src/tools/inventory_list_identifiers.d.ts
|
|
53
|
+
declare const ListIdentifiersSchema: z.ZodObject<{
|
|
54
|
+
limit: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
55
|
+
cursor: z.ZodOptional<z.ZodString>;
|
|
56
|
+
}, z.core.$strip>;
|
|
57
|
+
type ListIdentifiersInput = z.infer<typeof ListIdentifiersSchema>;
|
|
58
|
+
//#endregion
|
|
59
|
+
//#region src/tools/inventory_list_sub_data_points.d.ts
|
|
60
|
+
declare const ListSubDataPointsSchema: z.ZodObject<{
|
|
61
|
+
data_point_id: z.ZodString;
|
|
62
|
+
limit: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
63
|
+
offset: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
64
|
+
}, z.core.$strip>;
|
|
65
|
+
type ListSubDataPointsInput = z.infer<typeof ListSubDataPointsSchema>;
|
|
66
|
+
//#endregion
|
|
67
|
+
//#region src/tools/inventory_list_vendors.d.ts
|
|
68
|
+
declare const ListVendorsSchema: z.ZodObject<{
|
|
69
|
+
limit: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
70
|
+
cursor: z.ZodOptional<z.ZodString>;
|
|
71
|
+
}, z.core.$strip>;
|
|
72
|
+
type ListVendorsInput = z.infer<typeof ListVendorsSchema>;
|
|
73
|
+
//#endregion
|
|
74
|
+
//#region src/tools/inventory_update_data_silo.d.ts
|
|
75
|
+
declare const UpdateDataSiloSchema: z.ZodObject<{
|
|
76
|
+
data_silo_id: z.ZodString;
|
|
77
|
+
title: z.ZodOptional<z.ZodString>;
|
|
78
|
+
description: z.ZodOptional<z.ZodString>;
|
|
79
|
+
}, z.core.$strip>;
|
|
80
|
+
type UpdateDataSiloInput = z.infer<typeof UpdateDataSiloSchema>;
|
|
81
|
+
//#endregion
|
|
82
|
+
export { type CreateDataSiloInput, CreateDataSiloSchema, type GetDataSiloInput, GetDataSiloSchema, InventoryMixin, type ListCategoriesInput, ListCategoriesSchema, type ListDataPointsInput, ListDataPointsSchema, type ListDataSilosInput, ListDataSilosSchema, type ListIdentifiersInput, ListIdentifiersSchema, type ListSubDataPointsInput, ListSubDataPointsSchema, type ListVendorsInput, ListVendorsSchema, type UpdateDataSiloInput, UpdateDataSiloSchema, getInventoryTools };
|
|
83
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/tools/index.ts","../src/graphql.ts","../src/tools/inventory_create_data_silo.ts","../src/tools/inventory_get_data_silo.ts","../src/tools/inventory_list_categories.ts","../src/tools/inventory_list_data_points.ts","../src/tools/inventory_list_data_silos.ts","../src/tools/inventory_list_identifiers.ts","../src/tools/inventory_list_sub_data_points.ts","../src/tools/inventory_list_vendors.ts","../src/tools/inventory_update_data_silo.ts"],"mappings":";;;iBAagB,iBAAA,CAAkB,OAAA,EAAS,WAAA,GAAc,cAAA;;;cCE5C,cAAA,SAAuB,oBAAA;EAC5B,aAAA,CAAc,OAAA,GAAU,WAAA,GAAc,OAAA,CAAQ,iBAAA,CAAkB,QAAA;EA2BhE,WAAA,CAAY,EAAA,WAAa,OAAA,CAAQ,eAAA;EA0BjC,cAAA,CAAe,KAAA,EAAO,mBAAA,GAAsB,OAAA,CAAQ,QAAA;EAuBpD,cAAA,CAAe,KAAA,EAAO,mBAAA,GAAsB,OAAA,CAAQ,QAAA;EAyBpD,WAAA,CAAY,OAAA,GAAU,WAAA,GAAc,OAAA,CAAQ,iBAAA,CAAkB,MAAA;EA0B9D,cAAA,CACJ,WAAA,WACA,OAAA,GAAU,WAAA,GACT,OAAA,CAAQ,iBAAA,CAAkB,SAAA;EA4CvB,iBAAA,CACJ,WAAA,UACA,OAAA,GAAU,WAAA,GACT,OAAA,CAAQ,iBAAA,CAAkB,YAAA;EA+BvB,eAAA,CAAgB,OAAA,GAAU,WAAA,GAAc,OAAA,CAAQ,iBAAA,CAAkB,UAAA;EA0BlE,kBAAA,CAAmB,OAAA,GAAU,WAAA,GAAc,OAAA,CAAQ,iBAAA,CAAkB,YAAA;AAAA;;;cCtPhE,oBAAA,EAAoB,CAAA,CAAA,SAAA;;;KAOrB,mBAAA,GAAsB,CAAA,CAAE,KAAA,QAAa,oBAAA;;;cCPpC,iBAAA,EAAiB,CAAA,CAAA,SAAA;;;KAGlB,gBAAA,GAAmB,CAAA,CAAE,KAAA,QAAa,iBAAA;;;cCHjC,oBAAA,EAAoB,CAAA,CAAA,SAAA;;;;KAarB,mBAAA,GAAsB,CAAA,CAAE,KAAA,QAAa,oBAAA;;;cCbpC,oBAAA,EAAoB,CAAA,CAAA,SAAA;;;;KAarB,mBAAA,GAAsB,CAAA,CAAE,KAAA,QAAa,oBAAA;;;cCbpC,mBAAA,EAAmB,CAAA,CAAA,SAAA;;;;KAapB,kBAAA,GAAqB,CAAA,CAAE,KAAA,QAAa,mBAAA;;;cCbnC,qBAAA,EAAqB,CAAA,CAAA,SAAA;;;;KAatB,oBAAA,GAAuB,CAAA,CAAE,KAAA,QAAa,qBAAA;;;cCbrC,uBAAA,EAAuB,CAAA,CAAA,SAAA;;;;;KAgBxB,sBAAA,GAAyB,CAAA,CAAE,KAAA,QAAa,uBAAA;;;cChBvC,iBAAA,EAAiB,CAAA,CAAA,SAAA;;;;KAalB,gBAAA,GAAmB,CAAA,CAAE,KAAA,QAAa,iBAAA;;;cCbjC,oBAAA,EAAoB,CAAA,CAAA,SAAA;;;;;KAKrB,mBAAA,GAAsB,CAAA,CAAE,KAAA,QAAa,oBAAA"}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as ListSubDataPointsSchema, c as ListDataPointsSchema, d as CreateDataSiloSchema, i as ListVendorsSchema, l as ListCategoriesSchema, n as getInventoryTools, o as ListIdentifiersSchema, r as UpdateDataSiloSchema, s as ListDataSilosSchema, t as InventoryMixin, u as GetDataSiloSchema } from "./graphql-hWIhKdeR.mjs";
|
|
2
|
+
export { CreateDataSiloSchema, GetDataSiloSchema, InventoryMixin, ListCategoriesSchema, ListDataPointsSchema, ListDataSilosSchema, ListIdentifiersSchema, ListSubDataPointsSchema, ListVendorsSchema, UpdateDataSiloSchema, getInventoryTools };
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@transcend-io/mcp-server-inventory",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Transcend MCP Server — Data Inventory tools.",
|
|
5
|
+
"homepage": "https://github.com/transcend-io/tools/tree/main/packages/mcp/mcp-server-inventory",
|
|
6
|
+
"license": "Apache-2.0",
|
|
7
|
+
"author": "Transcend Inc.",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/transcend-io/tools.git",
|
|
11
|
+
"directory": "packages/mcp/mcp-server-inventory"
|
|
12
|
+
},
|
|
13
|
+
"bin": {
|
|
14
|
+
"transcend-mcp-inventory": "./dist/cli.mjs"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"type": "module",
|
|
20
|
+
"sideEffects": false,
|
|
21
|
+
"types": "./dist/index.d.mts",
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"@transcend-io/source": "./src/index.ts",
|
|
25
|
+
"types": "./dist/index.d.mts",
|
|
26
|
+
"default": "./dist/index.mjs"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"publishConfig": {
|
|
30
|
+
"access": "public"
|
|
31
|
+
},
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "tsdown",
|
|
34
|
+
"test": "vitest run",
|
|
35
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
36
|
+
"check:exports": "attw --pack . --ignore-rules cjs-resolves-to-esm",
|
|
37
|
+
"check:publint": "publint --level warning --strict --pack pnpm"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"@modelcontextprotocol/sdk": "catalog:",
|
|
41
|
+
"@transcend-io/mcp-server-core": "workspace:*",
|
|
42
|
+
"zod": "catalog:"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@arethetypeswrong/cli": "catalog:",
|
|
46
|
+
"@types/node": "catalog:",
|
|
47
|
+
"publint": "catalog:",
|
|
48
|
+
"tsdown": "catalog:",
|
|
49
|
+
"typescript": "catalog:",
|
|
50
|
+
"vitest": "catalog:"
|
|
51
|
+
},
|
|
52
|
+
"engines": {
|
|
53
|
+
"node": ">=22.12.0"
|
|
54
|
+
}
|
|
55
|
+
}
|