@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 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
@@ -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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"}
@@ -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
+ }