@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.
@@ -0,0 +1,323 @@
1
+ import { AppContext, RequestContext, createContextFactory } from "questpie";
2
+ import "questpie/executor";
3
+ import { z } from "zod";
4
+ import { CallToolResult, ToolAnnotations } from "@modelcontextprotocol/sdk/types.js";
5
+ import * as _modelcontextprotocol_sdk_server_mcp0 from "@modelcontextprotocol/sdk/server/mcp";
6
+
7
+ //#region src/server/types.d.ts
8
+ type McpTransportKind = "http" | "stdio" | "workload";
9
+ type McpAccessMode = "user" | "system";
10
+ interface McpAccessRuleContext {
11
+ transport: McpTransportKind;
12
+ accessMode: McpAccessMode;
13
+ session?: RequestContext["session"];
14
+ /**
15
+ * The consented OAuth scopes carried by the caller, when the request was
16
+ * authenticated by an OAuth access token (`ctx.principal.kind === "oauth"`).
17
+ * `undefined` for the `user` (first-party) and `system` (stdio/trusted)
18
+ * principals, which carry no scopes. This is the model input the scope gate
19
+ * (`scopeGateAllows`) reads when deciding whether a tool is visible/callable.
20
+ */
21
+ scopes?: string[];
22
+ ctx: AppContext & Partial<RequestContext>;
23
+ }
24
+ type McpAccessRule = boolean | ((ctx: McpAccessRuleContext) => boolean | Promise<boolean>);
25
+ /**
26
+ * OAuth scope requirement declaration. A single scope string, a list (all
27
+ * required — AND), or `false` to explicitly require no scope (public even to
28
+ * scoped OAuth callers). `undefined` means "fall back to the default mapping".
29
+ */
30
+ type McpRequiredScopes = string | string[] | false;
31
+ interface McpWorkloadRequirement {
32
+ /** Named facts interpreted exclusively by the consumer-supplied authorizer. */
33
+ capabilities: readonly string[];
34
+ /** Optional named capability delegated to the opaque execution handoff. */
35
+ handoff?: string;
36
+ }
37
+ type McpEntityPolicy = boolean | {
38
+ expose?: boolean;
39
+ operations?: Record<string, boolean | McpAccessRule>;
40
+ /**
41
+ * Scopes an OAuth caller must hold to reach this entity. Declarable at
42
+ * the entity level (applies to every operation) and/or per operation via
43
+ * {@link McpEntityPolicy.operationScopes}. When omitted, the default
44
+ * operation→scope mapping is derived from the operation kind (e.g.
45
+ * `collections:<name>:read`). Resolved by `requiredScopesForOperation`
46
+ * and enforced by the scope gate (`scopeGateAllows`) at both
47
+ * `tools/list` and `tools/call`.
48
+ */
49
+ requiredScopes?: McpRequiredScopes;
50
+ /**
51
+ * Per-operation scope requirements, keyed by operation name
52
+ * (`list`/`get`/`create`/`update`/`delete`/`invoke`/…). Overrides both
53
+ * {@link McpEntityPolicy.requiredScopes} and the default mapping for the
54
+ * named operation.
55
+ */
56
+ operationScopes?: Record<string, McpRequiredScopes>;
57
+ workload?: McpWorkloadRequirement;
58
+ operationWorkloads?: Record<string, McpWorkloadRequirement>;
59
+ fields?: {
60
+ include?: string[];
61
+ exclude?: string[];
62
+ };
63
+ description?: string;
64
+ };
65
+ interface McpCrudConfig {
66
+ collections?: Record<string, McpEntityPolicy>;
67
+ globals?: Record<string, McpEntityPolicy>;
68
+ maxLimit?: number;
69
+ }
70
+ interface McpRoutesConfig {
71
+ routes?: Record<string, McpEntityPolicy>;
72
+ }
73
+ interface McpResourcesConfig {
74
+ collections?: Record<string, boolean>;
75
+ globals?: Record<string, boolean>;
76
+ routes?: Record<string, boolean>;
77
+ }
78
+ interface McpTransportConfig {
79
+ accessMode?: McpAccessMode;
80
+ }
81
+ interface McpHttpConfig extends McpTransportConfig {
82
+ allowedOrigins?: string[];
83
+ allowedHosts?: string[];
84
+ enableJsonResponse?: boolean;
85
+ }
86
+ interface McpStdioConfig {
87
+ /**
88
+ * Explicitly grants this local stdio process maintenance authority. Without
89
+ * this flag, stdio requires an exact user-mode `ctx`.
90
+ */
91
+ trustedMaintenance?: boolean;
92
+ }
93
+ interface McpExecutionLimits {
94
+ /** Maximum serialized tool input accepted after protocol decoding. */
95
+ maxInputBytes?: number;
96
+ /** Maximum object/array nesting accepted in decoded operation input. */
97
+ maxInputDepth?: number;
98
+ /** Maximum object/array nesting accepted in operation output. */
99
+ maxOutputDepth?: number;
100
+ /** Maximum object properties and array entries visited per value. */
101
+ maxValueNodes?: number;
102
+ /** Maximum serialized tool result returned to a caller. */
103
+ maxOutputBytes?: number;
104
+ /** Wall-clock budget for authorization plus execution. */
105
+ timeoutMs?: number;
106
+ /** Maximum in-flight operations for one released app snapshot. */
107
+ maxConcurrency?: number;
108
+ /** Maximum in-flight operations for one resolved caller principal. */
109
+ maxConcurrencyPerPrincipal?: number;
110
+ /** Maximum released tools across custom, CRUD, and route catalogs. */
111
+ maxTools?: number;
112
+ /** Maximum released schema resources. */
113
+ maxResources?: number;
114
+ }
115
+ type McpPublicErrorCode = "access_denied" | "invalid_input" | "input_too_large" | "output_too_large" | "timeout" | "cancelled" | "busy" | "internal";
116
+ interface McpExecutionDiagnosticEvent {
117
+ correlationId: string;
118
+ requestId?: string | number;
119
+ transport: McpTransportKind;
120
+ operation: string;
121
+ durationMs: number;
122
+ outcome: "completed" | "rejected";
123
+ code?: McpPublicErrorCode;
124
+ /**
125
+ * Bounded and credential-redacted. Inputs, outputs, sessions, authorization
126
+ * envelopes, and workload attribution are never included.
127
+ */
128
+ internalError?: {
129
+ kind: "Error" | "Unknown";
130
+ };
131
+ }
132
+ interface McpExecutionConfig extends McpExecutionLimits {
133
+ /**
134
+ * Trusted server-side diagnostics sink. At most one unresolved callback is
135
+ * retained; subsequent events are dropped until it settles.
136
+ */
137
+ onDiagnostic?: (event: Readonly<McpExecutionDiagnosticEvent>) => void | Promise<void>;
138
+ }
139
+ interface McpConfig {
140
+ name?: string;
141
+ version?: string;
142
+ crud?: McpCrudConfig;
143
+ routes?: McpRoutesConfig;
144
+ resources?: McpResourcesConfig;
145
+ http?: McpHttpConfig;
146
+ stdio?: McpStdioConfig;
147
+ execution?: McpExecutionConfig;
148
+ }
149
+ interface McpExecutionOptions {
150
+ transport?: McpTransportKind;
151
+ accessMode?: McpAccessMode;
152
+ ctx?: AppContext & Partial<RequestContext>;
153
+ request?: Request;
154
+ config?: McpConfig;
155
+ }
156
+ interface McpWorkloadAuthorizationRequest {
157
+ phase: "discovery" | "call";
158
+ envelope: unknown;
159
+ tool: McpWorkloadToolFacts;
160
+ }
161
+ type McpWorkloadToolKind = "custom" | "collection" | "global" | "route";
162
+ interface McpWorkloadToolFacts {
163
+ kind: McpWorkloadToolKind;
164
+ name: string;
165
+ operation: string;
166
+ intent: "read" | "effect";
167
+ transport: "workload";
168
+ capabilities: readonly string[];
169
+ handoff?: string;
170
+ }
171
+ interface McpWorkloadAuthorization {
172
+ context: unknown;
173
+ attribution?: unknown;
174
+ }
175
+ interface McpWorkloadExecutionControl {
176
+ signal: AbortSignal;
177
+ requestId: string | number;
178
+ correlationId: string;
179
+ }
180
+ interface McpWorkloadAuthorizer {
181
+ authorize(request: McpWorkloadAuthorizationRequest, control?: McpWorkloadExecutionControl): McpWorkloadAuthorization | null | Promise<McpWorkloadAuthorization | null>;
182
+ }
183
+ interface McpWorkloadContextBindingInput {
184
+ authorizationContext: unknown;
185
+ attribution?: unknown;
186
+ tool: McpWorkloadToolFacts;
187
+ }
188
+ interface McpWorkloadContextBinder {
189
+ /**
190
+ * Bind opaque authorization to the exact user-mode QUESTPIE context used for
191
+ * access rechecks and execution. System-mode contexts fail closed.
192
+ */
193
+ bind(input: McpWorkloadContextBindingInput, control?: McpWorkloadExecutionControl): (AppContext & Partial<RequestContext>) | Promise<AppContext & Partial<RequestContext>>;
194
+ }
195
+ /**
196
+ * Remote workload execution is intentionally not an {@link McpExecutionOptions}
197
+ * variant. It cannot inherit HTTP request identity, cookies, OAuth, requester
198
+ * sessions, access-mode overrides, or the stdio system default.
199
+ */
200
+ interface WorkloadMcpServerOptions {
201
+ envelope: unknown;
202
+ /**
203
+ * Stable, non-secret consumer/tenant key for per-principal concurrency.
204
+ * Independent workload boundaries with different keys cannot exhaust one
205
+ * another's per-principal bucket. Omitted keys are isolated per boundary.
206
+ */
207
+ concurrencyKey?: string;
208
+ authorizer: McpWorkloadAuthorizer;
209
+ contextBinder: McpWorkloadContextBinder;
210
+ config?: McpConfig;
211
+ audit?: (event: McpWorkloadAuditEvent) => void | Promise<void>;
212
+ handoff?: McpWorkloadHandoff;
213
+ }
214
+ interface McpWorkloadHandoffInput {
215
+ authorizationContext: unknown;
216
+ attribution?: unknown;
217
+ toolName: string;
218
+ capability: string;
219
+ tool: McpWorkloadToolFacts;
220
+ metadata: unknown;
221
+ signal: AbortSignal;
222
+ requestId: string | number;
223
+ correlationId: string;
224
+ invoke: () => CallToolResult | Promise<CallToolResult>;
225
+ }
226
+ interface McpWorkloadHandoff {
227
+ execute(input: McpWorkloadHandoffInput): CallToolResult | Promise<CallToolResult>;
228
+ }
229
+ interface McpWorkloadAuditEvent {
230
+ phase: "discovery" | "call";
231
+ decision: "allowed" | "denied";
232
+ toolName?: string;
233
+ reason?: "authorization_denied" | "authorization_invalid" | "context_invalid";
234
+ attribution?: unknown;
235
+ }
236
+ interface McpToolHandlerArgs<TInput = unknown> {
237
+ input: TInput;
238
+ ctx: AppContext & Partial<RequestContext>;
239
+ transport: McpTransportKind;
240
+ accessMode: McpAccessMode;
241
+ request?: Request;
242
+ signal: AbortSignal;
243
+ requestId: string | number;
244
+ correlationId: string;
245
+ }
246
+ interface McpProgrammaticRequestOptions {
247
+ signal?: AbortSignal;
248
+ requestId?: string | number;
249
+ }
250
+ interface McpProgrammaticTool {
251
+ name: string;
252
+ title?: string;
253
+ description?: string;
254
+ inputSchema: Record<string, unknown>;
255
+ outputSchema?: Record<string, unknown>;
256
+ annotations?: ToolAnnotations;
257
+ _meta?: Record<string, unknown>;
258
+ }
259
+ interface McpProgrammaticToolResult {
260
+ content: Array<{
261
+ type: string;
262
+ [key: string]: unknown;
263
+ }>;
264
+ structuredContent?: Record<string, unknown>;
265
+ isError?: boolean;
266
+ _meta?: Record<string, unknown>;
267
+ }
268
+ interface McpWorkloadToolPort {
269
+ listCustomTools(options?: McpProgrammaticRequestOptions): Promise<{
270
+ tools: McpProgrammaticTool[];
271
+ }>;
272
+ callCustomTool(input: {
273
+ name: string;
274
+ input: unknown;
275
+ signal?: AbortSignal;
276
+ requestId?: string | number;
277
+ }): Promise<McpProgrammaticToolResult>;
278
+ }
279
+ interface McpToolConfig<TInputSchema extends z.ZodTypeAny = z.ZodTypeAny, TOutputSchema extends z.ZodTypeAny = z.ZodTypeAny> {
280
+ title?: string;
281
+ description?: string;
282
+ inputSchema?: TInputSchema;
283
+ outputSchema?: TOutputSchema;
284
+ annotations?: ToolAnnotations;
285
+ access: McpAccessRule;
286
+ /**
287
+ * Scopes an OAuth caller must hold to reach this custom tool (all required —
288
+ * AND), or `false` as an explicit no-OAuth-scope policy. Custom tools have no
289
+ * default mapping, so omission keeps the tool out of the released catalog. Enforced by the
290
+ * scope gate (`scopeGateAllows`) at both `tools/list` (hidden) and
291
+ * `tools/call` (denied); `system`/`user` callers carry no scopes and skip it.
292
+ */
293
+ scopes: McpRequiredScopes;
294
+ /** Explicit, fail-closed authority contract for remote workload execution. */
295
+ workload?: McpWorkloadRequirement;
296
+ _meta?: Record<string, unknown>;
297
+ }
298
+ interface McpToolDefinition<TInputSchema extends z.ZodTypeAny = z.ZodTypeAny, TOutputSchema extends z.ZodTypeAny = z.ZodTypeAny> {
299
+ readonly __brand: "mcpTool";
300
+ readonly name: string;
301
+ readonly config: McpToolConfig<TInputSchema, TOutputSchema>;
302
+ readonly handler: (args: McpToolHandlerArgs<z.infer<TInputSchema>>) => CallToolResult | Promise<CallToolResult>;
303
+ }
304
+ declare module "questpie" {
305
+ interface AppStateConfig {
306
+ mcp?: McpConfig;
307
+ }
308
+ interface ModuleDefinition {
309
+ mcpTools?: Record<string, McpToolDefinition>;
310
+ }
311
+ }
312
+ //#endregion
313
+ //#region src/server/execution-boundary.d.ts
314
+ /** Read a public boundary code without touching an error message or accessor. */
315
+ declare function mcpPublicErrorCode(error: unknown): McpPublicErrorCode | undefined;
316
+ //#endregion
317
+ //#region src/server/runtime.d.ts
318
+ type QuestpieApp = Parameters<typeof createContextFactory>[0];
319
+ //#endregion
320
+ //#region src/server/stdio.d.ts
321
+ declare function startStdioServer(app: QuestpieApp, options?: Omit<McpExecutionOptions, "transport">): Promise<_modelcontextprotocol_sdk_server_mcp0.McpServer>;
322
+ //#endregion
323
+ export { McpWorkloadAuthorizer as A, WorkloadMcpServerOptions as B, McpToolConfig as C, McpWorkloadAuditEvent as D, McpTransportKind as E, McpWorkloadHandoffInput as F, McpWorkloadRequirement as I, McpWorkloadToolFacts as L, McpWorkloadContextBindingInput as M, McpWorkloadExecutionControl as N, McpWorkloadAuthorization as O, McpWorkloadHandoff as P, McpWorkloadToolKind as R, McpStdioConfig as S, McpToolHandlerArgs as T, McpProgrammaticToolResult as _, McpAccessRule as a, McpResourcesConfig as b, McpCrudConfig as c, McpExecutionDiagnosticEvent as d, McpExecutionLimits as f, McpProgrammaticTool as g, McpProgrammaticRequestOptions as h, McpAccessMode as i, McpWorkloadContextBinder as j, McpWorkloadAuthorizationRequest as k, McpEntityPolicy as l, McpHttpConfig as m, QuestpieApp as n, McpAccessRuleContext as o, McpExecutionOptions as p, mcpPublicErrorCode as r, McpConfig as s, startStdioServer as t, McpExecutionConfig as u, McpPublicErrorCode as v, McpToolDefinition as w, McpRoutesConfig as x, McpRequiredScopes as y, McpWorkloadToolPort as z };
package/dist/stdio.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- import { t as startStdioServer } from "./stdio-t_9rKayH.mjs";
1
+ import { t as startStdioServer } from "./stdio-YoM70-42.mjs";
2
2
  export { startStdioServer };
package/dist/stdio.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import { t as startStdioServer } from "./stdio-qyQFVEyU.mjs";
1
+ import { t as startStdioServer } from "./stdio-CgIPiPUb.mjs";
2
2
 
3
3
  export { startStdioServer };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@questpie/mcp",
3
- "version": "3.15.2",
3
+ "version": "3.17.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/questpie/questpie.git",
@@ -64,11 +64,12 @@
64
64
  "scripts": {
65
65
  "build": "tsdown",
66
66
  "check-types": "tsc --noEmit",
67
- "questpie:generate": "bun questpie generate --verbose"
67
+ "questpie:generate": "bun questpie generate --verbose",
68
+ "test": "bun test ./test"
68
69
  },
69
70
  "dependencies": {
70
71
  "@modelcontextprotocol/sdk": "^1.29.0",
71
- "questpie": "^3.15.2",
72
+ "questpie": "^3.17.0",
72
73
  "zod": "^4.2.1"
73
74
  },
74
75
  "devDependencies": {
@@ -78,6 +79,6 @@
78
79
  "tsdown": "^0.18.3"
79
80
  },
80
81
  "peerDependencies": {
81
- "questpie": "^3.0.0"
82
+ "questpie": "^3.17.0"
82
83
  }
83
84
  }