@transcend-io/mcp-server-admin 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 +90 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +17 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/graphql-DBU41KQd.mjs +399 -0
- package/dist/graphql-DBU41KQd.mjs.map +1 -0
- package/dist/index.d.mts +58 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +2 -0
- package/package.json +56 -0
package/README.md
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# @transcend-io/mcp-server-admin
|
|
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 organization administration. Provides tools for managing users, teams, API keys, and organization settings.
|
|
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-admin
|
|
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-admin
|
|
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-admin` binary (see `bin` in `package.json`).
|
|
33
|
+
|
|
34
|
+
```json
|
|
35
|
+
{
|
|
36
|
+
"mcpServers": {
|
|
37
|
+
"transcend-admin": {
|
|
38
|
+
"command": "npx",
|
|
39
|
+
"args": ["-y", "@transcend-io/mcp-server-admin"],
|
|
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-admin` `bin` (use `node` because `pnpm exec transcend-mcp-admin` 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-admin..."
|
|
59
|
+
set -a && source ./secret.env && set +a
|
|
60
|
+
pnpm -F @transcend-io/mcp-server-admin exec node ./dist/cli.mjs
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**Alternative:** `./scripts/mcp-run.sh ./packages/mcp/mcp-server-admin/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
|
+
- `admin_test_connection` — Test API connectivity
|
|
80
|
+
- `admin_get_current_user` — Get the authenticated user
|
|
81
|
+
- `admin_get_organization` — Get organization details
|
|
82
|
+
- `admin_get_privacy_center` — Get privacy center configuration
|
|
83
|
+
- `admin_list_users` — List organization users
|
|
84
|
+
- `admin_list_teams` — List teams
|
|
85
|
+
- `admin_list_api_keys` — List API keys
|
|
86
|
+
- `admin_create_api_key` — Create a new API key
|
|
87
|
+
|
|
88
|
+
## Related packages
|
|
89
|
+
|
|
90
|
+
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 getAdminTools, t as AdminMixin } from "./graphql-DBU41KQd.mjs";
|
|
3
|
+
import { TranscendRestClient, createMCPServer } from "@transcend-io/mcp-server-core";
|
|
4
|
+
//#region src/cli.ts
|
|
5
|
+
createMCPServer({
|
|
6
|
+
name: "transcend-mcp-admin",
|
|
7
|
+
version: "1.0.0",
|
|
8
|
+
getTools: getAdminTools,
|
|
9
|
+
createClients: (auth, sombraUrl, graphqlUrl) => ({
|
|
10
|
+
rest: new TranscendRestClient(auth, sombraUrl),
|
|
11
|
+
graphql: new AdminMixin(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 { AdminMixin } from './graphql.js';\nimport { getAdminTools } from './tools/index.js';\n\ncreateMCPServer({\n name: 'transcend-mcp-admin',\n version: '1.0.0',\n getTools: getAdminTools,\n createClients: (auth, sombraUrl, graphqlUrl) => ({\n rest: new TranscendRestClient(auth, sombraUrl),\n graphql: new AdminMixin(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,WAAW,MAAM,WAAW;EAC1C;CACF,CAAC"}
|
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
import { EmptySchema, TranscendGraphQLBase, createListResult, createToolResult, defineTool, z } from "@transcend-io/mcp-server-core";
|
|
2
|
+
import { ScopeName, TRANSCEND_SCOPES } from "@transcend-io/privacy-types";
|
|
3
|
+
//#region src/tools/admin_create_api_key.ts
|
|
4
|
+
const scopeSummary = Object.entries(TRANSCEND_SCOPES).map(([name, def]) => {
|
|
5
|
+
const deps = def.dependencies.length > 0 ? ` (requires: ${def.dependencies.join(", ")})` : "";
|
|
6
|
+
return `- ${name}: ${def.title} — ${def.description}${deps}`;
|
|
7
|
+
}).join("\n");
|
|
8
|
+
const CreateApiKeySchema = z.object({
|
|
9
|
+
title: z.string().describe("Name/title for the API key"),
|
|
10
|
+
scopes: z.array(z.nativeEnum(ScopeName)).describe("Array of permission scopes for the key"),
|
|
11
|
+
data_silos: z.array(z.string()).optional().describe("Array of data silo IDs to assign the key to (optional)")
|
|
12
|
+
});
|
|
13
|
+
function createAdminCreateApiKeyTool(clients) {
|
|
14
|
+
const graphql = clients.graphql;
|
|
15
|
+
return defineTool({
|
|
16
|
+
name: "admin_create_api_key",
|
|
17
|
+
description: "Create a new API key with specified scopes. WARNING: The token is only shown once! Scopes control what the key can access. Some scopes inherit dependencies — for example, manageDataMap requires viewDataMap. Use \"readOnly\" for view-only access to all resources, or \"fullAdmin\" for unrestricted access. Common scopes: manageApiKeys, manageDataMap, manageConsentManager, makeDataSubjectRequest, connectDataSilos, manageAssessments, manageDataInventory.\n\nAvailable scopes:\n" + scopeSummary,
|
|
18
|
+
category: "Admin",
|
|
19
|
+
readOnly: false,
|
|
20
|
+
confirmationHint: "Creates a new API key with the specified scopes",
|
|
21
|
+
annotations: {
|
|
22
|
+
readOnlyHint: false,
|
|
23
|
+
destructiveHint: true,
|
|
24
|
+
idempotentHint: false
|
|
25
|
+
},
|
|
26
|
+
zodSchema: CreateApiKeySchema,
|
|
27
|
+
handler: async ({ title, scopes, data_silos }) => {
|
|
28
|
+
const result = await graphql.createApiKey({
|
|
29
|
+
title,
|
|
30
|
+
scopes,
|
|
31
|
+
dataSilos: data_silos
|
|
32
|
+
});
|
|
33
|
+
return createToolResult(true, {
|
|
34
|
+
apiKey: result.apiKey,
|
|
35
|
+
token: result.token,
|
|
36
|
+
warning: "IMPORTANT: Save this token now! It will not be shown again.",
|
|
37
|
+
message: `API key "${title}" created successfully`
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
//#endregion
|
|
43
|
+
//#region src/tools/admin_get_current_user.ts
|
|
44
|
+
function createAdminGetCurrentUserTool(clients) {
|
|
45
|
+
const graphql = clients.graphql;
|
|
46
|
+
return defineTool({
|
|
47
|
+
name: "admin_get_current_user",
|
|
48
|
+
description: "Get information about the currently authenticated user (the API key owner)",
|
|
49
|
+
category: "Admin",
|
|
50
|
+
readOnly: true,
|
|
51
|
+
annotations: {
|
|
52
|
+
readOnlyHint: true,
|
|
53
|
+
destructiveHint: false,
|
|
54
|
+
idempotentHint: true
|
|
55
|
+
},
|
|
56
|
+
zodSchema: EmptySchema,
|
|
57
|
+
handler: async (_args) => {
|
|
58
|
+
return createToolResult(true, await graphql.getCurrentUser());
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
//#endregion
|
|
63
|
+
//#region src/tools/admin_get_organization.ts
|
|
64
|
+
function createAdminGetOrganizationTool(clients) {
|
|
65
|
+
const graphql = clients.graphql;
|
|
66
|
+
return defineTool({
|
|
67
|
+
name: "admin_get_organization",
|
|
68
|
+
description: "Get information about your Transcend organization",
|
|
69
|
+
category: "Admin",
|
|
70
|
+
readOnly: true,
|
|
71
|
+
annotations: {
|
|
72
|
+
readOnlyHint: true,
|
|
73
|
+
destructiveHint: false,
|
|
74
|
+
idempotentHint: true
|
|
75
|
+
},
|
|
76
|
+
zodSchema: EmptySchema,
|
|
77
|
+
handler: async (_args) => {
|
|
78
|
+
return createToolResult(true, await graphql.getOrganization());
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
//#endregion
|
|
83
|
+
//#region src/tools/admin_get_privacy_center.ts
|
|
84
|
+
function createAdminGetPrivacyCenterTool(clients) {
|
|
85
|
+
const graphql = clients.graphql;
|
|
86
|
+
return defineTool({
|
|
87
|
+
name: "admin_get_privacy_center",
|
|
88
|
+
description: "Get privacy center configuration for your organization",
|
|
89
|
+
category: "Admin",
|
|
90
|
+
readOnly: true,
|
|
91
|
+
annotations: {
|
|
92
|
+
readOnlyHint: true,
|
|
93
|
+
destructiveHint: false,
|
|
94
|
+
idempotentHint: true
|
|
95
|
+
},
|
|
96
|
+
zodSchema: EmptySchema,
|
|
97
|
+
handler: async (_args) => {
|
|
98
|
+
const result = await graphql.getPrivacyCenter();
|
|
99
|
+
if (!result) return createToolResult(true, {
|
|
100
|
+
found: false,
|
|
101
|
+
message: "No privacy center configured for this organization"
|
|
102
|
+
});
|
|
103
|
+
return createToolResult(true, {
|
|
104
|
+
found: true,
|
|
105
|
+
privacyCenter: result
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
//#endregion
|
|
111
|
+
//#region src/tools/admin_list_api_keys.ts
|
|
112
|
+
const ListApiKeysSchema = z.object({
|
|
113
|
+
limit: z.coerce.number().min(1).max(100).optional().default(50).describe("Results per page (1-100, default: 50)"),
|
|
114
|
+
cursor: z.string().optional().describe("Pagination cursor from previous response (where supported)"),
|
|
115
|
+
offset: z.coerce.number().min(0).optional().default(0).describe("Number of results to skip (default: 0)")
|
|
116
|
+
});
|
|
117
|
+
function createAdminListApiKeysTool(clients) {
|
|
118
|
+
const graphql = clients.graphql;
|
|
119
|
+
return defineTool({
|
|
120
|
+
name: "admin_list_api_keys",
|
|
121
|
+
description: "List all API keys configured for your organization (tokens are not shown). Note: API does not support cursor pagination (max ~100 results).",
|
|
122
|
+
category: "Admin",
|
|
123
|
+
readOnly: true,
|
|
124
|
+
annotations: {
|
|
125
|
+
readOnlyHint: true,
|
|
126
|
+
destructiveHint: false,
|
|
127
|
+
idempotentHint: true
|
|
128
|
+
},
|
|
129
|
+
zodSchema: ListApiKeysSchema,
|
|
130
|
+
handler: async ({ limit, offset }) => {
|
|
131
|
+
const result = await graphql.listApiKeys({
|
|
132
|
+
first: limit,
|
|
133
|
+
offset
|
|
134
|
+
});
|
|
135
|
+
return createListResult(result.nodes, {
|
|
136
|
+
totalCount: result.totalCount,
|
|
137
|
+
hasNextPage: result.pageInfo?.hasNextPage
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
//#endregion
|
|
143
|
+
//#region src/tools/admin_list_teams.ts
|
|
144
|
+
const ListTeamsSchema = z.object({
|
|
145
|
+
limit: z.coerce.number().min(1).max(100).optional().default(50).describe("Results per page (1-100, default: 50)"),
|
|
146
|
+
cursor: z.string().optional().describe("Pagination cursor from previous response (where supported)")
|
|
147
|
+
});
|
|
148
|
+
function createAdminListTeamsTool(clients) {
|
|
149
|
+
const graphql = clients.graphql;
|
|
150
|
+
return defineTool({
|
|
151
|
+
name: "admin_list_teams",
|
|
152
|
+
description: "List all teams in your Transcend organization. Note: API does not support cursor pagination (max ~100 results).",
|
|
153
|
+
category: "Admin",
|
|
154
|
+
readOnly: true,
|
|
155
|
+
annotations: {
|
|
156
|
+
readOnlyHint: true,
|
|
157
|
+
destructiveHint: false,
|
|
158
|
+
idempotentHint: true
|
|
159
|
+
},
|
|
160
|
+
zodSchema: ListTeamsSchema,
|
|
161
|
+
handler: async ({ limit, cursor }) => {
|
|
162
|
+
const result = await graphql.listTeams({
|
|
163
|
+
first: limit,
|
|
164
|
+
after: cursor
|
|
165
|
+
});
|
|
166
|
+
return createListResult(result.nodes, {
|
|
167
|
+
totalCount: result.totalCount,
|
|
168
|
+
hasNextPage: result.pageInfo?.hasNextPage
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
//#endregion
|
|
174
|
+
//#region src/tools/admin_list_users.ts
|
|
175
|
+
const ListUsersSchema = z.object({
|
|
176
|
+
limit: z.coerce.number().min(1).max(100).optional().default(50).describe("Results per page (1-100, default: 50)"),
|
|
177
|
+
cursor: z.string().optional().describe("Pagination cursor from previous response (where supported)")
|
|
178
|
+
});
|
|
179
|
+
function createAdminListUsersTool(clients) {
|
|
180
|
+
const graphql = clients.graphql;
|
|
181
|
+
return defineTool({
|
|
182
|
+
name: "admin_list_users",
|
|
183
|
+
description: "List all users in your Transcend organization. Note: API does not support cursor pagination (max ~100 results).",
|
|
184
|
+
category: "Admin",
|
|
185
|
+
readOnly: true,
|
|
186
|
+
annotations: {
|
|
187
|
+
readOnlyHint: true,
|
|
188
|
+
destructiveHint: false,
|
|
189
|
+
idempotentHint: true
|
|
190
|
+
},
|
|
191
|
+
zodSchema: ListUsersSchema,
|
|
192
|
+
handler: async ({ limit, cursor }) => {
|
|
193
|
+
const result = await graphql.listUsers({
|
|
194
|
+
first: limit,
|
|
195
|
+
after: cursor
|
|
196
|
+
});
|
|
197
|
+
return createListResult(result.nodes, {
|
|
198
|
+
totalCount: result.totalCount,
|
|
199
|
+
hasNextPage: result.pageInfo?.hasNextPage
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
//#endregion
|
|
205
|
+
//#region src/tools/admin_test_connection.ts
|
|
206
|
+
function createAdminTestConnectionTool(clients) {
|
|
207
|
+
const { rest } = clients;
|
|
208
|
+
const graphql = clients.graphql;
|
|
209
|
+
return defineTool({
|
|
210
|
+
name: "admin_test_connection",
|
|
211
|
+
description: "Test connectivity to both Transcend REST and GraphQL APIs",
|
|
212
|
+
category: "Admin",
|
|
213
|
+
readOnly: true,
|
|
214
|
+
annotations: {
|
|
215
|
+
readOnlyHint: true,
|
|
216
|
+
destructiveHint: false,
|
|
217
|
+
idempotentHint: true
|
|
218
|
+
},
|
|
219
|
+
zodSchema: EmptySchema,
|
|
220
|
+
handler: async (_args) => {
|
|
221
|
+
const [graphqlConnected, restConnected] = await Promise.all([graphql.testConnection(), rest.testConnection()]);
|
|
222
|
+
const allConnected = graphqlConnected && restConnected;
|
|
223
|
+
return createToolResult(true, {
|
|
224
|
+
connected: allConnected,
|
|
225
|
+
details: {
|
|
226
|
+
graphql: {
|
|
227
|
+
connected: graphqlConnected,
|
|
228
|
+
url: graphql.getBaseUrl()
|
|
229
|
+
},
|
|
230
|
+
rest: {
|
|
231
|
+
connected: restConnected,
|
|
232
|
+
url: rest.getBaseUrl()
|
|
233
|
+
}
|
|
234
|
+
},
|
|
235
|
+
message: allConnected ? "Successfully connected to all Transcend APIs" : "Some API connections failed - check details",
|
|
236
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
//#endregion
|
|
242
|
+
//#region src/tools/index.ts
|
|
243
|
+
function getAdminTools(clients) {
|
|
244
|
+
return [
|
|
245
|
+
createAdminGetOrganizationTool(clients),
|
|
246
|
+
createAdminGetCurrentUserTool(clients),
|
|
247
|
+
createAdminListUsersTool(clients),
|
|
248
|
+
createAdminListTeamsTool(clients),
|
|
249
|
+
createAdminListApiKeysTool(clients),
|
|
250
|
+
createAdminCreateApiKeyTool(clients),
|
|
251
|
+
createAdminGetPrivacyCenterTool(clients),
|
|
252
|
+
createAdminTestConnectionTool(clients)
|
|
253
|
+
];
|
|
254
|
+
}
|
|
255
|
+
//#endregion
|
|
256
|
+
//#region src/graphql.ts
|
|
257
|
+
var AdminMixin = class extends TranscendGraphQLBase {
|
|
258
|
+
async getOrganization() {
|
|
259
|
+
return (await this.makeRequest(`
|
|
260
|
+
query {
|
|
261
|
+
organization {
|
|
262
|
+
id
|
|
263
|
+
name
|
|
264
|
+
createdAt
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
`)).organization;
|
|
268
|
+
}
|
|
269
|
+
async getCurrentUser() {
|
|
270
|
+
return (await this.makeRequest(`
|
|
271
|
+
query {
|
|
272
|
+
user {
|
|
273
|
+
id
|
|
274
|
+
email
|
|
275
|
+
name
|
|
276
|
+
createdAt
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
`)).user;
|
|
280
|
+
}
|
|
281
|
+
async listUsers(options) {
|
|
282
|
+
const data = await this.makeRequest(`
|
|
283
|
+
query ListUsers($first: Int, $filterBy: UserFiltersInput) {
|
|
284
|
+
users(first: $first, filterBy: $filterBy) {
|
|
285
|
+
nodes {
|
|
286
|
+
id
|
|
287
|
+
email
|
|
288
|
+
name
|
|
289
|
+
}
|
|
290
|
+
totalCount
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
`, {
|
|
294
|
+
first: Math.min(options?.first || 50, 100),
|
|
295
|
+
...options?.filterBy ? { filterBy: options.filterBy } : {}
|
|
296
|
+
});
|
|
297
|
+
return {
|
|
298
|
+
nodes: data.users.nodes,
|
|
299
|
+
pageInfo: {
|
|
300
|
+
hasNextPage: data.users.nodes.length < data.users.totalCount,
|
|
301
|
+
hasPreviousPage: false
|
|
302
|
+
},
|
|
303
|
+
totalCount: data.users.totalCount
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
async listTeams(options) {
|
|
307
|
+
const data = await this.makeRequest(`
|
|
308
|
+
query ListTeams($first: Int) {
|
|
309
|
+
teams(first: $first) {
|
|
310
|
+
nodes {
|
|
311
|
+
id
|
|
312
|
+
name
|
|
313
|
+
}
|
|
314
|
+
totalCount
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
`, { first: Math.min(options?.first || 50, 100) });
|
|
318
|
+
return {
|
|
319
|
+
nodes: data.teams.nodes,
|
|
320
|
+
pageInfo: {
|
|
321
|
+
hasNextPage: data.teams.nodes.length < data.teams.totalCount,
|
|
322
|
+
hasPreviousPage: false
|
|
323
|
+
},
|
|
324
|
+
totalCount: data.teams.totalCount
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
async listApiKeys(options) {
|
|
328
|
+
const data = await this.makeRequest(`
|
|
329
|
+
query ListApiKeys($first: Int, $offset: Int) {
|
|
330
|
+
apiKeys(first: $first, offset: $offset) {
|
|
331
|
+
nodes {
|
|
332
|
+
id
|
|
333
|
+
title
|
|
334
|
+
scopes {
|
|
335
|
+
id
|
|
336
|
+
name
|
|
337
|
+
}
|
|
338
|
+
lastUsedAt
|
|
339
|
+
createdAt
|
|
340
|
+
}
|
|
341
|
+
totalCount
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
`, {
|
|
345
|
+
first: Math.min(options?.first || 50, 100),
|
|
346
|
+
offset: options?.offset || 0
|
|
347
|
+
});
|
|
348
|
+
return {
|
|
349
|
+
nodes: data.apiKeys.nodes,
|
|
350
|
+
pageInfo: {
|
|
351
|
+
hasNextPage: data.apiKeys.nodes.length < data.apiKeys.totalCount,
|
|
352
|
+
hasPreviousPage: false
|
|
353
|
+
},
|
|
354
|
+
totalCount: data.apiKeys.totalCount
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
async createApiKey(input) {
|
|
358
|
+
return (await this.makeRequest(`
|
|
359
|
+
mutation CreateApiKey($input: ApiKeyInput!) {
|
|
360
|
+
createApiKey(input: $input) {
|
|
361
|
+
apiKey {
|
|
362
|
+
id
|
|
363
|
+
title
|
|
364
|
+
scopes
|
|
365
|
+
createdAt
|
|
366
|
+
}
|
|
367
|
+
token
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
`, { input })).createApiKey;
|
|
371
|
+
}
|
|
372
|
+
async getPrivacyCenter(lookup) {
|
|
373
|
+
const query = `
|
|
374
|
+
query GetPrivacyCenter($lookup: PrivacyCenterLookupInput) {
|
|
375
|
+
privacyCenter(lookup: $lookup) {
|
|
376
|
+
id
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
`;
|
|
380
|
+
try {
|
|
381
|
+
const data = await this.makeRequest(query, { lookup: lookup || void 0 });
|
|
382
|
+
if (data.privacyCenter) return {
|
|
383
|
+
id: data.privacyCenter.id,
|
|
384
|
+
name: "Privacy Center",
|
|
385
|
+
url: lookup?.url || "",
|
|
386
|
+
isActive: true,
|
|
387
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
388
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
389
|
+
};
|
|
390
|
+
return null;
|
|
391
|
+
} catch {
|
|
392
|
+
return null;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
};
|
|
396
|
+
//#endregion
|
|
397
|
+
export { ListApiKeysSchema as a, ListTeamsSchema as i, getAdminTools as n, CreateApiKeySchema as o, ListUsersSchema as r, AdminMixin as t };
|
|
398
|
+
|
|
399
|
+
//# sourceMappingURL=graphql-DBU41KQd.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graphql-DBU41KQd.mjs","names":[],"sources":["../src/tools/admin_create_api_key.ts","../src/tools/admin_get_current_user.ts","../src/tools/admin_get_organization.ts","../src/tools/admin_get_privacy_center.ts","../src/tools/admin_list_api_keys.ts","../src/tools/admin_list_teams.ts","../src/tools/admin_list_users.ts","../src/tools/admin_test_connection.ts","../src/tools/index.ts","../src/graphql.ts"],"sourcesContent":["import { createToolResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-core';\nimport { ScopeName, TRANSCEND_SCOPES } from '@transcend-io/privacy-types';\n\nimport type { AdminMixin } from '../graphql.js';\n\nconst scopeSummary = Object.entries(TRANSCEND_SCOPES)\n .map(([name, def]) => {\n const deps = def.dependencies.length > 0 ? ` (requires: ${def.dependencies.join(', ')})` : '';\n return `- ${name}: ${def.title} — ${def.description}${deps}`;\n })\n .join('\\n');\n\nexport const CreateApiKeySchema = z.object({\n title: z.string().describe('Name/title for the API key'),\n scopes: z.array(z.nativeEnum(ScopeName)).describe('Array of permission scopes for the key'),\n data_silos: z\n .array(z.string())\n .optional()\n .describe('Array of data silo IDs to assign the key to (optional)'),\n});\nexport type CreateApiKeyInput = z.infer<typeof CreateApiKeySchema>;\n\nexport function createAdminCreateApiKeyTool(clients: ToolClients) {\n const graphql = clients.graphql as AdminMixin;\n return defineTool({\n name: 'admin_create_api_key',\n description:\n 'Create a new API key with specified scopes. WARNING: The token is only shown once! ' +\n 'Scopes control what the key can access. Some scopes inherit dependencies — ' +\n 'for example, manageDataMap requires viewDataMap. ' +\n 'Use \"readOnly\" for view-only access to all resources, or \"fullAdmin\" for unrestricted access. ' +\n 'Common scopes: manageApiKeys, manageDataMap, manageConsentManager, makeDataSubjectRequest, ' +\n 'connectDataSilos, manageAssessments, manageDataInventory.\\n\\n' +\n 'Available scopes:\\n' +\n scopeSummary,\n category: 'Admin',\n readOnly: false,\n confirmationHint: 'Creates a new API key with the specified scopes',\n annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false },\n zodSchema: CreateApiKeySchema,\n handler: async ({ title, scopes, data_silos }) => {\n const result = await graphql.createApiKey({\n title,\n scopes,\n dataSilos: data_silos,\n });\n return createToolResult(true, {\n apiKey: result.apiKey,\n token: result.token,\n warning: 'IMPORTANT: Save this token now! It will not be shown again.',\n message: `API key \"${title}\" created successfully`,\n });\n },\n });\n}\n","import {\n createToolResult,\n defineTool,\n EmptySchema,\n type ToolClients,\n} from '@transcend-io/mcp-server-core';\n\nimport type { AdminMixin } from '../graphql.js';\n\nexport function createAdminGetCurrentUserTool(clients: ToolClients) {\n const graphql = clients.graphql as AdminMixin;\n return defineTool({\n name: 'admin_get_current_user',\n description: 'Get information about the currently authenticated user (the API key owner)',\n category: 'Admin',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: EmptySchema,\n handler: async (_args) => {\n const result = await graphql.getCurrentUser();\n return createToolResult(true, result);\n },\n });\n}\n","import {\n createToolResult,\n defineTool,\n EmptySchema,\n type ToolClients,\n} from '@transcend-io/mcp-server-core';\n\nimport type { AdminMixin } from '../graphql.js';\n\nexport function createAdminGetOrganizationTool(clients: ToolClients) {\n const graphql = clients.graphql as AdminMixin;\n return defineTool({\n name: 'admin_get_organization',\n description: 'Get information about your Transcend organization',\n category: 'Admin',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: EmptySchema,\n handler: async (_args) => {\n const result = await graphql.getOrganization();\n return createToolResult(true, result);\n },\n });\n}\n","import {\n createToolResult,\n defineTool,\n EmptySchema,\n type ToolClients,\n} from '@transcend-io/mcp-server-core';\n\nimport type { AdminMixin } from '../graphql.js';\n\nexport function createAdminGetPrivacyCenterTool(clients: ToolClients) {\n const graphql = clients.graphql as AdminMixin;\n return defineTool({\n name: 'admin_get_privacy_center',\n description: 'Get privacy center configuration for your organization',\n category: 'Admin',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: EmptySchema,\n handler: async (_args) => {\n const result = await graphql.getPrivacyCenter();\n if (!result) {\n return createToolResult(true, {\n found: false,\n message: 'No privacy center configured for this organization',\n });\n }\n return createToolResult(true, { found: true, privacyCenter: result });\n },\n });\n}\n","import { createListResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-core';\n\nimport type { AdminMixin } from '../graphql.js';\n\nexport const ListApiKeysSchema = 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 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 ListApiKeysInput = z.infer<typeof ListApiKeysSchema>;\n\nexport function createAdminListApiKeysTool(clients: ToolClients) {\n const graphql = clients.graphql as AdminMixin;\n return defineTool({\n name: 'admin_list_api_keys',\n description:\n 'List all API keys configured for your organization (tokens are not shown). Note: API does not support cursor pagination (max ~100 results).',\n category: 'Admin',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: ListApiKeysSchema,\n handler: async ({ limit, offset }) => {\n const result = await graphql.listApiKeys({\n first: limit,\n offset,\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 { AdminMixin } from '../graphql.js';\n\nexport const ListTeamsSchema = 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 ListTeamsInput = z.infer<typeof ListTeamsSchema>;\n\nexport function createAdminListTeamsTool(clients: ToolClients) {\n const graphql = clients.graphql as AdminMixin;\n return defineTool({\n name: 'admin_list_teams',\n description:\n 'List all teams in your Transcend organization. Note: API does not support cursor pagination (max ~100 results).',\n category: 'Admin',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: ListTeamsSchema,\n handler: async ({ limit, cursor }) => {\n const result = await graphql.listTeams({\n first: limit,\n after: cursor,\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 { AdminMixin } from '../graphql.js';\n\nexport const ListUsersSchema = 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 ListUsersInput = z.infer<typeof ListUsersSchema>;\n\nexport function createAdminListUsersTool(clients: ToolClients) {\n const graphql = clients.graphql as AdminMixin;\n return defineTool({\n name: 'admin_list_users',\n description:\n 'List all users in your Transcend organization. Note: API does not support cursor pagination (max ~100 results).',\n category: 'Admin',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: ListUsersSchema,\n handler: async ({ limit, cursor }) => {\n const result = await graphql.listUsers({\n first: limit,\n after: cursor,\n });\n return createListResult(result.nodes, {\n totalCount: result.totalCount,\n hasNextPage: result.pageInfo?.hasNextPage,\n });\n },\n });\n}\n","import {\n createToolResult,\n defineTool,\n EmptySchema,\n type ToolClients,\n} from '@transcend-io/mcp-server-core';\n\nimport type { AdminMixin } from '../graphql.js';\n\nexport function createAdminTestConnectionTool(clients: ToolClients) {\n const { rest } = clients;\n const graphql = clients.graphql as AdminMixin;\n return defineTool({\n name: 'admin_test_connection',\n description: 'Test connectivity to both Transcend REST and GraphQL APIs',\n category: 'Admin',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: EmptySchema,\n handler: async (_args) => {\n const [graphqlConnected, restConnected] = await Promise.all([\n graphql.testConnection(),\n rest.testConnection(),\n ]);\n const allConnected = graphqlConnected && restConnected;\n return createToolResult(true, {\n connected: allConnected,\n details: {\n graphql: { connected: graphqlConnected, url: graphql.getBaseUrl() },\n rest: { connected: restConnected, url: rest.getBaseUrl() },\n },\n message: allConnected\n ? 'Successfully connected to all Transcend APIs'\n : 'Some API connections failed - check details',\n timestamp: new Date().toISOString(),\n });\n },\n });\n}\n","import type { ToolDefinition, ToolClients } from '@transcend-io/mcp-server-core';\n\nimport { createAdminCreateApiKeyTool } from './admin_create_api_key.js';\nimport { createAdminGetCurrentUserTool } from './admin_get_current_user.js';\nimport { createAdminGetOrganizationTool } from './admin_get_organization.js';\nimport { createAdminGetPrivacyCenterTool } from './admin_get_privacy_center.js';\nimport { createAdminListApiKeysTool } from './admin_list_api_keys.js';\nimport { createAdminListTeamsTool } from './admin_list_teams.js';\nimport { createAdminListUsersTool } from './admin_list_users.js';\nimport { createAdminTestConnectionTool } from './admin_test_connection.js';\n\nexport function getAdminTools(clients: ToolClients): ToolDefinition[] {\n return [\n createAdminGetOrganizationTool(clients),\n createAdminGetCurrentUserTool(clients),\n createAdminListUsersTool(clients),\n createAdminListTeamsTool(clients),\n createAdminListApiKeysTool(clients),\n createAdminCreateApiKeyTool(clients),\n createAdminGetPrivacyCenterTool(clients),\n createAdminTestConnectionTool(clients),\n ];\n}\n","import {\n TranscendGraphQLBase,\n type ApiKey,\n type ApiKeyCreateInput,\n type ListOptions,\n type Organization,\n type PaginatedResponse,\n type PrivacyCenter,\n type Team,\n type User,\n} from '@transcend-io/mcp-server-core';\n\nexport class AdminMixin extends TranscendGraphQLBase {\n async getOrganization(): Promise<Organization> {\n const query = `\n query {\n organization {\n id\n name\n createdAt\n }\n }\n `;\n const data = await this.makeRequest<{ organization: Organization }>(query);\n return data.organization;\n }\n\n async getCurrentUser(): Promise<User> {\n const query = `\n query {\n user {\n id\n email\n name\n createdAt\n }\n }\n `;\n const data = await this.makeRequest<{ user: User }>(query);\n return data.user;\n }\n\n async listUsers(\n options?: ListOptions & { filterBy?: { text?: string } },\n ): Promise<PaginatedResponse<User>> {\n const query = `\n query ListUsers($first: Int, $filterBy: UserFiltersInput) {\n users(first: $first, filterBy: $filterBy) {\n nodes {\n id\n email\n name\n }\n totalCount\n }\n }\n `;\n const data = await this.makeRequest<{ users: { nodes: User[]; totalCount: number } }>(query, {\n first: Math.min(options?.first || 50, 100),\n ...(options?.filterBy ? { filterBy: options.filterBy } : {}),\n });\n return {\n nodes: data.users.nodes,\n pageInfo: {\n hasNextPage: data.users.nodes.length < data.users.totalCount,\n hasPreviousPage: false,\n },\n totalCount: data.users.totalCount,\n };\n }\n\n async listTeams(options?: ListOptions): Promise<PaginatedResponse<Team>> {\n const query = `\n query ListTeams($first: Int) {\n teams(first: $first) {\n nodes {\n id\n name\n }\n totalCount\n }\n }\n `;\n const data = await this.makeRequest<{ teams: { nodes: Team[]; totalCount: number } }>(query, {\n first: Math.min(options?.first || 50, 100),\n });\n return {\n nodes: data.teams.nodes,\n pageInfo: {\n hasNextPage: data.teams.nodes.length < data.teams.totalCount,\n hasPreviousPage: false,\n },\n totalCount: data.teams.totalCount,\n };\n }\n\n async listApiKeys(options?: ListOptions): Promise<PaginatedResponse<ApiKey>> {\n const query = `\n query ListApiKeys($first: Int, $offset: Int) {\n apiKeys(first: $first, offset: $offset) {\n nodes {\n id\n title\n scopes {\n id\n name\n }\n lastUsedAt\n createdAt\n }\n totalCount\n }\n }\n `;\n const data = await this.makeRequest<{ apiKeys: { nodes: ApiKey[]; totalCount: number } }>(\n query,\n {\n first: Math.min(options?.first || 50, 100),\n offset: options?.offset || 0,\n },\n );\n return {\n nodes: data.apiKeys.nodes,\n pageInfo: {\n hasNextPage: data.apiKeys.nodes.length < data.apiKeys.totalCount,\n hasPreviousPage: false,\n },\n totalCount: data.apiKeys.totalCount,\n };\n }\n\n async createApiKey(input: ApiKeyCreateInput): Promise<{ apiKey: ApiKey; token: string }> {\n const mutation = `\n mutation CreateApiKey($input: ApiKeyInput!) {\n createApiKey(input: $input) {\n apiKey {\n id\n title\n scopes\n createdAt\n }\n token\n }\n }\n `;\n const data = await this.makeRequest<{ createApiKey: { apiKey: ApiKey; token: string } }>(\n mutation,\n { input },\n );\n return data.createApiKey;\n }\n\n async getPrivacyCenter(lookup?: { url?: string }): Promise<PrivacyCenter | null> {\n const query = `\n query GetPrivacyCenter($lookup: PrivacyCenterLookupInput) {\n privacyCenter(lookup: $lookup) {\n id\n }\n }\n `;\n try {\n const data = await this.makeRequest<{ privacyCenter: { id: string } | null }>(query, {\n lookup: lookup || undefined,\n });\n if (data.privacyCenter) {\n return {\n id: data.privacyCenter.id,\n name: 'Privacy Center',\n url: lookup?.url || '',\n isActive: true,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n };\n }\n return null;\n } catch {\n return null;\n }\n }\n}\n"],"mappings":"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"}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { ApiKey, ApiKeyCreateInput, ListOptions, Organization, PaginatedResponse, PrivacyCenter, Team, ToolClients, ToolDefinition, TranscendGraphQLBase, User, z } from "@transcend-io/mcp-server-core";
|
|
2
|
+
import { ScopeName } from "@transcend-io/privacy-types";
|
|
3
|
+
|
|
4
|
+
//#region src/tools/index.d.ts
|
|
5
|
+
declare function getAdminTools(clients: ToolClients): ToolDefinition[];
|
|
6
|
+
//#endregion
|
|
7
|
+
//#region src/graphql.d.ts
|
|
8
|
+
declare class AdminMixin extends TranscendGraphQLBase {
|
|
9
|
+
getOrganization(): Promise<Organization>;
|
|
10
|
+
getCurrentUser(): Promise<User>;
|
|
11
|
+
listUsers(options?: ListOptions & {
|
|
12
|
+
filterBy?: {
|
|
13
|
+
text?: string;
|
|
14
|
+
};
|
|
15
|
+
}): Promise<PaginatedResponse<User>>;
|
|
16
|
+
listTeams(options?: ListOptions): Promise<PaginatedResponse<Team>>;
|
|
17
|
+
listApiKeys(options?: ListOptions): Promise<PaginatedResponse<ApiKey>>;
|
|
18
|
+
createApiKey(input: ApiKeyCreateInput): Promise<{
|
|
19
|
+
apiKey: ApiKey;
|
|
20
|
+
token: string;
|
|
21
|
+
}>;
|
|
22
|
+
getPrivacyCenter(lookup?: {
|
|
23
|
+
url?: string;
|
|
24
|
+
}): Promise<PrivacyCenter | null>;
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region src/tools/admin_create_api_key.d.ts
|
|
28
|
+
declare const CreateApiKeySchema: z.ZodObject<{
|
|
29
|
+
title: z.ZodString;
|
|
30
|
+
scopes: z.ZodArray<z.ZodEnum<typeof ScopeName>>;
|
|
31
|
+
data_silos: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
32
|
+
}, z.core.$strip>;
|
|
33
|
+
type CreateApiKeyInput = z.infer<typeof CreateApiKeySchema>;
|
|
34
|
+
//#endregion
|
|
35
|
+
//#region src/tools/admin_list_api_keys.d.ts
|
|
36
|
+
declare const ListApiKeysSchema: z.ZodObject<{
|
|
37
|
+
limit: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
38
|
+
cursor: z.ZodOptional<z.ZodString>;
|
|
39
|
+
offset: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
40
|
+
}, z.core.$strip>;
|
|
41
|
+
type ListApiKeysInput = z.infer<typeof ListApiKeysSchema>;
|
|
42
|
+
//#endregion
|
|
43
|
+
//#region src/tools/admin_list_teams.d.ts
|
|
44
|
+
declare const ListTeamsSchema: z.ZodObject<{
|
|
45
|
+
limit: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
46
|
+
cursor: z.ZodOptional<z.ZodString>;
|
|
47
|
+
}, z.core.$strip>;
|
|
48
|
+
type ListTeamsInput = z.infer<typeof ListTeamsSchema>;
|
|
49
|
+
//#endregion
|
|
50
|
+
//#region src/tools/admin_list_users.d.ts
|
|
51
|
+
declare const ListUsersSchema: z.ZodObject<{
|
|
52
|
+
limit: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
53
|
+
cursor: z.ZodOptional<z.ZodString>;
|
|
54
|
+
}, z.core.$strip>;
|
|
55
|
+
type ListUsersInput = z.infer<typeof ListUsersSchema>;
|
|
56
|
+
//#endregion
|
|
57
|
+
export { AdminMixin, type CreateApiKeyInput, CreateApiKeySchema, type ListApiKeysInput, ListApiKeysSchema, type ListTeamsInput, ListTeamsSchema, type ListUsersInput, ListUsersSchema, getAdminTools };
|
|
58
|
+
//# 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/admin_create_api_key.ts","../src/tools/admin_list_api_keys.ts","../src/tools/admin_list_teams.ts","../src/tools/admin_list_users.ts"],"mappings":";;;;iBAWgB,aAAA,CAAc,OAAA,EAAS,WAAA,GAAc,cAAA;;;cCCxC,UAAA,SAAmB,oBAAA;EACxB,eAAA,CAAA,GAAmB,OAAA,CAAQ,YAAA;EAc3B,cAAA,CAAA,GAAkB,OAAA,CAAQ,IAAA;EAe1B,SAAA,CACJ,OAAA,GAAU,WAAA;IAAgB,QAAA;MAAa,IAAA;IAAA;EAAA,IACtC,OAAA,CAAQ,iBAAA,CAAkB,IAAA;EA2BvB,SAAA,CAAU,OAAA,GAAU,WAAA,GAAc,OAAA,CAAQ,iBAAA,CAAkB,IAAA;EAyB5D,WAAA,CAAY,OAAA,GAAU,WAAA,GAAc,OAAA,CAAQ,iBAAA,CAAkB,MAAA;EAmC9D,YAAA,CAAa,KAAA,EAAO,iBAAA,GAAoB,OAAA;IAAU,MAAA,EAAQ,MAAA;IAAQ,KAAA;EAAA;EAqBlE,gBAAA,CAAiB,MAAA;IAAW,GAAA;EAAA,IAAiB,OAAA,CAAQ,aAAA;AAAA;;;cC5IhD,kBAAA,EAAkB,CAAA,CAAA,SAAA;;;;;KAQnB,iBAAA,GAAoB,CAAA,CAAE,KAAA,QAAa,kBAAA;;;cChBlC,iBAAA,EAAiB,CAAA,CAAA,SAAA;;;;;KAmBlB,gBAAA,GAAmB,CAAA,CAAE,KAAA,QAAa,iBAAA;;;cCnBjC,eAAA,EAAe,CAAA,CAAA,SAAA;;;;KAahB,cAAA,GAAiB,CAAA,CAAE,KAAA,QAAa,eAAA;;;cCb/B,eAAA,EAAe,CAAA,CAAA,SAAA;;;;KAahB,cAAA,GAAiB,CAAA,CAAE,KAAA,QAAa,eAAA"}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as ListApiKeysSchema, i as ListTeamsSchema, n as getAdminTools, o as CreateApiKeySchema, r as ListUsersSchema, t as AdminMixin } from "./graphql-DBU41KQd.mjs";
|
|
2
|
+
export { AdminMixin, CreateApiKeySchema, ListApiKeysSchema, ListTeamsSchema, ListUsersSchema, getAdminTools };
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@transcend-io/mcp-server-admin",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Transcend MCP Server — Admin tools.",
|
|
5
|
+
"homepage": "https://github.com/transcend-io/tools/tree/main/packages/mcp/mcp-server-admin",
|
|
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-admin"
|
|
12
|
+
},
|
|
13
|
+
"bin": {
|
|
14
|
+
"transcend-mcp-admin": "./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
|
+
"@transcend-io/privacy-types": "workspace:*",
|
|
43
|
+
"zod": "catalog:"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@arethetypeswrong/cli": "catalog:",
|
|
47
|
+
"@types/node": "catalog:",
|
|
48
|
+
"publint": "catalog:",
|
|
49
|
+
"tsdown": "catalog:",
|
|
50
|
+
"typescript": "catalog:",
|
|
51
|
+
"vitest": "catalog:"
|
|
52
|
+
},
|
|
53
|
+
"engines": {
|
|
54
|
+
"node": ">=22.12.0"
|
|
55
|
+
}
|
|
56
|
+
}
|