@questpie/mcp 3.15.2 → 3.17.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 +150 -6
- package/dist/create-server-CEWFf041.mjs +2394 -0
- package/dist/{index-Cxta5KOn.d.mts → index-DlBFWTIg.d.mts} +28 -23
- package/dist/index.d.mts +91 -47
- package/dist/index.mjs +92 -5
- package/dist/mcp-CuJEhynp.mjs +350 -0
- package/dist/modules/mcp.d.mts +1 -1
- package/dist/modules/mcp.mjs +1 -1
- package/dist/{plugin-BJ6gELRj.mjs → plugin-BZQe1pji.mjs} +1 -1
- package/dist/plugin.mjs +1 -1
- package/dist/{stdio-qyQFVEyU.mjs → stdio-CgIPiPUb.mjs} +1 -1
- package/dist/stdio-YoM70-42.d.mts +323 -0
- package/dist/stdio.d.mts +1 -1
- package/dist/stdio.mjs +1 -1
- package/package.json +5 -4
- package/dist/create-server-DIvtVlma.mjs +0 -1014
- package/dist/mcp-snyVygDQ.mjs +0 -168
- package/dist/stdio-t_9rKayH.d.mts +0 -154
|
@@ -1,23 +1,24 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as questpie1 from "questpie";
|
|
2
2
|
import { RouteDefinition, RouteParamsFromKey } from "questpie/types";
|
|
3
3
|
|
|
4
4
|
//#region src/server/modules/mcp/routes/mcp.d.ts
|
|
5
|
-
declare const _default$4:
|
|
5
|
+
declare const _default$4: questpie1.RawRouteDefinition<questpie1.JsonRouteParams>;
|
|
6
6
|
//#endregion
|
|
7
7
|
//#region src/server/modules/mcp/routes/mcp.delete.d.ts
|
|
8
|
-
declare const _default$3:
|
|
8
|
+
declare const _default$3: questpie1.RawRouteDefinition<questpie1.JsonRouteParams>;
|
|
9
9
|
//#endregion
|
|
10
10
|
//#region src/server/modules/mcp/routes/mcp.get.d.ts
|
|
11
|
-
declare const _default$2:
|
|
11
|
+
declare const _default$2: questpie1.RawRouteDefinition<questpie1.JsonRouteParams>;
|
|
12
12
|
//#endregion
|
|
13
13
|
//#region src/server/modules/mcp/routes/mcp.options.d.ts
|
|
14
|
-
declare const _default$1:
|
|
14
|
+
declare const _default$1: questpie1.RawRouteDefinition<questpie1.JsonRouteParams>;
|
|
15
15
|
//#endregion
|
|
16
16
|
//#region src/server/modules/mcp/plugin.d.ts
|
|
17
|
-
declare const _default:
|
|
17
|
+
declare const _default: questpie1.CodegenPlugin;
|
|
18
18
|
//#endregion
|
|
19
19
|
//#region src/server/modules/mcp/.generated/module.d.ts
|
|
20
20
|
type McpCollections = Record<never, never>;
|
|
21
|
+
type McpChannels = Record<never, never>;
|
|
21
22
|
type McpGlobals = Record<never, never>;
|
|
22
23
|
type McpJobs = Record<never, never>;
|
|
23
24
|
type McpRoutes = {
|
|
@@ -36,23 +37,27 @@ type McpRoutes = {
|
|
|
36
37
|
};
|
|
37
38
|
type McpFieldTypes = Record<never, never>;
|
|
38
39
|
type McpMcpTools = Record<never, never>;
|
|
39
|
-
type McpModule = {
|
|
40
|
-
name: "questpie-mcp";
|
|
41
|
-
routes: McpRoutes;
|
|
42
|
-
collections: McpCollections;
|
|
43
|
-
globals: McpGlobals;
|
|
44
|
-
jobs: McpJobs;
|
|
45
|
-
fieldTypes: McpFieldTypes;
|
|
46
|
-
mcpTools: McpMcpTools;
|
|
47
|
-
messages: Record<never, never>;
|
|
48
|
-
services: Record<never, never>;
|
|
49
|
-
emails: Record<never, never>;
|
|
50
|
-
migrations: readonly unknown[];
|
|
51
|
-
seeds: readonly unknown[];
|
|
52
|
-
plugin: typeof _default;
|
|
53
|
-
};
|
|
54
40
|
//#endregion
|
|
55
41
|
//#region src/server/modules/mcp/index.d.ts
|
|
56
|
-
|
|
42
|
+
type McpModule = typeof mcpModule;
|
|
43
|
+
declare const mcpModule: {
|
|
44
|
+
readonly oauthScopeCatalogs: {
|
|
45
|
+
readonly mcp: questpie1.OAuthScopeCatalogContributor;
|
|
46
|
+
};
|
|
47
|
+
readonly name: "questpie-mcp";
|
|
48
|
+
readonly routes: McpRoutes;
|
|
49
|
+
readonly collections: McpCollections;
|
|
50
|
+
readonly channels: McpChannels;
|
|
51
|
+
readonly globals: McpGlobals;
|
|
52
|
+
readonly jobs: McpJobs;
|
|
53
|
+
readonly fieldTypes: McpFieldTypes;
|
|
54
|
+
readonly mcpTools: McpMcpTools;
|
|
55
|
+
readonly messages: Record<never, never>;
|
|
56
|
+
readonly services: Record<never, never>;
|
|
57
|
+
readonly emails: Record<never, never>;
|
|
58
|
+
readonly migrations: readonly unknown[];
|
|
59
|
+
readonly seeds: readonly unknown[];
|
|
60
|
+
readonly plugin: typeof _default;
|
|
61
|
+
};
|
|
57
62
|
//#endregion
|
|
58
|
-
export {
|
|
63
|
+
export { mcpModule as n, McpModule as t };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,63 +1,31 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { _ as
|
|
1
|
+
import { n as mcpModule } from "./index-DlBFWTIg.mjs";
|
|
2
|
+
import { A as McpWorkloadAuthorizer, B as WorkloadMcpServerOptions, C as McpToolConfig, D as McpWorkloadAuditEvent, E as McpTransportKind, F as McpWorkloadHandoffInput, I as McpWorkloadRequirement, L as McpWorkloadToolFacts, M as McpWorkloadContextBindingInput, N as McpWorkloadExecutionControl, O as McpWorkloadAuthorization, P as McpWorkloadHandoff, R as McpWorkloadToolKind, S as McpStdioConfig, T as McpToolHandlerArgs, _ as McpProgrammaticToolResult, a as McpAccessRule, b as McpResourcesConfig, c as McpCrudConfig, d as McpExecutionDiagnosticEvent, f as McpExecutionLimits, g as McpProgrammaticTool, h as McpProgrammaticRequestOptions, i as McpAccessMode, j as McpWorkloadContextBinder, k as McpWorkloadAuthorizationRequest, l as McpEntityPolicy, m as McpHttpConfig, n as QuestpieApp, o as McpAccessRuleContext, p as McpExecutionOptions, r as mcpPublicErrorCode, s as McpConfig, t as startStdioServer, u as McpExecutionConfig, v as McpPublicErrorCode, w as McpToolDefinition, x as McpRoutesConfig, y as McpRequiredScopes, z as McpWorkloadToolPort } from "./stdio-YoM70-42.mjs";
|
|
3
3
|
import { t as mcpPlugin } from "./plugin-CMR-wkeP.mjs";
|
|
4
|
-
import { AppContext, RequestContext, ScopeOperationKind, defaultOperationScope } from "questpie";
|
|
5
|
-
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
4
|
+
import { AppContext, Questpie, RequestContext, ScopeOperationKind, defaultOperationScope, introspectRoutes } from "questpie";
|
|
6
5
|
import { z } from "zod";
|
|
6
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
7
7
|
|
|
8
8
|
//#region src/server/create-server.d.ts
|
|
9
9
|
declare function createMcpServer(app: QuestpieApp, options?: McpExecutionOptions): Promise<McpServer>;
|
|
10
|
+
declare function createWorkloadMcpServer(app: QuestpieApp, options: WorkloadMcpServerOptions): Promise<McpServer>;
|
|
10
11
|
//#endregion
|
|
11
|
-
//#region src/server/
|
|
12
|
-
declare function mcpConfig<TConfig extends McpConfig>(config: TConfig): TConfig;
|
|
13
|
-
//#endregion
|
|
14
|
-
//#region src/server/mcp-tool.d.ts
|
|
15
|
-
declare class McpToolBuilder<TInputSchema extends z.ZodTypeAny, TOutputSchema extends z.ZodTypeAny> {
|
|
16
|
-
private readonly name;
|
|
17
|
-
private readonly config;
|
|
18
|
-
constructor(name: string, config: McpToolConfig<TInputSchema, TOutputSchema>);
|
|
19
|
-
handler(handler: (args: McpToolHandlerArgs<z.infer<TInputSchema>>) => ReturnType<McpToolDefinition<TInputSchema, TOutputSchema>["handler"]>): McpToolDefinition<TInputSchema, TOutputSchema>;
|
|
20
|
-
}
|
|
12
|
+
//#region src/server/workload-tool-port.d.ts
|
|
21
13
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* framework auto-generates are the same shape.
|
|
26
|
-
*
|
|
27
|
-
* `config` mirrors the MCP tool contract: `inputSchema`/`outputSchema` (Zod),
|
|
28
|
-
* `title`/`description`/`annotations` for discovery, plus the two QUESTPIE
|
|
29
|
-
* authorization hooks that compose exactly like the built-in tools:
|
|
30
|
-
* - `access` — an {@link McpAccessRule} run against the caller's transport /
|
|
31
|
-
* accessMode / session (and, for an OAuth caller, its scopes). Same RBAC-style
|
|
32
|
-
* gate the CRUD tools use.
|
|
33
|
-
* - `scopes` — the OAuth scopes an `oauth` caller must hold ({@link McpToolConfig.scopes}).
|
|
34
|
-
* Custom tools have no default scope mapping (unlike CRUD, there is no
|
|
35
|
-
* resource/operation to derive one from), so an omitted value requires no
|
|
36
|
-
* scope. The shipped scope gate ({@link scopeGateAllows}) enforces this at both
|
|
37
|
-
* `tools/list` (hidden) and `tools/call` (denied); `system`/`user` callers
|
|
38
|
-
* carry no scopes and skip it, so the effective bound is always `scopes ∩ RBAC`.
|
|
39
|
-
*
|
|
40
|
-
* @example
|
|
41
|
-
* ```ts
|
|
42
|
-
* export const ping = mcpTool("ops.ping", {
|
|
43
|
-
* description: "Health probe",
|
|
44
|
-
* inputSchema: z.object({}),
|
|
45
|
-
* scopes: "routes:ops/ping:invoke", // only OAuth callers holding this scope
|
|
46
|
-
* }).handler(async () => ({ content: [{ type: "text", text: "pong" }] }));
|
|
47
|
-
* ```
|
|
14
|
+
* Programmatic, custom-tool-only workload port. This is deliberately not a
|
|
15
|
+
* general in-process MCP client: CRUD, routes, resources, and transport
|
|
16
|
+
* authority are absent by construction.
|
|
48
17
|
*/
|
|
49
|
-
declare function
|
|
18
|
+
declare function createWorkloadMcpToolPort(app: QuestpieApp, options: WorkloadMcpServerOptions): McpWorkloadToolPort;
|
|
50
19
|
//#endregion
|
|
51
20
|
//#region src/server/policy.d.ts
|
|
52
21
|
type EntityKind = "collection" | "global" | "route";
|
|
53
22
|
interface ResolvedMcpPolicy {
|
|
54
23
|
expose: boolean;
|
|
55
|
-
read?: boolean | McpAccessRule;
|
|
56
|
-
write?: boolean | McpAccessRule;
|
|
57
|
-
delete?: boolean | McpAccessRule;
|
|
58
24
|
operations: Record<string, boolean | McpAccessRule>;
|
|
59
25
|
requiredScopes?: McpRequiredScopes;
|
|
60
26
|
operationScopes: Record<string, McpRequiredScopes>;
|
|
27
|
+
workload?: McpWorkloadRequirement;
|
|
28
|
+
operationWorkloads: Record<string, McpWorkloadRequirement>;
|
|
61
29
|
fields?: {
|
|
62
30
|
include?: string[];
|
|
63
31
|
exclude?: string[];
|
|
@@ -85,7 +53,7 @@ declare function requiredScopesForOperation(policy: ResolvedMcpPolicy, kind: Ent
|
|
|
85
53
|
* is not OAuth-authenticated. Reads `ctx.principal` (populated by MO6): only the
|
|
86
54
|
* `oauth` principal carries `scopes`; `user` and `system` do not.
|
|
87
55
|
*/
|
|
88
|
-
declare function scopesFromContext(ctx: AppContext & Partial<RequestContext>): string[] | undefined;
|
|
56
|
+
declare function scopesFromContext(ctx: AppContext & Partial<RequestContext>): string[] | undefined | null;
|
|
89
57
|
/**
|
|
90
58
|
* The OAuth scope gate (MO8, extended by the umbrella model — LOCKED #2).
|
|
91
59
|
*
|
|
@@ -117,6 +85,82 @@ declare function scopesFromContext(ctx: AppContext & Partial<RequestContext>): s
|
|
|
117
85
|
* the collection/global `.access()` RBAC independently, and all must pass. The
|
|
118
86
|
* effective `oauth` permission is therefore `scopes ∩ RBAC`.
|
|
119
87
|
*/
|
|
120
|
-
declare function scopeGateAllows(heldScopes: string[] | undefined, required: string[]): boolean;
|
|
88
|
+
declare function scopeGateAllows(heldScopes: string[] | undefined | null, required: string[]): boolean;
|
|
89
|
+
//#endregion
|
|
90
|
+
//#region src/server/catalog.d.ts
|
|
91
|
+
interface ResolvedMcpEntityCatalogEntry {
|
|
92
|
+
policy: ResolvedMcpPolicy;
|
|
93
|
+
operations: readonly string[];
|
|
94
|
+
}
|
|
95
|
+
interface ResolvedMcpRouteCatalogEntry extends ResolvedMcpEntityCatalogEntry {
|
|
96
|
+
route: ReturnType<typeof introspectRoutes>[number];
|
|
97
|
+
toolName: string;
|
|
98
|
+
}
|
|
99
|
+
interface ResolvedMcpCustomToolCatalogEntry {
|
|
100
|
+
tool: McpToolDefinition;
|
|
101
|
+
}
|
|
102
|
+
interface ResolvedMcpCatalog {
|
|
103
|
+
collections: ReadonlyMap<string, ResolvedMcpEntityCatalogEntry>;
|
|
104
|
+
globals: ReadonlyMap<string, ResolvedMcpEntityCatalogEntry>;
|
|
105
|
+
routes: ReadonlyMap<string, ResolvedMcpRouteCatalogEntry>;
|
|
106
|
+
customTools: ReadonlyMap<string, ResolvedMcpCustomToolCatalogEntry>;
|
|
107
|
+
resources: {
|
|
108
|
+
collections: ReadonlySet<string>;
|
|
109
|
+
globals: ReadonlySet<string>;
|
|
110
|
+
routes: ReadonlySet<string>;
|
|
111
|
+
};
|
|
112
|
+
oauth: {
|
|
113
|
+
scopes: readonly string[];
|
|
114
|
+
scopesSupported: readonly string[];
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
type CatalogApp = Pick<Questpie<any>, "getCollections" | "getGlobals"> & {
|
|
118
|
+
state?: {
|
|
119
|
+
mcpTools?: Record<string, unknown>;
|
|
120
|
+
} & Record<string, unknown>;
|
|
121
|
+
config?: Questpie<any>["config"];
|
|
122
|
+
};
|
|
123
|
+
declare function resolveMcpCatalog(app: CatalogApp, config: McpConfig): ResolvedMcpCatalog;
|
|
124
|
+
//#endregion
|
|
125
|
+
//#region src/server/config.d.ts
|
|
126
|
+
declare function mcpConfig<TConfig extends McpConfig>(config: TConfig): TConfig;
|
|
127
|
+
//#endregion
|
|
128
|
+
//#region src/server/mcp-tool.d.ts
|
|
129
|
+
declare class McpToolBuilder<TInputSchema extends z.ZodTypeAny, TOutputSchema extends z.ZodTypeAny> {
|
|
130
|
+
private readonly name;
|
|
131
|
+
private readonly config;
|
|
132
|
+
constructor(name: string, config: McpToolConfig<TInputSchema, TOutputSchema>);
|
|
133
|
+
handler(handler: (args: McpToolHandlerArgs<z.infer<TInputSchema>>) => ReturnType<McpToolDefinition<TInputSchema, TOutputSchema>["handler"]>): McpToolDefinition<TInputSchema, TOutputSchema>;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Define a custom MCP tool, contributed by a module the same way collections and
|
|
137
|
+
* routes are (via `ModuleDefinition.mcpTools`). `mcpTool(name, config).handler(fn)`
|
|
138
|
+
* returns a frozen, branded {@link McpToolDefinition}; the CRUD/route tools the
|
|
139
|
+
* framework auto-generates are the same shape.
|
|
140
|
+
*
|
|
141
|
+
* `config` mirrors the MCP tool contract: `inputSchema`/`outputSchema` (Zod),
|
|
142
|
+
* `title`/`description`/`annotations` for discovery, plus the two QUESTPIE
|
|
143
|
+
* authorization hooks that compose exactly like the built-in tools:
|
|
144
|
+
* - `access` — required explicit opt-in and an {@link McpAccessRule} run against the caller's transport /
|
|
145
|
+
* accessMode / session (and, for an OAuth caller, its scopes). Same RBAC-style
|
|
146
|
+
* gate the CRUD tools use.
|
|
147
|
+
* - `scopes` — the OAuth scopes an `oauth` caller must hold ({@link McpToolConfig.scopes}).
|
|
148
|
+
* Custom tools have no default scope mapping (unlike CRUD, there is no
|
|
149
|
+
* resource/operation to derive one from), so it is required; use `false` for
|
|
150
|
+
* an explicit no-OAuth-scope policy. The shipped scope gate ({@link scopeGateAllows}) enforces this at both
|
|
151
|
+
* `tools/list` (hidden) and `tools/call` (denied); `system`/`user` callers
|
|
152
|
+
* carry no scopes and skip it, so the effective bound is always `scopes ∩ RBAC`.
|
|
153
|
+
*
|
|
154
|
+
* @example
|
|
155
|
+
* ```ts
|
|
156
|
+
* export const ping = mcpTool("ops.ping", {
|
|
157
|
+
* access: ({ session }) => !!session,
|
|
158
|
+
* description: "Health probe",
|
|
159
|
+
* inputSchema: z.object({}),
|
|
160
|
+
* scopes: "routes:ops/ping:invoke", // only OAuth callers holding this scope
|
|
161
|
+
* }).handler(async () => ({ content: [{ type: "text", text: "pong" }] }));
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
164
|
+
declare function mcpTool<TInputSchema extends z.ZodTypeAny = z.ZodTypeAny, TOutputSchema extends z.ZodTypeAny = z.ZodTypeAny>(name: string, config: McpToolConfig<TInputSchema, TOutputSchema>): McpToolBuilder<TInputSchema, TOutputSchema>;
|
|
121
165
|
//#endregion
|
|
122
|
-
export { type McpAccessMode, type McpAccessRule, type McpAccessRuleContext, type McpConfig, type McpCrudConfig, type
|
|
166
|
+
export { type McpAccessMode, type McpAccessRule, type McpAccessRuleContext, type McpConfig, type McpCrudConfig, type McpEntityPolicy, type McpExecutionConfig, type McpExecutionDiagnosticEvent, type McpExecutionLimits, type McpExecutionOptions, type McpHttpConfig, type McpProgrammaticRequestOptions, type McpProgrammaticTool, type McpProgrammaticToolResult, type McpPublicErrorCode, type McpRequiredScopes, type McpResourcesConfig, type McpRoutesConfig, type McpStdioConfig, type McpToolConfig, type McpToolDefinition, type McpToolHandlerArgs, type McpTransportKind, type McpWorkloadAuditEvent, type McpWorkloadAuthorization, type McpWorkloadAuthorizationRequest, type McpWorkloadAuthorizer, type McpWorkloadContextBinder, type McpWorkloadContextBindingInput, type McpWorkloadExecutionControl, type McpWorkloadHandoff, type McpWorkloadHandoffInput, type McpWorkloadRequirement, type McpWorkloadToolFacts, type McpWorkloadToolKind, type McpWorkloadToolPort, type ResolvedMcpCatalog, type ResolvedMcpCustomToolCatalogEntry, type ResolvedMcpEntityCatalogEntry, type ResolvedMcpRouteCatalogEntry, type ScopeOperationKind, type WorkloadMcpServerOptions, createMcpServer, createWorkloadMcpServer, createWorkloadMcpToolPort, mcpModule as default, mcpModule, defaultOperationScope, mcpConfig, mcpPlugin, mcpPublicErrorCode, mcpTool, normalizeRequiredScopes, requiredScopesForOperation, resolveMcpCatalog, scopeGateAllows, scopesFromContext, startStdioServer };
|
package/dist/index.mjs
CHANGED
|
@@ -1,12 +1,99 @@
|
|
|
1
|
-
import { a as requiredScopesForOperation, i as
|
|
2
|
-
import { n as mcp_default, t as mcpModule } from "./mcp-
|
|
3
|
-
import { t as mcpPlugin } from "./plugin-
|
|
4
|
-
import { t as startStdioServer } from "./stdio-
|
|
1
|
+
import { S as scopesFromContext, _ as resolveMcpCatalog, a as customToolWorkloadIdentity, b as requiredScopesForOperation, c as createWorkloadMcpBoundary, f as McpAccessDeniedError, g as toMcpToolError, h as mcpPublicErrorCode, i as customToolDescriptor, l as createRuntimeScope, m as assertBoundedMcpValue, n as createWorkloadMcpServer, o as executeCustomToolCall, p as McpPublicError, r as customToolAllows, s as authorizeWorkload, t as createMcpServer, u as createWorkloadMcpRelease, v as defaultOperationScope, w as mcpTool, x as scopeGateAllows, y as normalizeRequiredScopes } from "./create-server-CEWFf041.mjs";
|
|
2
|
+
import { n as mcp_default, t as mcpModule } from "./mcp-CuJEhynp.mjs";
|
|
3
|
+
import { t as mcpPlugin } from "./plugin-BZQe1pji.mjs";
|
|
4
|
+
import { t as startStdioServer } from "./stdio-CgIPiPUb.mjs";
|
|
5
|
+
import { randomUUID } from "node:crypto";
|
|
5
6
|
|
|
7
|
+
//#region src/server/workload-tool-port.ts
|
|
8
|
+
const defaultSignal = () => new AbortController().signal;
|
|
9
|
+
/**
|
|
10
|
+
* Programmatic, custom-tool-only workload port. This is deliberately not a
|
|
11
|
+
* general in-process MCP client: CRUD, routes, resources, and transport
|
|
12
|
+
* authority are absent by construction.
|
|
13
|
+
*/
|
|
14
|
+
function createWorkloadMcpToolPort(app, options) {
|
|
15
|
+
const workload = createWorkloadMcpBoundary(options);
|
|
16
|
+
const release = createWorkloadMcpRelease(app, options.config);
|
|
17
|
+
const scope = createRuntimeScope(app, {
|
|
18
|
+
transport: "workload",
|
|
19
|
+
accessMode: "user",
|
|
20
|
+
config: release.config
|
|
21
|
+
}, release.execution, workload);
|
|
22
|
+
return Object.freeze({
|
|
23
|
+
async listCustomTools(request = {}) {
|
|
24
|
+
const tools = [];
|
|
25
|
+
const controller = new AbortController();
|
|
26
|
+
let timedOut = false;
|
|
27
|
+
const cancel = () => controller.abort(request.signal?.reason);
|
|
28
|
+
if (request.signal?.aborted) cancel();
|
|
29
|
+
else request.signal?.addEventListener("abort", cancel, { once: true });
|
|
30
|
+
const timer = setTimeout(() => {
|
|
31
|
+
timedOut = true;
|
|
32
|
+
controller.abort(/* @__PURE__ */ new Error("MCP list deadline exceeded"));
|
|
33
|
+
}, release.execution.limits.timeoutMs);
|
|
34
|
+
const extra = {
|
|
35
|
+
signal: controller.signal,
|
|
36
|
+
requestId: request.requestId ?? randomUUID()
|
|
37
|
+
};
|
|
38
|
+
try {
|
|
39
|
+
if (controller.signal.aborted) throw new McpPublicError(timedOut ? "timeout" : "cancelled");
|
|
40
|
+
for (const [toolName, { tool }] of release.catalog.customTools) {
|
|
41
|
+
if (!tool.config.workload) continue;
|
|
42
|
+
const identity = customToolWorkloadIdentity(toolName, tool);
|
|
43
|
+
try {
|
|
44
|
+
let workloadAuthorization;
|
|
45
|
+
const descriptor = await scope.execution.execute({
|
|
46
|
+
operation: "tools/list",
|
|
47
|
+
transport: "workload",
|
|
48
|
+
accessMode: "user",
|
|
49
|
+
input: { name: toolName },
|
|
50
|
+
extra,
|
|
51
|
+
authorize: async (control) => {
|
|
52
|
+
workloadAuthorization = await authorizeWorkload(workload, "discovery", identity, tool.config.workload, control);
|
|
53
|
+
if (!workloadAuthorization || !await customToolAllows(scope, tool, workloadAuthorization.context)) throw new McpAccessDeniedError();
|
|
54
|
+
return workloadAuthorization.context;
|
|
55
|
+
},
|
|
56
|
+
concurrencyKey: () => workloadAuthorization?.concurrencyKey,
|
|
57
|
+
invoke: async () => customToolDescriptor(toolName, tool)
|
|
58
|
+
});
|
|
59
|
+
tools.push(descriptor);
|
|
60
|
+
} catch (error) {
|
|
61
|
+
if (mcpPublicErrorCode(error) === "access_denied") continue;
|
|
62
|
+
if (timedOut && mcpPublicErrorCode(error) === "cancelled") throw new McpPublicError("timeout");
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
assertBoundedMcpValue({ tools }, {
|
|
67
|
+
maxBytes: release.execution.limits.maxOutputBytes,
|
|
68
|
+
maxValueDepth: release.execution.limits.maxOutputDepth,
|
|
69
|
+
maxValueNodes: release.execution.limits.maxValueNodes
|
|
70
|
+
}, "output_too_large");
|
|
71
|
+
return { tools };
|
|
72
|
+
} finally {
|
|
73
|
+
clearTimeout(timer);
|
|
74
|
+
request.signal?.removeEventListener("abort", cancel);
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
async callCustomTool(request) {
|
|
78
|
+
const entry = typeof request?.name === "string" && request.name.length <= 256 ? release.catalog.customTools.get(request.name) : void 0;
|
|
79
|
+
if (!entry?.tool.config.workload) return toMcpToolError(new McpPublicError("access_denied"));
|
|
80
|
+
try {
|
|
81
|
+
return await executeCustomToolCall(scope, request.name, entry.tool, request.input, {
|
|
82
|
+
signal: request.signal ?? defaultSignal(),
|
|
83
|
+
requestId: request.requestId ?? randomUUID()
|
|
84
|
+
});
|
|
85
|
+
} catch (error) {
|
|
86
|
+
return toMcpToolError(error);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
//#endregion
|
|
6
93
|
//#region src/server/config.ts
|
|
7
94
|
function mcpConfig(config) {
|
|
8
95
|
return config;
|
|
9
96
|
}
|
|
10
97
|
|
|
11
98
|
//#endregion
|
|
12
|
-
export { createMcpServer, mcp_default as default, defaultOperationScope, mcpConfig, mcpModule, mcpPlugin, mcpTool, normalizeRequiredScopes, requiredScopesForOperation, scopeGateAllows, scopesFromContext, startStdioServer };
|
|
99
|
+
export { createMcpServer, createWorkloadMcpServer, createWorkloadMcpToolPort, mcp_default as default, defaultOperationScope, mcpConfig, mcpModule, mcpPlugin, mcpPublicErrorCode, mcpTool, normalizeRequiredScopes, requiredScopesForOperation, resolveMcpCatalog, scopeGateAllows, scopesFromContext, startStdioServer };
|