@happyvertical/smrt-app-mcp 0.57.43 → 0.57.45
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/AGENTS.md +6 -0
- package/README.md +41 -0
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +12 -4
- package/dist/auth.js.map +1 -1
- package/dist/chunks/errors-XG_zn1pP.js +73 -0
- package/dist/chunks/errors-XG_zn1pP.js.map +1 -0
- package/dist/chunks/identity-BNzyRsWf.js +14 -0
- package/dist/chunks/identity-BNzyRsWf.js.map +1 -0
- package/dist/chunks/{protocol-CoCuR_w7.js → protocol-BRQji5k_.js} +110 -48
- package/dist/chunks/protocol-BRQji5k_.js.map +1 -0
- package/dist/errors.d.ts +42 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/host-operations.d.ts +117 -0
- package/dist/host-operations.d.ts.map +1 -0
- package/dist/host-operations.js +160 -0
- package/dist/host-operations.js.map +1 -0
- package/dist/identity.d.ts +11 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +1 -1
- package/dist/server.d.ts +46 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/smrt-knowledge.json +6 -5
- package/dist/sveltekit.d.ts.map +1 -1
- package/dist/sveltekit.js +5 -3
- package/dist/sveltekit.js.map +1 -1
- package/dist/workflow-tools.d.ts +8 -0
- package/dist/workflow-tools.d.ts.map +1 -1
- package/package.json +7 -3
- package/dist/chunks/protocol-CoCuR_w7.js.map +0 -1
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
//#region src/errors.ts
|
|
2
|
+
var MCP_TOOL_ACCESS_DENIED_CODE = "mcp_tool_access_denied";
|
|
3
|
+
var MCP_ORIGIN_DENIED_CODE = "mcp_origin_denied";
|
|
4
|
+
var McpAccessError = class extends Error {
|
|
5
|
+
constructor(status, message, metadata = {}) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.status = status;
|
|
8
|
+
this.metadata = metadata;
|
|
9
|
+
this.name = "McpAccessError";
|
|
10
|
+
}
|
|
11
|
+
status;
|
|
12
|
+
metadata;
|
|
13
|
+
};
|
|
14
|
+
var MCP_TOOL_NOT_FOUND_CODE = "mcp_tool_not_found";
|
|
15
|
+
var MCP_AUTHENTICATION_REQUIRED_CODE = "mcp_authentication_required";
|
|
16
|
+
var MCP_TOOL_EXECUTION_FAILED_CODE = "mcp_tool_execution_failed";
|
|
17
|
+
var MCP_TOOL_EXECUTION_FAILED_MESSAGE = "Workflow execution failed.";
|
|
18
|
+
var McpToolError = class extends Error {
|
|
19
|
+
code;
|
|
20
|
+
details;
|
|
21
|
+
constructor(code, message, details) {
|
|
22
|
+
super(message);
|
|
23
|
+
this.name = "McpToolError";
|
|
24
|
+
this.code = code;
|
|
25
|
+
if (details !== void 0) this.details = details;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
var SAFE_CODE = /^[A-Za-z][A-Za-z0-9_.:-]{0,63}$/;
|
|
29
|
+
var MAX_SAFE_MESSAGE_LENGTH = 500;
|
|
30
|
+
var MAX_SAFE_DETAILS_BYTES = 4096;
|
|
31
|
+
var GENERIC_TOOL_ERROR = Object.freeze({
|
|
32
|
+
code: MCP_TOOL_EXECUTION_FAILED_CODE,
|
|
33
|
+
message: MCP_TOOL_EXECUTION_FAILED_MESSAGE
|
|
34
|
+
});
|
|
35
|
+
function validInfo(value) {
|
|
36
|
+
if (!value || typeof value !== "object") return void 0;
|
|
37
|
+
const { code, message, details } = value;
|
|
38
|
+
if (typeof code !== "string" || !SAFE_CODE.test(code)) return void 0;
|
|
39
|
+
if (typeof message !== "string" || !message.trim() || message.length > MAX_SAFE_MESSAGE_LENGTH) return;
|
|
40
|
+
const info = {
|
|
41
|
+
code,
|
|
42
|
+
message
|
|
43
|
+
};
|
|
44
|
+
if (details !== void 0) try {
|
|
45
|
+
if (!details || typeof details !== "object" || Array.isArray(details) || typeof JSON.stringify(details) !== "string" || JSON.stringify(details).length > MAX_SAFE_DETAILS_BYTES) return;
|
|
46
|
+
info.details = JSON.parse(JSON.stringify(details));
|
|
47
|
+
} catch {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
return info;
|
|
51
|
+
}
|
|
52
|
+
function safeMcpToolError(error, mapError) {
|
|
53
|
+
return authoredMcpToolError(error, mapError) ?? { ...GENERIC_TOOL_ERROR };
|
|
54
|
+
}
|
|
55
|
+
function authoredMcpToolError(error, mapError) {
|
|
56
|
+
try {
|
|
57
|
+
if (error instanceof McpToolError) {
|
|
58
|
+
const info = validInfo({
|
|
59
|
+
code: error.code,
|
|
60
|
+
message: error.message,
|
|
61
|
+
details: error.details
|
|
62
|
+
});
|
|
63
|
+
if (info) return info;
|
|
64
|
+
} else if (mapError) {
|
|
65
|
+
const info = validInfo(mapError(error));
|
|
66
|
+
if (info) return info;
|
|
67
|
+
}
|
|
68
|
+
} catch {}
|
|
69
|
+
}
|
|
70
|
+
//#endregion
|
|
71
|
+
export { MCP_TOOL_NOT_FOUND_CODE as a, authoredMcpToolError as c, MCP_TOOL_EXECUTION_FAILED_CODE as i, safeMcpToolError as l, MCP_ORIGIN_DENIED_CODE as n, McpAccessError as o, MCP_TOOL_ACCESS_DENIED_CODE as r, McpToolError as s, MCP_AUTHENTICATION_REQUIRED_CODE as t };
|
|
72
|
+
|
|
73
|
+
//# sourceMappingURL=errors-XG_zn1pP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors-XG_zn1pP.js","names":[],"sources":["../../src/errors.ts"],"sourcesContent":["/** Machine-readable code for a principal policy denial. */\nexport const MCP_TOOL_ACCESS_DENIED_CODE = 'mcp_tool_access_denied';\n\n/** Machine-readable code for a request refused by the endpoint's origin check. */\nexport const MCP_ORIGIN_DENIED_CODE = 'mcp_origin_denied';\n\n/**\n * Metadata that is safe to expose for an app-MCP access failure. Policy\n * implementations must not place principal, scope, tool, or internal-error\n * details here.\n */\nexport interface McpAccessErrorMetadata {\n code?: string;\n retryable?: boolean;\n}\n\n/**\n * Error returned by the MCP app server when a caller tries to use a tool\n * they are not allowed to access. The HTTP layer should map `status` onto\n * the response status code.\n */\nexport class McpAccessError extends Error {\n constructor(\n readonly status: number,\n message: string,\n readonly metadata: McpAccessErrorMetadata = {},\n ) {\n super(message);\n this.name = 'McpAccessError';\n }\n}\n\n/** Stable code for a request naming a tool this server does not publish. */\nexport const MCP_TOOL_NOT_FOUND_CODE = 'mcp_tool_not_found';\n\n/** Stable code for a tool call that needs an authenticated principal. */\nexport const MCP_AUTHENTICATION_REQUIRED_CODE = 'mcp_authentication_required';\n\n/** Stable code for an unmapped handler failure; carries no internals. */\nexport const MCP_TOOL_EXECUTION_FAILED_CODE = 'mcp_tool_execution_failed';\n\n/** The generic message an unmapped handler failure returns. */\nexport const MCP_TOOL_EXECUTION_FAILED_MESSAGE = 'Workflow execution failed.';\n\n/** The agent-safe projection of a tool failure: a stable code and a message. */\nexport interface McpToolErrorInfo {\n code: string;\n message: string;\n /** Optional JSON-safe, non-sensitive structured detail. */\n details?: Record<string, unknown>;\n}\n\n/**\n * Throw from a workflow tool handler to hand the calling agent a typed,\n * authored failure. The `code` and `message` (and optional `details`) reach\n * the agent verbatim, so they must be safe to disclose: never put records,\n * credentials, stack traces, or other tenants' data in them. Any other\n * thrown value stays behind the generic failure message.\n */\nexport class McpToolError extends Error {\n readonly code: string;\n readonly details?: Record<string, unknown>;\n constructor(\n code: string,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(message);\n this.name = 'McpToolError';\n this.code = code;\n if (details !== undefined) this.details = details;\n }\n}\n\n/** Per-tool mapping of a handler failure to a safe code and message. */\nexport type McpToolErrorMapper = (\n error: unknown,\n) => McpToolErrorInfo | null | undefined;\n\nconst SAFE_CODE = /^[A-Za-z][A-Za-z0-9_.:-]{0,63}$/;\nconst MAX_SAFE_MESSAGE_LENGTH = 500;\nconst MAX_SAFE_DETAILS_BYTES = 4096;\n\nconst GENERIC_TOOL_ERROR: Readonly<McpToolErrorInfo> = Object.freeze({\n code: MCP_TOOL_EXECUTION_FAILED_CODE,\n message: MCP_TOOL_EXECUTION_FAILED_MESSAGE,\n});\n\nfunction validInfo(value: unknown): McpToolErrorInfo | undefined {\n if (!value || typeof value !== 'object') return undefined;\n const { code, message, details } = value as Record<string, unknown>;\n if (typeof code !== 'string' || !SAFE_CODE.test(code)) return undefined;\n if (\n typeof message !== 'string' ||\n !message.trim() ||\n message.length > MAX_SAFE_MESSAGE_LENGTH\n ) {\n return undefined;\n }\n const info: McpToolErrorInfo = { code, message };\n if (details !== undefined) {\n try {\n if (\n !details ||\n typeof details !== 'object' ||\n Array.isArray(details) ||\n typeof JSON.stringify(details) !== 'string' ||\n JSON.stringify(details).length > MAX_SAFE_DETAILS_BYTES\n ) {\n return undefined;\n }\n info.details = JSON.parse(JSON.stringify(details));\n } catch {\n return undefined;\n }\n }\n return info;\n}\n\n/**\n * Resolve a thrown value to the information that may reach an agent. Never\n * throws: a thrown {@link McpToolError} or a valid `mapError` result yields its\n * safe code and message; anything else (including a throwing or malformed\n * mapper) yields the generic failure.\n */\nexport function safeMcpToolError(\n error: unknown,\n mapError?: McpToolErrorMapper,\n): McpToolErrorInfo {\n return authoredMcpToolError(error, mapError) ?? { ...GENERIC_TOOL_ERROR };\n}\n\n/**\n * The authored (opt-in) safe error for a thrown value: a valid\n * {@link McpToolError} or `mapError` result, else `undefined`. Only this form\n * is typed on the MCP wire; an unmapped failure keeps the generic result.\n */\nexport function authoredMcpToolError(\n error: unknown,\n mapError?: McpToolErrorMapper,\n): McpToolErrorInfo | undefined {\n try {\n if (error instanceof McpToolError) {\n const info = validInfo({\n code: error.code,\n message: error.message,\n details: error.details,\n });\n if (info) return info;\n } else if (mapError) {\n const info = validInfo(mapError(error));\n if (info) return info;\n }\n } catch {\n // A mapper failure falls back to the generic message.\n }\n return undefined;\n}\n"],"mappings":";AACO,IAAM,8BAA8B;AAGpC,IAAM,yBAAyB;AAiB/B,IAAM,iBAAN,cAA6B,MAAM;CACxC,YACW,QACT,SACS,WAAmC,CAAC,GAC7C;EACA,MAAM,OAAO;EAJJ,KAAA,SAAA;EAEA,KAAA,WAAA;EAGT,KAAK,OAAO;CACd;CANW;CAEA;AAKb;AAGO,IAAM,0BAA0B;AAGhC,IAAM,mCAAmC;AAGzC,IAAM,iCAAiC;AAGvC,IAAM,oCAAoC;AAiB1C,IAAM,eAAN,cAA2B,MAAM;CAC7B;CACA;CACT,YACE,MACA,SACA,SACA;EACA,MAAM,OAAO;EACb,KAAK,OAAO;EACZ,KAAK,OAAO;EACZ,IAAI,YAAY,KAAA,GAAW,KAAK,UAAU;CAC5C;AACF;AAOA,IAAM,YAAY;AAClB,IAAM,0BAA0B;AAChC,IAAM,yBAAyB;AAE/B,IAAM,qBAAiD,OAAO,OAAO;CACnE,MAAM;CACN,SAAS;AACX,CAAC;AAED,SAAS,UAAU,OAA8C;CAC/D,IAAI,CAAC,SAAS,OAAO,UAAU,UAAU,OAAO,KAAA;CAChD,MAAM,EAAE,MAAM,SAAS,YAAY;CACnC,IAAI,OAAO,SAAS,YAAY,CAAC,UAAU,KAAK,IAAI,GAAG,OAAO,KAAA;CAC9D,IACE,OAAO,YAAY,YACnB,CAAC,QAAQ,KAAK,KACd,QAAQ,SAAS,yBAEjB;CAEF,MAAM,OAAyB;EAAE;EAAM;CAAQ;CAC/C,IAAI,YAAY,KAAA,GACd,IAAI;EACF,IACE,CAAC,WACD,OAAO,YAAY,YACnB,MAAM,QAAQ,OAAO,KACrB,OAAO,KAAK,UAAU,OAAO,MAAM,YACnC,KAAK,UAAU,OAAO,CAAA,CAAE,SAAS,wBAEjC;EAEF,KAAK,UAAU,KAAK,MAAM,KAAK,UAAU,OAAO,CAAC;CACnD,QAAQ;EACN;CACF;CAEF,OAAO;AACT;AAQO,SAAS,iBACd,OACA,UACkB;CAClB,OAAO,qBAAqB,OAAO,QAAQ,KAAK,EAAE,GAAG,mBAAmB;AAC1E;AAOO,SAAS,qBACd,OACA,UAC8B;CAC9B,IAAI;EACF,IAAI,iBAAiB,cAAc;GACjC,MAAM,OAAO,UAAU;IACrB,MAAM,MAAM;IACZ,SAAS,MAAM;IACf,SAAS,MAAM;GACjB,CAAC;GACD,IAAI,MAAM,OAAO;EACnB,OAAA,IAAW,UAAU;GACnB,MAAM,OAAO,UAAU,SAAS,KAAK,CAAC;GACtC,IAAI,MAAM,OAAO;EACnB;CACF,QAAQ,CAER;AAEF"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region src/identity.ts
|
|
2
|
+
function stampVerifiedIdentity(principal, identity) {
|
|
3
|
+
if (identity) Object.defineProperty(principal, "identity", {
|
|
4
|
+
value: Object.freeze({ ...identity }),
|
|
5
|
+
enumerable: false,
|
|
6
|
+
configurable: false,
|
|
7
|
+
writable: false
|
|
8
|
+
});
|
|
9
|
+
return principal;
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
export { stampVerifiedIdentity as t };
|
|
13
|
+
|
|
14
|
+
//# sourceMappingURL=identity-BNzyRsWf.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity-BNzyRsWf.js","names":[],"sources":["../../src/identity.ts"],"sourcesContent":["import type { McpPrincipalIdentity } from './server.js';\n\n/**\n * Attach the adapter-verified credential identity to a principal as a\n * non-enumerable property: it never changes the principal's enumerable\n * (deep-equal, serialized) shape, and an object spread drops it, so any\n * code that rebuilds a principal must re-stamp it from the authenticated one.\n *\n * @internal\n */\nexport function stampVerifiedIdentity<T extends object>(\n principal: T,\n identity: McpPrincipalIdentity | undefined,\n): T {\n if (identity) {\n Object.defineProperty(principal, 'identity', {\n value: Object.freeze({ ...identity }),\n enumerable: false,\n configurable: false,\n writable: false,\n });\n }\n return principal;\n}\n"],"mappings":";AAUO,SAAS,sBACd,WACA,UACG;CACH,IAAI,UACF,OAAO,eAAe,WAAW,YAAY;EAC3C,OAAO,OAAO,OAAO,EAAE,GAAG,SAAS,CAAC;EACpC,YAAY;EACZ,cAAc;EACd,UAAU;CACZ,CAAC;CAEH,OAAO;AACT"}
|
|
@@ -1,22 +1,9 @@
|
|
|
1
|
+
import { c as authoredMcpToolError, l as safeMcpToolError, o as McpAccessError, r as MCP_TOOL_ACCESS_DENIED_CODE } from "./errors-XG_zn1pP.js";
|
|
1
2
|
import { McpTaskNotFoundError, McpTaskStore, SmrtJobCollection } from "@happyvertical/smrt-jobs";
|
|
2
3
|
import { MCPGenerator, MCP_STABLE_CATALOG_TTL_MS, assertMcpJsonSchemaSafety, mcpToolAnnotationsFor } from "@happyvertical/smrt-core/generators/mcp";
|
|
3
4
|
import { ObjectRegistry, isTenantScopedClassResolved } from "@happyvertical/smrt-core";
|
|
4
5
|
import { createHash } from "node:crypto";
|
|
5
6
|
import { ProtocolError, ProtocolErrorCode, Server } from "@modelcontextprotocol/server";
|
|
6
|
-
//#region src/errors.ts
|
|
7
|
-
var MCP_TOOL_ACCESS_DENIED_CODE = "mcp_tool_access_denied";
|
|
8
|
-
var MCP_ORIGIN_DENIED_CODE = "mcp_origin_denied";
|
|
9
|
-
var McpAccessError = class extends Error {
|
|
10
|
-
constructor(status, message, metadata = {}) {
|
|
11
|
-
super(message);
|
|
12
|
-
this.status = status;
|
|
13
|
-
this.metadata = metadata;
|
|
14
|
-
this.name = "McpAccessError";
|
|
15
|
-
}
|
|
16
|
-
status;
|
|
17
|
-
metadata;
|
|
18
|
-
};
|
|
19
|
-
//#endregion
|
|
20
7
|
//#region src/workflow-tools.ts
|
|
21
8
|
var TOOL_NAME = /^[a-z][a-z0-9_]{0,63}$/;
|
|
22
9
|
function assertRecord(value, label) {
|
|
@@ -94,6 +81,7 @@ function createMcpWorkflowTool(definition) {
|
|
|
94
81
|
if (typeof definition.name !== "string" || !TOOL_NAME.test(definition.name)) throw new TypeError("Workflow tool name must be lowercase snake_case with at most 64 characters.");
|
|
95
82
|
if (typeof definition.description !== "string" || !definition.description.trim()) throw new TypeError("Workflow tool description must be non-empty.");
|
|
96
83
|
if (typeof definition.execute !== "function") throw new TypeError("Workflow tool execute must be a function.");
|
|
84
|
+
if (definition.mapError !== void 0 && typeof definition.mapError !== "function") throw new TypeError("Workflow tool mapError must be a function.");
|
|
97
85
|
if (![
|
|
98
86
|
"read",
|
|
99
87
|
"write",
|
|
@@ -134,7 +122,8 @@ function createMcpWorkflowTool(definition) {
|
|
|
134
122
|
...icons ? { icons } : {},
|
|
135
123
|
...Object.keys(meta).length > 0 ? { _meta: meta } : {}
|
|
136
124
|
},
|
|
137
|
-
execute: definition.execute
|
|
125
|
+
execute: definition.execute,
|
|
126
|
+
...definition.mapError ? { mapError: definition.mapError } : {}
|
|
138
127
|
};
|
|
139
128
|
}
|
|
140
129
|
//#endregion
|
|
@@ -7345,32 +7334,104 @@ function createMcpAppServer(options) {
|
|
|
7345
7334
|
tool
|
|
7346
7335
|
};
|
|
7347
7336
|
}
|
|
7348
|
-
|
|
7349
|
-
|
|
7350
|
-
const
|
|
7351
|
-
if (
|
|
7352
|
-
|
|
7353
|
-
|
|
7354
|
-
|
|
7355
|
-
|
|
7337
|
+
function snapshotPrincipal(principal) {
|
|
7338
|
+
if (!principal) return null;
|
|
7339
|
+
const copy = { ...principal };
|
|
7340
|
+
if (principal.roles) copy.roles = Object.freeze([...principal.roles]);
|
|
7341
|
+
if (principal.scopes) copy.scopes = Object.freeze([...principal.scopes]);
|
|
7342
|
+
return Object.freeze(copy);
|
|
7343
|
+
}
|
|
7344
|
+
function identityOf(principal) {
|
|
7345
|
+
const identity = principal?.identity;
|
|
7346
|
+
if (!identity || typeof identity.issuer !== "string" || typeof identity.subject !== "string") return null;
|
|
7347
|
+
return Object.freeze({
|
|
7348
|
+
issuer: identity.issuer,
|
|
7349
|
+
subject: identity.subject,
|
|
7350
|
+
...typeof identity.clientId === "string" ? { clientId: identity.clientId } : {}
|
|
7351
|
+
});
|
|
7352
|
+
}
|
|
7353
|
+
async function audit(input, principal, outcome, error) {
|
|
7354
|
+
if (!options.onToolCall) return;
|
|
7355
|
+
try {
|
|
7356
|
+
await options.onToolCall(Object.freeze({
|
|
7357
|
+
tool: String(input.name).slice(0, 256),
|
|
7358
|
+
principal: snapshotPrincipal(principal),
|
|
7359
|
+
identity: identityOf(principal),
|
|
7360
|
+
outcome,
|
|
7361
|
+
...error ? { error: Object.freeze({ ...error }) } : {}
|
|
7362
|
+
}));
|
|
7363
|
+
} catch (hookError) {
|
|
7364
|
+
try {
|
|
7365
|
+
options.onToolCallHookError?.(hookError);
|
|
7366
|
+
} catch {}
|
|
7367
|
+
}
|
|
7368
|
+
}
|
|
7369
|
+
function deniedInfo(error) {
|
|
7370
|
+
return {
|
|
7371
|
+
code: error.metadata.code ?? (error.status === 404 ? "mcp_tool_not_found" : error.status === 401 ? "mcp_authentication_required" : "mcp_access_denied"),
|
|
7372
|
+
message: error.message
|
|
7373
|
+
};
|
|
7374
|
+
}
|
|
7375
|
+
async function audited(input, run) {
|
|
7376
|
+
const principal = principalForCall(input);
|
|
7377
|
+
let authorized;
|
|
7378
|
+
try {
|
|
7379
|
+
authorized = await authorizeCall(input);
|
|
7356
7380
|
} catch (error) {
|
|
7357
|
-
if (error instanceof McpAccessError)
|
|
7358
|
-
|
|
7359
|
-
|
|
7360
|
-
|
|
7361
|
-
|
|
7362
|
-
|
|
7363
|
-
|
|
7364
|
-
|
|
7365
|
-
|
|
7366
|
-
|
|
7381
|
+
if (error instanceof McpAccessError) await audit(input, principal, "denied", deniedInfo(error));
|
|
7382
|
+
else await audit(input, principal, "error", safeMcpToolError(error));
|
|
7383
|
+
throw error;
|
|
7384
|
+
}
|
|
7385
|
+
let result;
|
|
7386
|
+
try {
|
|
7387
|
+
result = await run(authorized);
|
|
7388
|
+
} catch (error) {
|
|
7389
|
+
if (error instanceof McpAccessError) await audit(input, principal, "denied", deniedInfo(error));
|
|
7390
|
+
else await audit(input, principal, "error", safeMcpToolError(error));
|
|
7391
|
+
throw error;
|
|
7367
7392
|
}
|
|
7368
|
-
|
|
7369
|
-
|
|
7370
|
-
|
|
7371
|
-
|
|
7372
|
-
|
|
7393
|
+
if (result.response.isError) await audit(input, principal, "error", result.failure ?? failureOf(result.response));
|
|
7394
|
+
else await audit(input, principal, "ok");
|
|
7395
|
+
return result.response;
|
|
7396
|
+
}
|
|
7397
|
+
function failureOf(response) {
|
|
7398
|
+
const error = response.structuredContent?.error;
|
|
7399
|
+
return safeMcpToolError(void 0, () => typeof error?.code === "string" && typeof error?.message === "string" ? {
|
|
7400
|
+
code: error.code,
|
|
7401
|
+
message: error.message
|
|
7402
|
+
} : void 0);
|
|
7403
|
+
}
|
|
7404
|
+
async function callTool(input) {
|
|
7405
|
+
return audited(input, async ({ args, principal }) => {
|
|
7406
|
+
const workflowTool = workflowToolsByName.get(input.name);
|
|
7407
|
+
if (workflowTool) try {
|
|
7408
|
+
return { response: await workflowTool.execute({
|
|
7409
|
+
arguments: args,
|
|
7410
|
+
principal
|
|
7411
|
+
}) };
|
|
7412
|
+
} catch (error) {
|
|
7413
|
+
if (error instanceof McpAccessError) throw error;
|
|
7414
|
+
const typed = authoredMcpToolError(error, workflowTool.mapError);
|
|
7415
|
+
const message = typed?.message ?? "Workflow execution failed.";
|
|
7416
|
+
return {
|
|
7417
|
+
failure: typed ?? safeMcpToolError(error),
|
|
7418
|
+
response: {
|
|
7419
|
+
isError: true,
|
|
7420
|
+
content: [{
|
|
7421
|
+
type: "text",
|
|
7422
|
+
text: message
|
|
7423
|
+
}],
|
|
7424
|
+
structuredContent: { error: typed ?? { message } }
|
|
7425
|
+
}
|
|
7426
|
+
};
|
|
7373
7427
|
}
|
|
7428
|
+
return { response: await makeGenerator(principal).handleToolCall({
|
|
7429
|
+
method: "tools/call",
|
|
7430
|
+
params: {
|
|
7431
|
+
arguments: args,
|
|
7432
|
+
name: input.name
|
|
7433
|
+
}
|
|
7434
|
+
}) };
|
|
7374
7435
|
});
|
|
7375
7436
|
}
|
|
7376
7437
|
async function hasTaskSupport() {
|
|
@@ -7388,14 +7449,15 @@ function createMcpAppServer(options) {
|
|
|
7388
7449
|
return makeGenerator().supportsTaskTool(name);
|
|
7389
7450
|
}
|
|
7390
7451
|
async function callTask(input) {
|
|
7391
|
-
|
|
7392
|
-
|
|
7393
|
-
|
|
7394
|
-
|
|
7395
|
-
|
|
7396
|
-
|
|
7397
|
-
|
|
7398
|
-
|
|
7452
|
+
return audited(input, async ({ args, principal }) => {
|
|
7453
|
+
if (workflowToolsByName.has(input.name)) throw new McpAccessError(400, "Workflow MCP tools do not support tasks.");
|
|
7454
|
+
return { response: await makeGenerator(principal, await taskStoreFor(principal)).createTask({
|
|
7455
|
+
method: "tools/call",
|
|
7456
|
+
params: {
|
|
7457
|
+
arguments: args,
|
|
7458
|
+
name: input.name
|
|
7459
|
+
}
|
|
7460
|
+
}) };
|
|
7399
7461
|
});
|
|
7400
7462
|
}
|
|
7401
7463
|
async function taskOrigin(taskId, principal) {
|
|
@@ -7676,6 +7738,6 @@ function assertExtensionMetadata(value) {
|
|
|
7676
7738
|
for (const [name, entry] of Object.entries(value)) if (!name.trim() || !entry || typeof entry !== "object" || Array.isArray(entry)) throw new TypeError("Expected named extension object.");
|
|
7677
7739
|
}
|
|
7678
7740
|
//#endregion
|
|
7679
|
-
export {
|
|
7741
|
+
export { MCP_APP_RESOURCE_MAX_BYTES as _, createDefaultMcpAppServer as a, createMcpWorkflowTool as b, createMcpAppServer as c, isAllowedCoreTool as d, isPublicMcpTool as f, mcpToolEffect as g, matchesToolPattern as h, DEFAULT_MCP_APP_SERVER_INFO as i, MCP_TOOL_EFFECTS as l, isReadOnlyToolName as m, createMcpProtocolServer as n, mcpAllowedClassNames as o, isPublicToolName as p, createMcpProtocolServerForRequest as r, mcpPrincipalScopePolicy as s, MCP_TASKS_EXTENSION as t, classNamePrefixes as u, MCP_APP_RESOURCE_MIME as v, prepareMcpAppResource as y };
|
|
7680
7742
|
|
|
7681
|
-
//# sourceMappingURL=protocol-
|
|
7743
|
+
//# sourceMappingURL=protocol-BRQji5k_.js.map
|