@transcend-io/mcp 0.7.1 → 0.8.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/dist/cli.mjs +2 -2
- package/dist/index.d.mts +17 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{oauth-scopes-uzulgUw_.mjs → oauth-scopes-Crj6iyN6.mjs} +32 -15
- package/dist/oauth-scopes-Crj6iyN6.mjs.map +1 -0
- package/package.json +12 -12
- package/dist/oauth-scopes-uzulgUw_.mjs.map +0 -1
package/dist/cli.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { n as ToolRegistry, r as TranscendGraphQLClient, t as UMBRELLA_OAUTH_SCOPES } from "./oauth-scopes-
|
|
2
|
+
import { n as ToolRegistry, r as TranscendGraphQLClient, t as UMBRELLA_OAUTH_SCOPES } from "./oauth-scopes-Crj6iyN6.mjs";
|
|
3
3
|
import { SimpleLogger, buildMcpServer, configureOAuthScopes, createTranscendRestClient, isOAuthModeEnabled, parseTransportArgs, readSombraEnvConfig, resolveMcpDashboardUrl, resolveMcpGraphqlUrl, resolveStdioStartupAuthOptional, runMcpHttp } from "@transcend-io/mcp-server-base";
|
|
4
4
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5
5
|
//#region package.json
|
|
6
|
-
var version = "0.
|
|
6
|
+
var version = "0.8.1";
|
|
7
7
|
//#endregion
|
|
8
8
|
//#region src/server-instructions.ts
|
|
9
9
|
/** MCP initialize instructions for the unified @transcend-io/mcp server. */
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AdminMixin } from "@transcend-io/mcp-server-admin";
|
|
2
2
|
import { AssessmentsMixin } from "@transcend-io/mcp-server-assessment";
|
|
3
|
-
import { AuthCredentials, Logger, ToolDefinition, TranscendGraphQLBase, TranscendRestClient } from "@transcend-io/mcp-server-base";
|
|
3
|
+
import { AuthCredentials, ClientCapabilityReport, Logger, ToolDefinition, TranscendGraphQLBase, TranscendRestClient } from "@transcend-io/mcp-server-base";
|
|
4
4
|
import { DiscoveryMixin } from "@transcend-io/mcp-server-discovery";
|
|
5
5
|
import { DSRMixin } from "@transcend-io/mcp-server-dsr";
|
|
6
6
|
import { InventoryMixin } from "@transcend-io/mcp-server-inventory";
|
|
@@ -67,7 +67,18 @@ declare class ToolRegistry {
|
|
|
67
67
|
constructor(clients: UmbrellaToolClients);
|
|
68
68
|
private registerAllTools;
|
|
69
69
|
private registerToolsFromModule;
|
|
70
|
-
|
|
70
|
+
/**
|
|
71
|
+
* Tool descriptors as a host would see them.
|
|
72
|
+
*
|
|
73
|
+
* The serving path builds descriptors in `buildMcpServer` rather than here, so
|
|
74
|
+
* this method exists for callers embedding the registry directly. It still
|
|
75
|
+
* resolves capability variants and carries `_meta`, because a descriptor list
|
|
76
|
+
* that quietly disagreed with what the server actually serves would be worse
|
|
77
|
+
* than no method at all.
|
|
78
|
+
*/
|
|
79
|
+
getToolList(/** Capabilities of the host being served; defaults to a host with none */
|
|
80
|
+
|
|
81
|
+
client?: ClientCapabilityReport): Array<{
|
|
71
82
|
name: string;
|
|
72
83
|
description: string;
|
|
73
84
|
inputSchema: Record<string, unknown>;
|
|
@@ -76,9 +87,12 @@ declare class ToolRegistry {
|
|
|
76
87
|
destructiveHint: boolean;
|
|
77
88
|
idempotentHint: boolean;
|
|
78
89
|
};
|
|
90
|
+
_meta?: Record<string, unknown>;
|
|
79
91
|
}>;
|
|
80
92
|
getTool(name: string): ToolDefinition | undefined;
|
|
81
|
-
executeTool(name: string, args: Record<string, unknown
|
|
93
|
+
executeTool(name: string, args: Record<string, unknown>, /** Capabilities of the host being served; defaults to a host with none */
|
|
94
|
+
|
|
95
|
+
client?: ClientCapabilityReport): Promise<unknown>;
|
|
82
96
|
getToolsByCategory(category: string): ToolDefinition[];
|
|
83
97
|
getCategories(): string[];
|
|
84
98
|
getAllTools(): ToolDefinition[];
|
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","../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;;;
|
|
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;;;UCtEjC,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,QAYA,uBAAA;EDxB+B;;;;;;;;;EC+CvC,WAAA,CDxC0C;;EC0CxC,MAAA,GAAQ,sBAAA,GACP,KAAA;IACD,IAAA;IACA,WAAA;IACA,WAAA,EAAa,MAAA;IACb,WAAA;MACE,YAAA;MACA,eAAA;MACA,cAAA;IAAA;IAEF,KAAA,GAAQ,MAAA;EAAA;EAkBV,OAAA,CAAQ,IAAA,WAAe,cAAA;EAIjB,WAAA,CACJ,IAAA,UACA,IAAA,EAAM,MAAA,mBDjEoC;;ECmE1C,MAAA,GAAQ,sBAAA,GACP,OAAA;EAwBH,kBAAA,CAAmB,QAAA,WAAmB,cAAA;EAItC,aAAA,CAAA;EAQA,WAAA,CAAA,GAAe,cAAA;EAIf,YAAA,CAAA;AAAA;;;;cCnJW,qBAAA"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as ToolRegistry, r as TranscendGraphQLClient, t as UMBRELLA_OAUTH_SCOPES } from "./oauth-scopes-
|
|
1
|
+
import { n as ToolRegistry, r as TranscendGraphQLClient, t as UMBRELLA_OAUTH_SCOPES } from "./oauth-scopes-Crj6iyN6.mjs";
|
|
2
2
|
export { ToolRegistry, TranscendGraphQLClient, UMBRELLA_OAUTH_SCOPES };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ADMIN_OAUTH_SCOPES, AdminMixin, getAdminTools } from "@transcend-io/mcp-server-admin";
|
|
2
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";
|
|
3
|
+
import { EMPTY_CAPABILITY_REPORT, SimpleLogger, TranscendGraphQLBase, createErrorResult, expandToolsForClient, isVisibleToModel, mergeOAuthScopes, resolveToolVariant } from "@transcend-io/mcp-server-base";
|
|
4
4
|
import { DISCOVERY_OAUTH_SCOPES, DiscoveryMixin, getDiscoveryTools } from "@transcend-io/mcp-server-discovery";
|
|
5
5
|
import { DSRMixin, DSR_OAUTH_SCOPES, getDSRTools } from "@transcend-io/mcp-server-dsr";
|
|
6
6
|
import { INVENTORY_OAUTH_SCOPES, InventoryMixin, getInventoryTools } from "@transcend-io/mcp-server-inventory";
|
|
@@ -60,23 +60,40 @@ var ToolRegistry = class {
|
|
|
60
60
|
this.jsonSchemaCache.set(tool.name, toJsonSchemaCompat(tool.zodSchema));
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
63
|
+
/**
|
|
64
|
+
* Tool descriptors as a host would see them.
|
|
65
|
+
*
|
|
66
|
+
* The serving path builds descriptors in `buildMcpServer` rather than here, so
|
|
67
|
+
* this method exists for callers embedding the registry directly. It still
|
|
68
|
+
* resolves capability variants and carries `_meta`, because a descriptor list
|
|
69
|
+
* that quietly disagreed with what the server actually serves would be worse
|
|
70
|
+
* than no method at all.
|
|
71
|
+
*/
|
|
72
|
+
getToolList(client = EMPTY_CAPABILITY_REPORT) {
|
|
73
|
+
return expandToolsForClient(Array.from(this.tools.values()), client).filter((tool) => isVisibleToModel(tool)).map((tool) => {
|
|
74
|
+
const resourceUri = tool.ui?.resource.uri;
|
|
75
|
+
return {
|
|
76
|
+
name: tool.name,
|
|
77
|
+
description: tool.description,
|
|
78
|
+
inputSchema: this.jsonSchemaCache.get(tool.name) || {
|
|
79
|
+
type: "object",
|
|
80
|
+
properties: {}
|
|
81
|
+
},
|
|
82
|
+
annotations: tool.annotations,
|
|
83
|
+
...resourceUri && { _meta: {
|
|
84
|
+
ui: { resourceUri },
|
|
85
|
+
"ui/resourceUri": resourceUri
|
|
86
|
+
} }
|
|
87
|
+
};
|
|
88
|
+
});
|
|
73
89
|
}
|
|
74
90
|
getTool(name) {
|
|
75
91
|
return this.tools.get(name);
|
|
76
92
|
}
|
|
77
|
-
async executeTool(name, args) {
|
|
78
|
-
const
|
|
79
|
-
if (!
|
|
93
|
+
async executeTool(name, args, client = EMPTY_CAPABILITY_REPORT) {
|
|
94
|
+
const registered = this.tools.get(name);
|
|
95
|
+
if (!registered) throw new Error(`Unknown tool: ${name}`);
|
|
96
|
+
const tool = resolveToolVariant(registered, client);
|
|
80
97
|
const parseResult = tool.zodSchema.safeParse(args);
|
|
81
98
|
if (!parseResult.success) {
|
|
82
99
|
const issues = parseResult.error.issues.map((i) => `${i.path.join(".") || "input"}: ${i.message}`).join("; ");
|
|
@@ -110,4 +127,4 @@ const UMBRELLA_OAUTH_SCOPES = mergeOAuthScopes(ADMIN_OAUTH_SCOPES, ASSESSMENT_OA
|
|
|
110
127
|
//#endregion
|
|
111
128
|
export { ToolRegistry as n, TranscendGraphQLClient as r, UMBRELLA_OAUTH_SCOPES as t };
|
|
112
129
|
|
|
113
|
-
//# sourceMappingURL=oauth-scopes-
|
|
130
|
+
//# sourceMappingURL=oauth-scopes-Crj6iyN6.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-scopes-Crj6iyN6.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 EMPTY_CAPABILITY_REPORT,\n expandToolsForClient,\n isVisibleToModel,\n resolveToolVariant,\n SimpleLogger,\n type ClientCapabilityReport,\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 { getDocsTools } from '@transcend-io/mcp-server-docs';\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(getDocsTools(this.clients));\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 /**\n * Tool descriptors as a host would see them.\n *\n * The serving path builds descriptors in `buildMcpServer` rather than here, so\n * this method exists for callers embedding the registry directly. It still\n * resolves capability variants and carries `_meta`, because a descriptor list\n * that quietly disagreed with what the server actually serves would be worse\n * than no method at all.\n */\n getToolList(\n /** Capabilities of the host being served; defaults to a host with none */\n client: ClientCapabilityReport = EMPTY_CAPABILITY_REPORT,\n ): 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 _meta?: Record<string, unknown>;\n }> {\n return expandToolsForClient(Array.from(this.tools.values()), client)\n .filter((tool) => isVisibleToModel(tool))\n .map((tool) => {\n const resourceUri = tool.ui?.resource.uri;\n return {\n name: tool.name,\n description: tool.description,\n inputSchema: this.jsonSchemaCache.get(tool.name) || { type: 'object', properties: {} },\n annotations: tool.annotations,\n ...(resourceUri && {\n _meta: { ui: { resourceUri }, 'ui/resourceUri': resourceUri },\n }),\n };\n });\n }\n\n getTool(name: string): ToolDefinition | undefined {\n return this.tools.get(name);\n }\n\n async executeTool(\n name: string,\n args: Record<string, unknown>,\n /** Capabilities of the host being served; defaults to a host with none */\n client: ClientCapabilityReport = EMPTY_CAPABILITY_REPORT,\n ): Promise<unknown> {\n const registered = this.tools.get(name);\n if (!registered) {\n throw new Error(`Unknown tool: ${name}`);\n }\n\n // Resolve so the handler that runs matches the descriptor getToolList emitted.\n const tool = resolveToolVariant(registered, client);\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":";;;;;;;;;;;;AAcA,SAAS,WAAW,QAAqB,OAA0B;AACjE,QAAO,oBAAoB,MAAM,UAAU,CAAC,SAAS,SAAS;AAC5D,MAAI,SAAS,cAAe;EAC5B,MAAM,aAAa,OAAO,yBAAyB,MAAM,WAAW,KAAK;AACzE,MAAI,WACF,QAAO,eAAe,OAAO,WAAW,MAAM,WAAW;GAE3D;;AAGJ,IAAa,yBAAb,cAA4C,qBAAqB;CAC/D,YAAY,MAA8B,SAAkB,QAAiB;AAC3E,QAAM,MAAM,SAAS,OAAO;;;AAuEhC,WAAW,wBAAwB,WAAW;AAC9C,WAAW,wBAAwB,SAAS;AAC5C,WAAW,wBAAwB,eAAe;AAClD,WAAW,wBAAwB,eAAe;AAClD,WAAW,wBAAwB,iBAAiB;AACpD,WAAW,wBAAwB,eAAe;;;ACrElD,IAAa,eAAb,MAA0B;CACxB,wBAA6C,IAAI,KAAK;CACtD,kCAAgE,IAAI,KAAK;CACzE;CACA,SAAiB,IAAI,cAAc;CAEnC,YAAY,SAA8B;AACxC,OAAK,UAAU;AACf,OAAK,kBAAkB;;CAGzB,mBAAiC;AAC/B,OAAK,wBAAwB,aAAa,KAAK,QAAQ,CAAC;AACxD,OAAK,wBAAwB,YAAY,KAAK,QAAQ,CAAC;AACvD,OAAK,wBAAwB,gBAAgB,KAAK,QAAQ,CAAC;AAC3D,OAAK,wBAAwB,mBAAmB,KAAK,QAAQ,CAAC;AAC9D,OAAK,wBAAwB,kBAAkB,KAAK,QAAQ,CAAC;AAC7D,OAAK,wBAAwB,kBAAkB,KAAK,QAAQ,CAAC;AAC7D,OAAK,wBAAwB,mBAAmB,KAAK,QAAQ,CAAC;AAC9D,OAAK,wBAAwB,iBAAiB,KAAK,QAAQ,CAAC;AAC5D,OAAK,wBAAwB,cAAc,KAAK,QAAQ,CAAC;;CAG3D,wBAAgC,OAA+B;AAC7D,OAAK,MAAM,QAAQ,OAAO;AACxB,OAAI,KAAK,MAAM,IAAI,KAAK,KAAK,EAAE;AAC7B,SAAK,OAAO,KAAK,kCAAkC,EAAE,UAAU,KAAK,MAAM,CAAC;AAC3E;;AAEF,QAAK,MAAM,IAAI,KAAK,MAAM,KAAK;AAC/B,QAAK,gBAAgB,IACnB,KAAK,MACL,mBAAmB,KAAK,UAAiB,CAC1C;;;;;;;;;;;;CAaL,YAEE,SAAiC,yBAWhC;AACD,SAAO,qBAAqB,MAAM,KAAK,KAAK,MAAM,QAAQ,CAAC,EAAE,OAAO,CACjE,QAAQ,SAAS,iBAAiB,KAAK,CAAC,CACxC,KAAK,SAAS;GACb,MAAM,cAAc,KAAK,IAAI,SAAS;AACtC,UAAO;IACL,MAAM,KAAK;IACX,aAAa,KAAK;IAClB,aAAa,KAAK,gBAAgB,IAAI,KAAK,KAAK,IAAI;KAAE,MAAM;KAAU,YAAY,EAAE;KAAE;IACtF,aAAa,KAAK;IAClB,GAAI,eAAe,EACjB,OAAO;KAAE,IAAI,EAAE,aAAa;KAAE,kBAAkB;KAAa,EAC9D;IACF;IACD;;CAGN,QAAQ,MAA0C;AAChD,SAAO,KAAK,MAAM,IAAI,KAAK;;CAG7B,MAAM,YACJ,MACA,MAEA,SAAiC,yBACf;EAClB,MAAM,aAAa,KAAK,MAAM,IAAI,KAAK;AACvC,MAAI,CAAC,WACH,OAAM,IAAI,MAAM,iBAAiB,OAAO;EAI1C,MAAM,OAAO,mBAAmB,YAAY,OAAO;EAEnD,MAAM,cAAc,KAAK,UAAU,UAAU,KAAK;AAClD,MAAI,CAAC,YAAY,SAAS;GACxB,MAAM,SAAS,YAAY,MAAM,OAC9B,KAAK,MAAW,GAAG,EAAE,KAAK,KAAK,IAAI,IAAI,QAAQ,IAAI,EAAE,UAAU,CAC/D,KAAK,KAAK;AACb,SAAM,IAAI,MAAM,kBAAkB,SAAS;;AAG7C,MAAI;AACF,UAAO,MAAM,KAAK,QAAQ,YAAY,KAAK;WACpC,OAAO;AACd,UAAO,kBAAkB,MAAM;;;CAInC,mBAAmB,UAAoC;AACrD,SAAO,MAAM,KAAK,KAAK,MAAM,QAAQ,CAAC,CAAC,QAAQ,SAAS,KAAK,aAAa,SAAS;;CAGrF,gBAA0B;EACxB,MAAM,6BAAa,IAAI,KAAa;AACpC,OAAK,MAAM,QAAQ,KAAK,MAAM,QAAQ,CACpC,YAAW,IAAI,KAAK,SAAS;AAE/B,SAAO,MAAM,KAAK,WAAW;;CAG/B,cAAgC;AAC9B,SAAO,MAAM,KAAK,KAAK,MAAM,QAAQ,CAAC;;CAGxC,eAAuB;AACrB,SAAO,KAAK,MAAM;;;;;;ACpJtB,MAAa,wBAAwB,iBACnC,oBACA,yBACA,sBACA,wBACA,kBACA,wBACA,yBACA,sBACD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@transcend-io/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.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,16 +32,16 @@
|
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
34
34
|
"zod": "^4.3.6",
|
|
35
|
-
"@transcend-io/mcp-server-admin": "0.5.
|
|
36
|
-
"@transcend-io/mcp-server-assessment": "0.5.
|
|
37
|
-
"@transcend-io/mcp-server-base": "0.
|
|
38
|
-
"@transcend-io/mcp-server-consent": "0.6.
|
|
39
|
-
"@transcend-io/mcp-server-discovery": "0.5.
|
|
40
|
-
"@transcend-io/mcp-server-docs": "0.3.
|
|
41
|
-
"@transcend-io/mcp-server-dsr": "0.5.
|
|
42
|
-
"@transcend-io/mcp-server-inventory": "0.5.
|
|
43
|
-
"@transcend-io/mcp-server-preferences": "0.5.
|
|
44
|
-
"@transcend-io/mcp-server-workflows": "0.5.
|
|
35
|
+
"@transcend-io/mcp-server-admin": "0.5.3",
|
|
36
|
+
"@transcend-io/mcp-server-assessment": "0.5.3",
|
|
37
|
+
"@transcend-io/mcp-server-base": "0.10.0",
|
|
38
|
+
"@transcend-io/mcp-server-consent": "0.6.3",
|
|
39
|
+
"@transcend-io/mcp-server-discovery": "0.5.3",
|
|
40
|
+
"@transcend-io/mcp-server-docs": "0.3.7",
|
|
41
|
+
"@transcend-io/mcp-server-dsr": "0.5.3",
|
|
42
|
+
"@transcend-io/mcp-server-inventory": "0.5.3",
|
|
43
|
+
"@transcend-io/mcp-server-preferences": "0.5.3",
|
|
44
|
+
"@transcend-io/mcp-server-workflows": "0.5.3"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@arethetypeswrong/cli": "^0.18.2",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"tsdown": "^0.21.2",
|
|
51
51
|
"typescript": "^6.0.0",
|
|
52
52
|
"vitest": "^4.0.18",
|
|
53
|
-
"@transcend-io/privacy-types": "5.
|
|
53
|
+
"@transcend-io/privacy-types": "5.10.1"
|
|
54
54
|
},
|
|
55
55
|
"engines": {
|
|
56
56
|
"node": ">=22.12.0"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"oauth-scopes-uzulgUw_.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 { getDocsTools } from '@transcend-io/mcp-server-docs';\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(getDocsTools(this.clients));\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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"}
|