@transcend-io/mcp 0.4.23 → 0.5.1
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 +41 -15
- package/dist/cli.mjs +8 -6
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +5 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/{registry-DwQ6w9YS.mjs → oauth-scopes-BURfVnpI.mjs} +15 -11
- package/dist/oauth-scopes-BURfVnpI.mjs.map +1 -0
- package/package.json +12 -11
- package/dist/registry-DwQ6w9YS.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ Unified Transcend MCP Server that combines all domain tools into a single server
|
|
|
6
6
|
|
|
7
7
|
Requires **Node.js ≥ 22.12** (see `engines` in `package.json`).
|
|
8
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
|
|
9
|
+
For local runs from this repository, copy [`secret.env.example`](../../../secret.env.example) to **`secret.env`** at the repo root (gitignored) and set the OAuth environment variables (see **Run from the monorepo**).
|
|
10
10
|
|
|
11
11
|
## Install
|
|
12
12
|
|
|
@@ -23,8 +23,11 @@ Or run from a checkout of this repository (see **Run from the monorepo** below).
|
|
|
23
23
|
### stdio (local, default)
|
|
24
24
|
|
|
25
25
|
```bash
|
|
26
|
-
# With
|
|
27
|
-
|
|
26
|
+
# With OAuth env vars in the environment; from the monorepo use secret.env (see Run from the monorepo)
|
|
27
|
+
TRANSCEND_OAUTH_CLIENT_ID=your-client-id \
|
|
28
|
+
TRANSCEND_OAUTH_CLIENT_SECRET=your-client-secret \
|
|
29
|
+
TRANSCEND_OAUTH_REDIRECT_PORT=your-client-redirect-port \
|
|
30
|
+
transcend-mcp
|
|
28
31
|
```
|
|
29
32
|
|
|
30
33
|
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.
|
|
@@ -37,18 +40,39 @@ TRANSCEND_API_KEY=your-api-key transcend-mcp --transport http --port 3000
|
|
|
37
40
|
|
|
38
41
|
This starts a Streamable HTTP server at `http://127.0.0.1:3000/mcp` with a health check at `/health`. See [DEPLOYMENT.md](../DEPLOYMENT.md) for Docker, reverse proxy, and production deployment patterns.
|
|
39
42
|
|
|
43
|
+
### OAuth client setup
|
|
44
|
+
|
|
45
|
+
OAuth stdio is the recommended path for MCP clients. Requires **org admin** access to create OAuth clients at [app.transcend.com/admin/oauth-clients](https://app.transcend.com/admin/oauth-clients).
|
|
46
|
+
|
|
47
|
+
1. Create an OAuth client and copy the **client ID** and **client secret**.
|
|
48
|
+
2. Register `http://127.0.0.1:{port}/callback` — use **`127.0.0.1`, not `localhost`**, and ensure the path is `/callback`.
|
|
49
|
+
3. Set `TRANSCEND_OAUTH_REDIRECT_PORT` to the matching port.
|
|
50
|
+
|
|
51
|
+
At startup the server verifies client ID, secret, and redirect URI against Transcend's API. On first tool call it opens a browser for login. Tokens are session-only (in-memory).
|
|
52
|
+
|
|
53
|
+
**OAuth scopes:** this server requests the union of all domain scopes (see the [scopes table](../README.md#oauth-scopes) in the MCP root README). The signed-in user must hold these permissions.
|
|
54
|
+
|
|
55
|
+
Full setup, troubleshooting, and multi-server guidance: [MCP root README](../README.md#quick-start-stdio--oauth).
|
|
56
|
+
|
|
57
|
+
> **API key alternative:** set `TRANSCEND_API_KEY` instead of OAuth vars for stdio (OAuth is disabled when both are set).
|
|
58
|
+
|
|
40
59
|
### Environment variables
|
|
41
60
|
|
|
42
|
-
| Variable
|
|
43
|
-
|
|
|
44
|
-
| `
|
|
45
|
-
| `
|
|
46
|
-
| `
|
|
47
|
-
| `
|
|
48
|
-
| `
|
|
49
|
-
| `
|
|
50
|
-
| `
|
|
51
|
-
| `
|
|
61
|
+
| Variable | Required (stdio OAuth) | Default | Description |
|
|
62
|
+
| ------------------------------- | ---------------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
63
|
+
| `TRANSCEND_OAUTH_CLIENT_ID` | Yes | — | Client ID from [app.transcend.com/admin/oauth-clients](https://app.transcend.com/admin/oauth-clients) |
|
|
64
|
+
| `TRANSCEND_OAUTH_CLIENT_SECRET` | Yes | — | Client secret from the same OAuth clients page |
|
|
65
|
+
| `TRANSCEND_OAUTH_REDIRECT_PORT` | Yes | — | Localhost port for the OAuth callback server; **must match the port in your registered redirect URI** |
|
|
66
|
+
| `TRANSCEND_OAUTH_REDIRECT_HOST` | No | `127.0.0.1` | Loopback host for the OAuth callback (`127.0.0.1` or `::1` for `http://[::1]:{port}/callback`) |
|
|
67
|
+
| `TRANSCEND_OAUTH_ISSUER` | No | auto-detected | OAuth issuer URL; production auto-detects region. Test-only override |
|
|
68
|
+
| `TRANSCEND_API_KEY` | No | — | API key for stdio (alternative to OAuth) or HTTP default auth. Disables OAuth when set alongside client ID |
|
|
69
|
+
| `TRANSCEND_API_URL` | No | `https://api.transcend.io` | GraphQL backend API URL (matches CLI convention) |
|
|
70
|
+
| `SOMBRA_URL` | No | `https://multi-tenant.sombra.transcend.io` | Sombra REST API URL (matches CLI / SDK convention) |
|
|
71
|
+
| `TRANSCEND_DASHBOARD_URL` | No | `https://app.transcend.io` | Override the admin-dashboard base URL used for deep links returned by tool responses. Intended for local development against staging / fake hosts |
|
|
72
|
+
| `TRANSCEND_HTTP_PORT` | No | `3000` | HTTP listen port |
|
|
73
|
+
| `TRANSCEND_HTTP_HOST` | No | `127.0.0.1` | HTTP listen host |
|
|
74
|
+
| `TRANSCEND_MCP_CORS_ORIGINS` | No | — | Comma-separated allowed CORS origins |
|
|
75
|
+
| `TRANSCEND_MCP_SESSION_TTL_MS` | No | `1800000` | Idle session timeout (ms) |
|
|
52
76
|
|
|
53
77
|
### MCP client configuration (stdio)
|
|
54
78
|
|
|
@@ -61,7 +85,9 @@ This starts a Streamable HTTP server at `http://127.0.0.1:3000/mcp` with a healt
|
|
|
61
85
|
"command": "npx",
|
|
62
86
|
"args": ["-y", "@transcend-io/mcp"],
|
|
63
87
|
"env": {
|
|
64
|
-
"
|
|
88
|
+
"TRANSCEND_OAUTH_CLIENT_ID": "your-client-id",
|
|
89
|
+
"TRANSCEND_OAUTH_CLIENT_SECRET": "your-client-secret",
|
|
90
|
+
"TRANSCEND_OAUTH_REDIRECT_PORT": "your-client-redirect-port"
|
|
65
91
|
}
|
|
66
92
|
}
|
|
67
93
|
}
|
|
@@ -72,7 +98,7 @@ When developing in this repository, reuse the same variable names from root **`s
|
|
|
72
98
|
|
|
73
99
|
### Run from the monorepo
|
|
74
100
|
|
|
75
|
-
1. **Credentials** — From the repository root, copy [`secret.env.example`](../../../secret.env.example) to **`secret.env`** and set `
|
|
101
|
+
1. **Credentials** — From the repository root, copy [`secret.env.example`](../../../secret.env.example) to **`secret.env`** and set `TRANSCEND_OAUTH_CLIENT_ID`, `TRANSCEND_OAUTH_CLIENT_SECRET`, and `TRANSCEND_OAUTH_REDIRECT_PORT` (and optional URL overrides).
|
|
76
102
|
|
|
77
103
|
2. **Build and run** — `node ./dist/cli.mjs` matches the `transcend-mcp` `bin` (use `node` because `pnpm exec transcend-mcp` may not resolve this package’s own binary in a pnpm workspace):
|
|
78
104
|
|
package/dist/cli.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { n as TranscendGraphQLClient, t as
|
|
3
|
-
import {
|
|
2
|
+
import { n as ToolRegistry, r as TranscendGraphQLClient, t as UMBRELLA_OAUTH_SCOPES } from "./oauth-scopes-BURfVnpI.mjs";
|
|
3
|
+
import { DEFAULT_SOMBRA_URL, SimpleLogger, TranscendRestClient, buildMcpServer, configureOAuthScopes, isOAuthModeEnabled, parseTransportArgs, resolveMcpDashboardUrl, resolveMcpGraphqlUrl, resolveStdioStartupAuth, runMcpHttp } from "@transcend-io/mcp-server-base";
|
|
4
4
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5
5
|
//#region src/cli.ts
|
|
6
6
|
const VERSION = "3.0.2";
|
|
@@ -17,8 +17,8 @@ async function main() {
|
|
|
17
17
|
SimpleLogger.setInfoToStdout(isHttpTransport);
|
|
18
18
|
const logger = new SimpleLogger();
|
|
19
19
|
const sombraUrl = process.env.SOMBRA_URL || DEFAULT_SOMBRA_URL;
|
|
20
|
-
const
|
|
21
|
-
const
|
|
20
|
+
const dashboardUrl = resolveMcpDashboardUrl();
|
|
21
|
+
const graphqlUrl = await resolveMcpGraphqlUrl(logger);
|
|
22
22
|
if (isHttpTransport) {
|
|
23
23
|
await runMcpHttp({
|
|
24
24
|
name: "transcend-mcp",
|
|
@@ -39,11 +39,13 @@ async function main() {
|
|
|
39
39
|
}, config);
|
|
40
40
|
return;
|
|
41
41
|
}
|
|
42
|
-
|
|
42
|
+
configureOAuthScopes(UMBRELLA_OAUTH_SCOPES);
|
|
43
|
+
const auth = resolveStdioStartupAuth();
|
|
43
44
|
logger.info("Initializing Transcend API clients...", {
|
|
44
45
|
sombraUrl,
|
|
45
46
|
graphqlUrl,
|
|
46
|
-
dashboardUrl
|
|
47
|
+
dashboardUrl,
|
|
48
|
+
authType: auth?.type ?? (isOAuthModeEnabled() ? "oauth-pending" : "none")
|
|
47
49
|
});
|
|
48
50
|
const toolRegistry = createToolRegistry(auth, sombraUrl, graphqlUrl, dashboardUrl);
|
|
49
51
|
logger.info(`Registered ${toolRegistry.getToolCount()} tools across ${toolRegistry.getCategories().length} categories`, {
|
package/dist/cli.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.mjs","names":[],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport {\n buildMcpServer,\n
|
|
1
|
+
{"version":3,"file":"cli.mjs","names":[],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport {\n buildMcpServer,\n DEFAULT_SOMBRA_URL,\n isOAuthModeEnabled,\n parseTransportArgs,\n resolveStdioStartupAuth,\n configureOAuthScopes,\n resolveMcpDashboardUrl,\n resolveMcpGraphqlUrl,\n runMcpHttp,\n SimpleLogger,\n TranscendRestClient,\n type AuthCredentials,\n} from '@transcend-io/mcp-server-base';\n\nimport { TranscendGraphQLClient } from './graphql-client.js';\nimport { UMBRELLA_OAUTH_SCOPES } from './oauth-scopes.js';\nimport { ToolRegistry } from './registry.js';\n\nconst VERSION = '3.0.2';\n\nfunction createToolRegistry(\n auth: AuthCredentials | null,\n sombraUrl: string,\n graphqlUrl: string,\n dashboardUrl: string,\n): ToolRegistry {\n const restClient = new TranscendRestClient(auth, sombraUrl);\n const graphqlClient = new TranscendGraphQLClient(auth, graphqlUrl);\n return new ToolRegistry({ rest: restClient, graphql: graphqlClient, dashboardUrl });\n}\n\nasync function main(): Promise<void> {\n const config = parseTransportArgs();\n const isHttpTransport = config.transport === 'http';\n SimpleLogger.setInfoToStdout(isHttpTransport);\n const logger = new SimpleLogger();\n const sombraUrl = process.env.SOMBRA_URL || DEFAULT_SOMBRA_URL;\n const dashboardUrl = resolveMcpDashboardUrl();\n const graphqlUrl = await resolveMcpGraphqlUrl(logger);\n\n if (isHttpTransport) {\n await runMcpHttp(\n {\n name: 'transcend-mcp',\n version: VERSION,\n createServer: async (auth) => {\n logger.info('Creating unified MCP server for new HTTP session...', {\n sombraUrl,\n graphqlUrl,\n dashboardUrl,\n authType: auth?.type ?? 'none',\n });\n const registry = createToolRegistry(auth, sombraUrl, graphqlUrl, dashboardUrl);\n return buildMcpServer({\n name: 'transcend-mcp',\n version: VERSION,\n tools: registry.getAllTools(),\n });\n },\n },\n config,\n );\n return;\n }\n\n // stdio mode\n configureOAuthScopes(UMBRELLA_OAUTH_SCOPES);\n const auth = resolveStdioStartupAuth();\n logger.info('Initializing Transcend API clients...', {\n sombraUrl,\n graphqlUrl,\n dashboardUrl,\n authType: auth?.type ?? (isOAuthModeEnabled() ? 'oauth-pending' : 'none'),\n });\n\n const toolRegistry = createToolRegistry(auth, sombraUrl, graphqlUrl, dashboardUrl);\n\n logger.info(\n `Registered ${toolRegistry.getToolCount()} tools across ${toolRegistry.getCategories().length} categories`,\n {\n categories: toolRegistry.getCategories(),\n toolCount: toolRegistry.getToolCount(),\n },\n );\n\n const server = buildMcpServer({\n name: 'transcend-mcp',\n version: VERSION,\n tools: toolRegistry.getAllTools(),\n });\n\n logger.info(`Starting Transcend MCP Server v${VERSION}...`, {\n toolCount: toolRegistry.getToolCount(),\n categories: toolRegistry.getCategories(),\n });\n\n const transport = new StdioServerTransport();\n await server.connect(transport);\n\n logger.info('Transcend MCP Server started successfully', {\n sombraUrl,\n graphqlUrl,\n dashboardUrl,\n tools: toolRegistry.getToolCount(),\n });\n}\n\nmain().catch((error) => {\n const logger = new SimpleLogger();\n logger.error('Failed to start server:', error);\n process.exit(1);\n});\n"],"mappings":";;;;;AAsBA,MAAM,UAAU;AAEhB,SAAS,mBACP,MACA,WACA,YACA,cACc;AAGd,QAAO,IAAI,aAAa;EAAE,MAAM,IAFT,oBAAoB,MAAM,UAEP;EAAE,SAAS,IAD3B,uBAAuB,MAAM,WACW;EAAE;EAAc,CAAC;;AAGrF,eAAe,OAAsB;CACnC,MAAM,SAAS,oBAAoB;CACnC,MAAM,kBAAkB,OAAO,cAAc;AAC7C,cAAa,gBAAgB,gBAAgB;CAC7C,MAAM,SAAS,IAAI,cAAc;CACjC,MAAM,YAAY,QAAQ,IAAI,cAAc;CAC5C,MAAM,eAAe,wBAAwB;CAC7C,MAAM,aAAa,MAAM,qBAAqB,OAAO;AAErD,KAAI,iBAAiB;AACnB,QAAM,WACJ;GACE,MAAM;GACN,SAAS;GACT,cAAc,OAAO,SAAS;AAC5B,WAAO,KAAK,uDAAuD;KACjE;KACA;KACA;KACA,UAAU,MAAM,QAAQ;KACzB,CAAC;AAEF,WAAO,eAAe;KACpB,MAAM;KACN,SAAS;KACT,OAJe,mBAAmB,MAAM,WAAW,YAAY,aAIhD,CAAC,aAAa;KAC9B,CAAC;;GAEL,EACD,OACD;AACD;;AAIF,sBAAqB,sBAAsB;CAC3C,MAAM,OAAO,yBAAyB;AACtC,QAAO,KAAK,yCAAyC;EACnD;EACA;EACA;EACA,UAAU,MAAM,SAAS,oBAAoB,GAAG,kBAAkB;EACnE,CAAC;CAEF,MAAM,eAAe,mBAAmB,MAAM,WAAW,YAAY,aAAa;AAElF,QAAO,KACL,cAAc,aAAa,cAAc,CAAC,gBAAgB,aAAa,eAAe,CAAC,OAAO,cAC9F;EACE,YAAY,aAAa,eAAe;EACxC,WAAW,aAAa,cAAc;EACvC,CACF;CAED,MAAM,SAAS,eAAe;EAC5B,MAAM;EACN,SAAS;EACT,OAAO,aAAa,aAAa;EAClC,CAAC;AAEF,QAAO,KAAK,kCAAkC,QAAQ,MAAM;EAC1D,WAAW,aAAa,cAAc;EACtC,YAAY,aAAa,eAAe;EACzC,CAAC;CAEF,MAAM,YAAY,IAAI,sBAAsB;AAC5C,OAAM,OAAO,QAAQ,UAAU;AAE/B,QAAO,KAAK,6CAA6C;EACvD;EACA;EACA;EACA,OAAO,aAAa,cAAc;EACnC,CAAC;;AAGJ,MAAM,CAAC,OAAO,UAAU;AAEtB,KADmB,cACb,CAAC,MAAM,2BAA2B,MAAM;AAC9C,SAAQ,KAAK,EAAE;EACf"}
|
package/dist/index.d.mts
CHANGED
|
@@ -30,8 +30,6 @@ declare class TranscendGraphQLClient extends TranscendGraphQLBase {
|
|
|
30
30
|
listIdentifiers: InstanceType<typeof InventoryMixin>['listIdentifiers'];
|
|
31
31
|
listDataCategories: InstanceType<typeof InventoryMixin>['listDataCategories'];
|
|
32
32
|
listClassificationScans: InstanceType<typeof DiscoveryMixin>['listClassificationScans'];
|
|
33
|
-
startClassificationScan: InstanceType<typeof DiscoveryMixin>['startClassificationScan'];
|
|
34
|
-
getClassificationScan: InstanceType<typeof DiscoveryMixin>['getClassificationScan'];
|
|
35
33
|
listDiscoveryPlugins: InstanceType<typeof DiscoveryMixin>['listDiscoveryPlugins'];
|
|
36
34
|
listAssessments: InstanceType<typeof AssessmentsMixin>['listAssessments'];
|
|
37
35
|
getAssessment: InstanceType<typeof AssessmentsMixin>['getAssessment'];
|
|
@@ -87,5 +85,9 @@ declare class ToolRegistry {
|
|
|
87
85
|
getToolCount(): number;
|
|
88
86
|
}
|
|
89
87
|
//#endregion
|
|
90
|
-
|
|
88
|
+
//#region src/oauth-scopes.d.ts
|
|
89
|
+
/** OAuth scopes for the unified MCP server (offline_access added by base). */
|
|
90
|
+
declare const UMBRELLA_OAUTH_SCOPES: string[];
|
|
91
|
+
//#endregion
|
|
92
|
+
export { ToolRegistry, TranscendGraphQLClient, UMBRELLA_OAUTH_SCOPES };
|
|
91
93
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/graphql-client.ts","../src/registry.ts"],"mappings":";;;;;;;;;cAwBa,sBAAA,SAA+B,oBAAA;cAC9B,IAAA,EAAM,eAAA,SAAwB,OAAA,WAAkB,MAAA,GAAS,MAAA;EAK7D,eAAA,EAAiB,YAAA,QAAoB,UAAA;EACrC,cAAA,EAAgB,YAAA,QAAoB,UAAA;EACpC,SAAA,EAAW,YAAA,QAAoB,UAAA;EAC/B,SAAA,EAAW,YAAA,QAAoB,UAAA;EAC/B,WAAA,EAAa,YAAA,QAAoB,UAAA;EACjC,YAAA,EAAc,YAAA,QAAoB,UAAA;EAClC,gBAAA,EAAkB,YAAA,QAAoB,UAAA;EAGtC,YAAA,EAAc,YAAA,QAAoB,QAAA;EAClC,UAAA,EAAY,YAAA,QAAoB,QAAA;EAChC,8BAAA,EAAgC,YAAA,QAC/B,QAAA;EAED,aAAA,EAAe,YAAA,QAAoB,QAAA;EAGnC,aAAA,EAAe,YAAA,QAAoB,cAAA;EACnC,WAAA,EAAa,YAAA,QAAoB,cAAA;EACjC,cAAA,EAAgB,YAAA,QAAoB,cAAA;EACpC,cAAA,EAAgB,YAAA,QAAoB,cAAA;EACpC,WAAA,EAAa,YAAA,QAAoB,cAAA;EACjC,cAAA,EAAgB,YAAA,QAAoB,cAAA;EACpC,iBAAA,EAAmB,YAAA,QAAoB,cAAA;EACvC,eAAA,EAAiB,YAAA,QAAoB,cAAA;EACrC,kBAAA,EAAoB,YAAA,QAAoB,cAAA;EAKxC,uBAAA,EAAyB,YAAA,QAAoB,cAAA;EAC7C,
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/graphql-client.ts","../src/registry.ts","../src/oauth-scopes.ts"],"mappings":";;;;;;;;;cAwBa,sBAAA,SAA+B,oBAAA;cAC9B,IAAA,EAAM,eAAA,SAAwB,OAAA,WAAkB,MAAA,GAAS,MAAA;EAK7D,eAAA,EAAiB,YAAA,QAAoB,UAAA;EACrC,cAAA,EAAgB,YAAA,QAAoB,UAAA;EACpC,SAAA,EAAW,YAAA,QAAoB,UAAA;EAC/B,SAAA,EAAW,YAAA,QAAoB,UAAA;EAC/B,WAAA,EAAa,YAAA,QAAoB,UAAA;EACjC,YAAA,EAAc,YAAA,QAAoB,UAAA;EAClC,gBAAA,EAAkB,YAAA,QAAoB,UAAA;EAGtC,YAAA,EAAc,YAAA,QAAoB,QAAA;EAClC,UAAA,EAAY,YAAA,QAAoB,QAAA;EAChC,8BAAA,EAAgC,YAAA,QAC/B,QAAA;EAED,aAAA,EAAe,YAAA,QAAoB,QAAA;EAGnC,aAAA,EAAe,YAAA,QAAoB,cAAA;EACnC,WAAA,EAAa,YAAA,QAAoB,cAAA;EACjC,cAAA,EAAgB,YAAA,QAAoB,cAAA;EACpC,cAAA,EAAgB,YAAA,QAAoB,cAAA;EACpC,WAAA,EAAa,YAAA,QAAoB,cAAA;EACjC,cAAA,EAAgB,YAAA,QAAoB,cAAA;EACpC,iBAAA,EAAmB,YAAA,QAAoB,cAAA;EACvC,eAAA,EAAiB,YAAA,QAAoB,cAAA;EACrC,kBAAA,EAAoB,YAAA,QAAoB,cAAA;EAKxC,uBAAA,EAAyB,YAAA,QAAoB,cAAA;EAC7C,oBAAA,EAAsB,YAAA,QAAoB,cAAA;EAG1C,eAAA,EAAiB,YAAA,QAAoB,gBAAA;EACrC,aAAA,EAAe,YAAA,QAAoB,gBAAA;EACnC,+BAAA,EAAiC,YAAA,QAChC,gBAAA;EAED,6BAAA,EAA+B,YAAA,QAC9B,gBAAA;EAED,oBAAA,EAAsB,YAAA,QAAoB,gBAAA;EAC1C,qBAAA,EAAuB,YAAA,QAAoB,gBAAA;EAC3C,gBAAA,EAAkB,YAAA,QAAoB,gBAAA;EACtC,gBAAA,EAAkB,YAAA,QAAoB,gBAAA;EACtC,uBAAA,EAAyB,YAAA,QAAoB,gBAAA;EAC7C,yBAAA,EAA2B,YAAA,QAC1B,gBAAA;EAED,4BAAA,EAA8B,YAAA,QAC7B,gBAAA;EAED,uBAAA,EAAyB,YAAA,QAAoB,gBAAA;EAC7C,yBAAA,EAA2B,YAAA,QAC1B,gBAAA;EAED,yBAAA,EAA2B,YAAA,QAC1B,gBAAA;EAID,aAAA,EAAe,YAAA,QAAoB,cAAA;EACnC,oBAAA,EAAsB,YAAA,QAAoB,cAAA;EAC1C,kBAAA,EAAoB,YAAA,QAAoB,cAAA;AAAA;;;UC5EjC,mBAAA;;EAEf,IAAA,EAAM,mBAAA;;EAEN,OAAA,EAAS,sBAAA;;EAET,YAAA;AAAA;AAAA,cAGW,YAAA;EAAA,QACH,KAAA;EAAA,QACA,eAAA;EAAA,QACA,OAAA;EAAA,QACA,MAAA;cAEI,OAAA,EAAS,mBAAA;EAAA,QAKb,gBAAA;EAAA,QAWA,uBAAA;EAcR,WAAA,CAAA,GAAe,KAAA;IACb,IAAA;IACA,WAAA;IACA,WAAA,EAAa,MAAA;IACb,WAAA;MACE,YAAA;MACA,eAAA;MACA,cAAA;IAAA;EAAA;EAWJ,OAAA,CAAQ,IAAA,WAAe,cAAA;EAIjB,WAAA,CAAY,IAAA,UAAc,IAAA,EAAM,MAAA,oBAA0B,OAAA;EAqBhE,kBAAA,CAAmB,QAAA,WAAmB,cAAA;EAItC,aAAA,CAAA;EAQA,WAAA,CAAA,GAAe,cAAA;EAIf,YAAA,CAAA;AAAA;;;;cC/GW,qBAAA"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as TranscendGraphQLClient, t as
|
|
2
|
-
export { ToolRegistry, TranscendGraphQLClient };
|
|
1
|
+
import { n as ToolRegistry, r as TranscendGraphQLClient, t as UMBRELLA_OAUTH_SCOPES } from "./oauth-scopes-BURfVnpI.mjs";
|
|
2
|
+
export { ToolRegistry, TranscendGraphQLClient, UMBRELLA_OAUTH_SCOPES };
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { AdminMixin, getAdminTools } from "@transcend-io/mcp-server-admin";
|
|
2
|
-
import { AssessmentsMixin, getAssessmentTools } from "@transcend-io/mcp-server-assessment";
|
|
3
|
-
import { SimpleLogger, TranscendGraphQLBase, createErrorResult } from "@transcend-io/mcp-server-base";
|
|
4
|
-
import { DiscoveryMixin, getDiscoveryTools } from "@transcend-io/mcp-server-discovery";
|
|
5
|
-
import { DSRMixin, getDSRTools } from "@transcend-io/mcp-server-dsr";
|
|
6
|
-
import { InventoryMixin, getInventoryTools } from "@transcend-io/mcp-server-inventory";
|
|
7
|
-
import { WorkflowsMixin, getWorkflowTools } from "@transcend-io/mcp-server-workflows";
|
|
1
|
+
import { ADMIN_OAUTH_SCOPES, AdminMixin, getAdminTools } from "@transcend-io/mcp-server-admin";
|
|
2
|
+
import { ASSESSMENT_OAUTH_SCOPES, AssessmentsMixin, getAssessmentTools } from "@transcend-io/mcp-server-assessment";
|
|
3
|
+
import { SimpleLogger, TranscendGraphQLBase, createErrorResult, mergeOAuthScopes } from "@transcend-io/mcp-server-base";
|
|
4
|
+
import { DISCOVERY_OAUTH_SCOPES, DiscoveryMixin, getDiscoveryTools } from "@transcend-io/mcp-server-discovery";
|
|
5
|
+
import { DSRMixin, DSR_OAUTH_SCOPES, getDSRTools } from "@transcend-io/mcp-server-dsr";
|
|
6
|
+
import { INVENTORY_OAUTH_SCOPES, InventoryMixin, getInventoryTools } from "@transcend-io/mcp-server-inventory";
|
|
7
|
+
import { WORKFLOW_OAUTH_SCOPES, WorkflowsMixin, getWorkflowTools } from "@transcend-io/mcp-server-workflows";
|
|
8
8
|
import { toJsonSchemaCompat } from "@modelcontextprotocol/sdk/server/zod-json-schema-compat.js";
|
|
9
|
-
import { getConsentTools } from "@transcend-io/mcp-server-consent";
|
|
10
|
-
import { getPreferenceTools } from "@transcend-io/mcp-server-preferences";
|
|
9
|
+
import { CONSENT_OAUTH_SCOPES, getConsentTools } from "@transcend-io/mcp-server-consent";
|
|
10
|
+
import { PREFERENCE_OAUTH_SCOPES, getPreferenceTools } from "@transcend-io/mcp-server-preferences";
|
|
11
11
|
//#region src/graphql-client.ts
|
|
12
12
|
function applyMixin(target, mixin) {
|
|
13
13
|
Object.getOwnPropertyNames(mixin.prototype).forEach((name) => {
|
|
@@ -102,6 +102,10 @@ var ToolRegistry = class {
|
|
|
102
102
|
}
|
|
103
103
|
};
|
|
104
104
|
//#endregion
|
|
105
|
-
|
|
105
|
+
//#region src/oauth-scopes.ts
|
|
106
|
+
/** OAuth scopes for the unified MCP server (offline_access added by base). */
|
|
107
|
+
const UMBRELLA_OAUTH_SCOPES = mergeOAuthScopes(ADMIN_OAUTH_SCOPES, ASSESSMENT_OAUTH_SCOPES, CONSENT_OAUTH_SCOPES, DISCOVERY_OAUTH_SCOPES, DSR_OAUTH_SCOPES, INVENTORY_OAUTH_SCOPES, PREFERENCE_OAUTH_SCOPES, WORKFLOW_OAUTH_SCOPES);
|
|
108
|
+
//#endregion
|
|
109
|
+
export { ToolRegistry as n, TranscendGraphQLClient as r, UMBRELLA_OAUTH_SCOPES as t };
|
|
106
110
|
|
|
107
|
-
//# sourceMappingURL=
|
|
111
|
+
//# sourceMappingURL=oauth-scopes-BURfVnpI.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-scopes-BURfVnpI.mjs","names":[],"sources":["../src/graphql-client.ts","../src/registry.ts","../src/oauth-scopes.ts"],"sourcesContent":["import { AdminMixin } from '@transcend-io/mcp-server-admin';\nimport { AssessmentsMixin } from '@transcend-io/mcp-server-assessment';\nimport {\n TranscendGraphQLBase,\n type AuthCredentials,\n type Logger,\n} from '@transcend-io/mcp-server-base';\nimport { DiscoveryMixin } from '@transcend-io/mcp-server-discovery';\nimport { DSRMixin } from '@transcend-io/mcp-server-dsr';\nimport { InventoryMixin } from '@transcend-io/mcp-server-inventory';\nimport { WorkflowsMixin } from '@transcend-io/mcp-server-workflows';\n\ntype Constructor<T = object> = new (...args: [AuthCredentials | null, string?, Logger?]) => T;\n\nfunction applyMixin(target: Constructor, mixin: Constructor): void {\n Object.getOwnPropertyNames(mixin.prototype).forEach((name) => {\n if (name === 'constructor') return;\n const descriptor = Object.getOwnPropertyDescriptor(mixin.prototype, name);\n if (descriptor) {\n Object.defineProperty(target.prototype, name, descriptor);\n }\n });\n}\n\nexport class TranscendGraphQLClient extends TranscendGraphQLBase {\n constructor(auth: AuthCredentials | null, baseUrl?: string, logger?: Logger) {\n super(auth, baseUrl, logger);\n }\n\n // Admin\n declare getOrganization: InstanceType<typeof AdminMixin>['getOrganization'];\n declare getCurrentUser: InstanceType<typeof AdminMixin>['getCurrentUser'];\n declare listUsers: InstanceType<typeof AdminMixin>['listUsers'];\n declare listTeams: InstanceType<typeof AdminMixin>['listTeams'];\n declare listApiKeys: InstanceType<typeof AdminMixin>['listApiKeys'];\n declare createApiKey: InstanceType<typeof AdminMixin>['createApiKey'];\n declare getPrivacyCenter: InstanceType<typeof AdminMixin>['getPrivacyCenter'];\n\n // DSR\n declare listRequests: InstanceType<typeof DSRMixin>['listRequests'];\n declare getRequest: InstanceType<typeof DSRMixin>['getRequest'];\n declare employeeMakeDataSubjectRequest: InstanceType<\n typeof DSRMixin\n >['employeeMakeDataSubjectRequest'];\n declare cancelRequest: InstanceType<typeof DSRMixin>['cancelRequest'];\n\n // Inventory\n declare listDataSilos: InstanceType<typeof InventoryMixin>['listDataSilos'];\n declare getDataSilo: InstanceType<typeof InventoryMixin>['getDataSilo'];\n declare createDataSilo: InstanceType<typeof InventoryMixin>['createDataSilo'];\n declare updateDataSilo: InstanceType<typeof InventoryMixin>['updateDataSilo'];\n declare listVendors: InstanceType<typeof InventoryMixin>['listVendors'];\n declare listDataPoints: InstanceType<typeof InventoryMixin>['listDataPoints'];\n declare listSubDataPoints: InstanceType<typeof InventoryMixin>['listSubDataPoints'];\n declare listIdentifiers: InstanceType<typeof InventoryMixin>['listIdentifiers'];\n declare listDataCategories: InstanceType<typeof InventoryMixin>['listDataCategories'];\n\n // Consent tools now call makeRequest directly (no mixin needed)\n\n // Discovery\n declare listClassificationScans: InstanceType<typeof DiscoveryMixin>['listClassificationScans'];\n declare listDiscoveryPlugins: InstanceType<typeof DiscoveryMixin>['listDiscoveryPlugins'];\n\n // Assessments\n declare listAssessments: InstanceType<typeof AssessmentsMixin>['listAssessments'];\n declare getAssessment: InstanceType<typeof AssessmentsMixin>['getAssessment'];\n declare selectAssessmentQuestionAnswers: InstanceType<\n typeof AssessmentsMixin\n >['selectAssessmentQuestionAnswers'];\n declare updateAssessmentFormAssignees: InstanceType<\n typeof AssessmentsMixin\n >['updateAssessmentFormAssignees'];\n declare listAssessmentGroups: InstanceType<typeof AssessmentsMixin>['listAssessmentGroups'];\n declare createAssessmentGroup: InstanceType<typeof AssessmentsMixin>['createAssessmentGroup'];\n declare createAssessment: InstanceType<typeof AssessmentsMixin>['createAssessment'];\n declare updateAssessment: InstanceType<typeof AssessmentsMixin>['updateAssessment'];\n declare listAssessmentTemplates: InstanceType<typeof AssessmentsMixin>['listAssessmentTemplates'];\n declare submitAssessmentForReview: InstanceType<\n typeof AssessmentsMixin\n >['submitAssessmentForReview'];\n declare createAssessmentFormTemplate: InstanceType<\n typeof AssessmentsMixin\n >['createAssessmentFormTemplate'];\n declare createAssessmentSection: InstanceType<typeof AssessmentsMixin>['createAssessmentSection'];\n declare createAssessmentQuestions: InstanceType<\n typeof AssessmentsMixin\n >['createAssessmentQuestions'];\n declare getAssessmentFormTemplate: InstanceType<\n typeof AssessmentsMixin\n >['getAssessmentFormTemplate'];\n\n // Workflows\n declare listWorkflows: InstanceType<typeof WorkflowsMixin>['listWorkflows'];\n declare updateWorkflowConfig: InstanceType<typeof WorkflowsMixin>['updateWorkflowConfig'];\n declare listEmailTemplates: InstanceType<typeof WorkflowsMixin>['listEmailTemplates'];\n}\n\napplyMixin(TranscendGraphQLClient, AdminMixin);\napplyMixin(TranscendGraphQLClient, DSRMixin);\napplyMixin(TranscendGraphQLClient, InventoryMixin);\napplyMixin(TranscendGraphQLClient, DiscoveryMixin);\napplyMixin(TranscendGraphQLClient, AssessmentsMixin);\napplyMixin(TranscendGraphQLClient, WorkflowsMixin);\n","import { toJsonSchemaCompat } from '@modelcontextprotocol/sdk/server/zod-json-schema-compat.js';\nimport { getAdminTools } from '@transcend-io/mcp-server-admin';\nimport { getAssessmentTools } from '@transcend-io/mcp-server-assessment';\nimport {\n createErrorResult,\n SimpleLogger,\n type ToolDefinition,\n type TranscendRestClient,\n} from '@transcend-io/mcp-server-base';\nimport { getConsentTools } from '@transcend-io/mcp-server-consent';\nimport { getDiscoveryTools } from '@transcend-io/mcp-server-discovery';\nimport { getDSRTools } from '@transcend-io/mcp-server-dsr';\nimport { getInventoryTools } from '@transcend-io/mcp-server-inventory';\nimport { getPreferenceTools } from '@transcend-io/mcp-server-preferences';\nimport { getWorkflowTools } from '@transcend-io/mcp-server-workflows';\n\nimport type { TranscendGraphQLClient } from './graphql-client.js';\n\nexport interface UmbrellaToolClients {\n /** REST client for Sombra API */\n rest: TranscendRestClient;\n /** Composed GraphQL client with all domain mixins */\n graphql: TranscendGraphQLClient;\n /** Admin-dashboard base URL used to build deep links */\n dashboardUrl: string;\n}\n\nexport class ToolRegistry {\n private tools: Map<string, ToolDefinition> = new Map();\n private jsonSchemaCache: Map<string, Record<string, unknown>> = new Map();\n private clients: UmbrellaToolClients;\n private logger = new SimpleLogger();\n\n constructor(clients: UmbrellaToolClients) {\n this.clients = clients;\n this.registerAllTools();\n }\n\n private registerAllTools(): void {\n this.registerToolsFromModule(getDSRTools(this.clients));\n this.registerToolsFromModule(getConsentTools(this.clients));\n this.registerToolsFromModule(getPreferenceTools(this.clients));\n this.registerToolsFromModule(getInventoryTools(this.clients));\n this.registerToolsFromModule(getDiscoveryTools(this.clients));\n this.registerToolsFromModule(getAssessmentTools(this.clients));\n this.registerToolsFromModule(getWorkflowTools(this.clients));\n this.registerToolsFromModule(getAdminTools(this.clients));\n }\n\n private registerToolsFromModule(tools: ToolDefinition[]): void {\n for (const tool of tools) {\n if (this.tools.has(tool.name)) {\n this.logger.warn('Duplicate tool name - skipping', { toolName: tool.name });\n continue;\n }\n this.tools.set(tool.name, tool);\n this.jsonSchemaCache.set(\n tool.name,\n toJsonSchemaCompat(tool.zodSchema as any) as Record<string, unknown>,\n );\n }\n }\n\n getToolList(): Array<{\n name: string;\n description: string;\n inputSchema: Record<string, unknown>;\n annotations: {\n readOnlyHint: boolean;\n destructiveHint: boolean;\n idempotentHint: boolean;\n };\n }> {\n return Array.from(this.tools.values()).map((tool) => ({\n name: tool.name,\n description: tool.description,\n inputSchema: this.jsonSchemaCache.get(tool.name) || { type: 'object', properties: {} },\n annotations: tool.annotations,\n }));\n }\n\n getTool(name: string): ToolDefinition | undefined {\n return this.tools.get(name);\n }\n\n async executeTool(name: string, args: Record<string, unknown>): Promise<unknown> {\n const tool = this.tools.get(name);\n if (!tool) {\n throw new Error(`Unknown tool: ${name}`);\n }\n\n const parseResult = tool.zodSchema.safeParse(args);\n if (!parseResult.success) {\n const issues = parseResult.error.issues\n .map((i: any) => `${i.path.join('.') || 'input'}: ${i.message}`)\n .join('; ');\n throw new Error(`Invalid input: ${issues}`);\n }\n\n try {\n return await tool.handler(parseResult.data);\n } catch (error) {\n return createErrorResult(error);\n }\n }\n\n getToolsByCategory(category: string): ToolDefinition[] {\n return Array.from(this.tools.values()).filter((tool) => tool.category === category);\n }\n\n getCategories(): string[] {\n const categories = new Set<string>();\n for (const tool of this.tools.values()) {\n categories.add(tool.category);\n }\n return Array.from(categories);\n }\n\n getAllTools(): ToolDefinition[] {\n return Array.from(this.tools.values());\n }\n\n getToolCount(): number {\n return this.tools.size;\n }\n}\n","import { ADMIN_OAUTH_SCOPES } from '@transcend-io/mcp-server-admin';\nimport { ASSESSMENT_OAUTH_SCOPES } from '@transcend-io/mcp-server-assessment';\nimport { mergeOAuthScopes } from '@transcend-io/mcp-server-base';\nimport { CONSENT_OAUTH_SCOPES } from '@transcend-io/mcp-server-consent';\nimport { DISCOVERY_OAUTH_SCOPES } from '@transcend-io/mcp-server-discovery';\nimport { DSR_OAUTH_SCOPES } from '@transcend-io/mcp-server-dsr';\nimport { INVENTORY_OAUTH_SCOPES } from '@transcend-io/mcp-server-inventory';\nimport { PREFERENCE_OAUTH_SCOPES } from '@transcend-io/mcp-server-preferences';\nimport { WORKFLOW_OAUTH_SCOPES } from '@transcend-io/mcp-server-workflows';\n\n/** OAuth scopes for the unified MCP server (offline_access added by base). */\nexport const UMBRELLA_OAUTH_SCOPES = mergeOAuthScopes(\n ADMIN_OAUTH_SCOPES,\n ASSESSMENT_OAUTH_SCOPES,\n CONSENT_OAUTH_SCOPES,\n DISCOVERY_OAUTH_SCOPES,\n DSR_OAUTH_SCOPES,\n INVENTORY_OAUTH_SCOPES,\n PREFERENCE_OAUTH_SCOPES,\n WORKFLOW_OAUTH_SCOPES,\n);\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@transcend-io/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Transcend MCP Server — unified server with all domain tools.",
|
|
5
5
|
"homepage": "https://github.com/transcend-io/tools/tree/main/packages/mcp/mcp",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -32,15 +32,15 @@
|
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
34
34
|
"zod": "^4.3.6",
|
|
35
|
-
"@transcend-io/mcp-server-admin": "0.
|
|
36
|
-
"@transcend-io/mcp-server-assessment": "0.
|
|
37
|
-
"@transcend-io/mcp-server-base": "0.
|
|
38
|
-
"@transcend-io/mcp-server-consent": "0.
|
|
39
|
-
"@transcend-io/mcp-server-discovery": "0.
|
|
40
|
-
"@transcend-io/mcp-server-dsr": "0.
|
|
41
|
-
"@transcend-io/mcp-server-inventory": "0.
|
|
42
|
-
"@transcend-io/mcp-server-preferences": "0.
|
|
43
|
-
"@transcend-io/mcp-server-workflows": "0.
|
|
35
|
+
"@transcend-io/mcp-server-admin": "0.4.1",
|
|
36
|
+
"@transcend-io/mcp-server-assessment": "0.4.1",
|
|
37
|
+
"@transcend-io/mcp-server-base": "0.5.0",
|
|
38
|
+
"@transcend-io/mcp-server-consent": "0.4.1",
|
|
39
|
+
"@transcend-io/mcp-server-discovery": "0.4.1",
|
|
40
|
+
"@transcend-io/mcp-server-dsr": "0.4.1",
|
|
41
|
+
"@transcend-io/mcp-server-inventory": "0.4.1",
|
|
42
|
+
"@transcend-io/mcp-server-preferences": "0.4.1",
|
|
43
|
+
"@transcend-io/mcp-server-workflows": "0.4.1"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@arethetypeswrong/cli": "^0.18.2",
|
|
@@ -48,7 +48,8 @@
|
|
|
48
48
|
"publint": "^0.3.18",
|
|
49
49
|
"tsdown": "^0.21.2",
|
|
50
50
|
"typescript": "^6.0.0",
|
|
51
|
-
"vitest": "^4.0.18"
|
|
51
|
+
"vitest": "^4.0.18",
|
|
52
|
+
"@transcend-io/privacy-types": "5.4.0"
|
|
52
53
|
},
|
|
53
54
|
"engines": {
|
|
54
55
|
"node": ">=22.12.0"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"registry-DwQ6w9YS.mjs","names":[],"sources":["../src/graphql-client.ts","../src/registry.ts"],"sourcesContent":["import { AdminMixin } from '@transcend-io/mcp-server-admin';\nimport { AssessmentsMixin } from '@transcend-io/mcp-server-assessment';\nimport {\n TranscendGraphQLBase,\n type AuthCredentials,\n type Logger,\n} from '@transcend-io/mcp-server-base';\nimport { DiscoveryMixin } from '@transcend-io/mcp-server-discovery';\nimport { DSRMixin } from '@transcend-io/mcp-server-dsr';\nimport { InventoryMixin } from '@transcend-io/mcp-server-inventory';\nimport { WorkflowsMixin } from '@transcend-io/mcp-server-workflows';\n\ntype Constructor<T = object> = new (...args: [AuthCredentials | null, string?, Logger?]) => T;\n\nfunction applyMixin(target: Constructor, mixin: Constructor): void {\n Object.getOwnPropertyNames(mixin.prototype).forEach((name) => {\n if (name === 'constructor') return;\n const descriptor = Object.getOwnPropertyDescriptor(mixin.prototype, name);\n if (descriptor) {\n Object.defineProperty(target.prototype, name, descriptor);\n }\n });\n}\n\nexport class TranscendGraphQLClient extends TranscendGraphQLBase {\n constructor(auth: AuthCredentials | null, baseUrl?: string, logger?: Logger) {\n super(auth, baseUrl, logger);\n }\n\n // Admin\n declare getOrganization: InstanceType<typeof AdminMixin>['getOrganization'];\n declare getCurrentUser: InstanceType<typeof AdminMixin>['getCurrentUser'];\n declare listUsers: InstanceType<typeof AdminMixin>['listUsers'];\n declare listTeams: InstanceType<typeof AdminMixin>['listTeams'];\n declare listApiKeys: InstanceType<typeof AdminMixin>['listApiKeys'];\n declare createApiKey: InstanceType<typeof AdminMixin>['createApiKey'];\n declare getPrivacyCenter: InstanceType<typeof AdminMixin>['getPrivacyCenter'];\n\n // DSR\n declare listRequests: InstanceType<typeof DSRMixin>['listRequests'];\n declare getRequest: InstanceType<typeof DSRMixin>['getRequest'];\n declare employeeMakeDataSubjectRequest: InstanceType<\n typeof DSRMixin\n >['employeeMakeDataSubjectRequest'];\n declare cancelRequest: InstanceType<typeof DSRMixin>['cancelRequest'];\n\n // Inventory\n declare listDataSilos: InstanceType<typeof InventoryMixin>['listDataSilos'];\n declare getDataSilo: InstanceType<typeof InventoryMixin>['getDataSilo'];\n declare createDataSilo: InstanceType<typeof InventoryMixin>['createDataSilo'];\n declare updateDataSilo: InstanceType<typeof InventoryMixin>['updateDataSilo'];\n declare listVendors: InstanceType<typeof InventoryMixin>['listVendors'];\n declare listDataPoints: InstanceType<typeof InventoryMixin>['listDataPoints'];\n declare listSubDataPoints: InstanceType<typeof InventoryMixin>['listSubDataPoints'];\n declare listIdentifiers: InstanceType<typeof InventoryMixin>['listIdentifiers'];\n declare listDataCategories: InstanceType<typeof InventoryMixin>['listDataCategories'];\n\n // Consent tools now call makeRequest directly (no mixin needed)\n\n // Discovery\n declare listClassificationScans: InstanceType<typeof DiscoveryMixin>['listClassificationScans'];\n declare startClassificationScan: InstanceType<typeof DiscoveryMixin>['startClassificationScan'];\n declare getClassificationScan: InstanceType<typeof DiscoveryMixin>['getClassificationScan'];\n declare listDiscoveryPlugins: InstanceType<typeof DiscoveryMixin>['listDiscoveryPlugins'];\n\n // Assessments\n declare listAssessments: InstanceType<typeof AssessmentsMixin>['listAssessments'];\n declare getAssessment: InstanceType<typeof AssessmentsMixin>['getAssessment'];\n declare selectAssessmentQuestionAnswers: InstanceType<\n typeof AssessmentsMixin\n >['selectAssessmentQuestionAnswers'];\n declare updateAssessmentFormAssignees: InstanceType<\n typeof AssessmentsMixin\n >['updateAssessmentFormAssignees'];\n declare listAssessmentGroups: InstanceType<typeof AssessmentsMixin>['listAssessmentGroups'];\n declare createAssessmentGroup: InstanceType<typeof AssessmentsMixin>['createAssessmentGroup'];\n declare createAssessment: InstanceType<typeof AssessmentsMixin>['createAssessment'];\n declare updateAssessment: InstanceType<typeof AssessmentsMixin>['updateAssessment'];\n declare listAssessmentTemplates: InstanceType<typeof AssessmentsMixin>['listAssessmentTemplates'];\n declare submitAssessmentForReview: InstanceType<\n typeof AssessmentsMixin\n >['submitAssessmentForReview'];\n declare createAssessmentFormTemplate: InstanceType<\n typeof AssessmentsMixin\n >['createAssessmentFormTemplate'];\n declare createAssessmentSection: InstanceType<typeof AssessmentsMixin>['createAssessmentSection'];\n declare createAssessmentQuestions: InstanceType<\n typeof AssessmentsMixin\n >['createAssessmentQuestions'];\n declare getAssessmentFormTemplate: InstanceType<\n typeof AssessmentsMixin\n >['getAssessmentFormTemplate'];\n\n // Workflows\n declare listWorkflows: InstanceType<typeof WorkflowsMixin>['listWorkflows'];\n declare updateWorkflowConfig: InstanceType<typeof WorkflowsMixin>['updateWorkflowConfig'];\n declare listEmailTemplates: InstanceType<typeof WorkflowsMixin>['listEmailTemplates'];\n}\n\napplyMixin(TranscendGraphQLClient, AdminMixin);\napplyMixin(TranscendGraphQLClient, DSRMixin);\napplyMixin(TranscendGraphQLClient, InventoryMixin);\napplyMixin(TranscendGraphQLClient, DiscoveryMixin);\napplyMixin(TranscendGraphQLClient, AssessmentsMixin);\napplyMixin(TranscendGraphQLClient, WorkflowsMixin);\n","import { toJsonSchemaCompat } from '@modelcontextprotocol/sdk/server/zod-json-schema-compat.js';\nimport { getAdminTools } from '@transcend-io/mcp-server-admin';\nimport { getAssessmentTools } from '@transcend-io/mcp-server-assessment';\nimport {\n createErrorResult,\n SimpleLogger,\n type ToolDefinition,\n type TranscendRestClient,\n} from '@transcend-io/mcp-server-base';\nimport { getConsentTools } from '@transcend-io/mcp-server-consent';\nimport { getDiscoveryTools } from '@transcend-io/mcp-server-discovery';\nimport { getDSRTools } from '@transcend-io/mcp-server-dsr';\nimport { getInventoryTools } from '@transcend-io/mcp-server-inventory';\nimport { getPreferenceTools } from '@transcend-io/mcp-server-preferences';\nimport { getWorkflowTools } from '@transcend-io/mcp-server-workflows';\n\nimport type { TranscendGraphQLClient } from './graphql-client.js';\n\nexport interface UmbrellaToolClients {\n /** REST client for Sombra API */\n rest: TranscendRestClient;\n /** Composed GraphQL client with all domain mixins */\n graphql: TranscendGraphQLClient;\n /** Admin-dashboard base URL used to build deep links */\n dashboardUrl: string;\n}\n\nexport class ToolRegistry {\n private tools: Map<string, ToolDefinition> = new Map();\n private jsonSchemaCache: Map<string, Record<string, unknown>> = new Map();\n private clients: UmbrellaToolClients;\n private logger = new SimpleLogger();\n\n constructor(clients: UmbrellaToolClients) {\n this.clients = clients;\n this.registerAllTools();\n }\n\n private registerAllTools(): void {\n this.registerToolsFromModule(getDSRTools(this.clients));\n this.registerToolsFromModule(getConsentTools(this.clients));\n this.registerToolsFromModule(getPreferenceTools(this.clients));\n this.registerToolsFromModule(getInventoryTools(this.clients));\n this.registerToolsFromModule(getDiscoveryTools(this.clients));\n this.registerToolsFromModule(getAssessmentTools(this.clients));\n this.registerToolsFromModule(getWorkflowTools(this.clients));\n this.registerToolsFromModule(getAdminTools(this.clients));\n }\n\n private registerToolsFromModule(tools: ToolDefinition[]): void {\n for (const tool of tools) {\n if (this.tools.has(tool.name)) {\n this.logger.warn('Duplicate tool name - skipping', { toolName: tool.name });\n continue;\n }\n this.tools.set(tool.name, tool);\n this.jsonSchemaCache.set(\n tool.name,\n toJsonSchemaCompat(tool.zodSchema as any) as Record<string, unknown>,\n );\n }\n }\n\n getToolList(): Array<{\n name: string;\n description: string;\n inputSchema: Record<string, unknown>;\n annotations: {\n readOnlyHint: boolean;\n destructiveHint: boolean;\n idempotentHint: boolean;\n };\n }> {\n return Array.from(this.tools.values()).map((tool) => ({\n name: tool.name,\n description: tool.description,\n inputSchema: this.jsonSchemaCache.get(tool.name) || { type: 'object', properties: {} },\n annotations: tool.annotations,\n }));\n }\n\n getTool(name: string): ToolDefinition | undefined {\n return this.tools.get(name);\n }\n\n async executeTool(name: string, args: Record<string, unknown>): Promise<unknown> {\n const tool = this.tools.get(name);\n if (!tool) {\n throw new Error(`Unknown tool: ${name}`);\n }\n\n const parseResult = tool.zodSchema.safeParse(args);\n if (!parseResult.success) {\n const issues = parseResult.error.issues\n .map((i: any) => `${i.path.join('.') || 'input'}: ${i.message}`)\n .join('; ');\n throw new Error(`Invalid input: ${issues}`);\n }\n\n try {\n return await tool.handler(parseResult.data);\n } catch (error) {\n return createErrorResult(error);\n }\n }\n\n getToolsByCategory(category: string): ToolDefinition[] {\n return Array.from(this.tools.values()).filter((tool) => tool.category === category);\n }\n\n getCategories(): string[] {\n const categories = new Set<string>();\n for (const tool of this.tools.values()) {\n categories.add(tool.category);\n }\n return Array.from(categories);\n }\n\n getAllTools(): ToolDefinition[] {\n return Array.from(this.tools.values());\n }\n\n getToolCount(): number {\n return this.tools.size;\n }\n}\n"],"mappings":"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"}
|