@frontmcp/plugin-codecall 1.0.4 → 1.1.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/index.js CHANGED
@@ -56,19 +56,19 @@ module.exports = __toCommonJS(index_exports);
56
56
  var import_sdk7 = require("@frontmcp/sdk");
57
57
 
58
58
  // plugins/plugin-codecall/src/codecall.types.ts
59
- var import_zod = require("zod");
60
- var directCallsFilterSchema = import_zod.z.custom((val) => typeof val === "function", {
59
+ var import_lazy_zod = require("@frontmcp/lazy-zod");
60
+ var directCallsFilterSchema = import_lazy_zod.z.custom((val) => typeof val === "function", {
61
61
  message: "filter must be a function with signature (tool: DirectCallsFilterToolInfo) => boolean"
62
62
  });
63
- var includeToolsFilterSchema = import_zod.z.custom((val) => typeof val === "function", {
63
+ var includeToolsFilterSchema = import_lazy_zod.z.custom((val) => typeof val === "function", {
64
64
  message: "includeTools must be a function with signature (tool: IncludeToolsFilterToolInfo) => boolean"
65
65
  });
66
- var codeCallModeSchema = import_zod.z.enum(["codecall_only", "codecall_opt_in", "metadata_driven"]).default("codecall_only");
67
- var codeCallVmPresetSchema = import_zod.z.enum(["locked_down", "secure", "balanced", "experimental"]).default("secure");
66
+ var codeCallModeSchema = import_lazy_zod.z.enum(["codecall_only", "codecall_opt_in", "metadata_driven"]).default("codecall_only");
67
+ var codeCallVmPresetSchema = import_lazy_zod.z.enum(["locked_down", "secure", "balanced", "experimental"]).default("secure");
68
68
  var DEFAULT_VM_OPTIONS = {
69
69
  preset: "secure"
70
70
  };
71
- var codeCallVmOptionsSchema = import_zod.z.object({
71
+ var codeCallVmOptionsSchema = import_lazy_zod.z.object({
72
72
  /**
73
73
  * CSP-like preset; see README.
74
74
  * @default 'secure'
@@ -78,86 +78,86 @@ var codeCallVmOptionsSchema = import_zod.z.object({
78
78
  * Timeout for script execution in milliseconds
79
79
  * Defaults vary by preset
80
80
  */
81
- timeoutMs: import_zod.z.number().positive().optional(),
81
+ timeoutMs: import_lazy_zod.z.number().positive().optional(),
82
82
  /**
83
83
  * Allow loop constructs (for, while, do-while)
84
84
  * Defaults vary by preset
85
85
  */
86
- allowLoops: import_zod.z.boolean().optional(),
86
+ allowLoops: import_lazy_zod.z.boolean().optional(),
87
87
  /**
88
88
  * Maximum number of steps (if applicable)
89
89
  * Defaults vary by preset
90
90
  */
91
- maxSteps: import_zod.z.number().positive().optional(),
91
+ maxSteps: import_lazy_zod.z.number().positive().optional(),
92
92
  /**
93
93
  * List of disabled builtin functions
94
94
  * Defaults vary by preset
95
95
  */
96
- disabledBuiltins: import_zod.z.array(import_zod.z.string()).optional(),
96
+ disabledBuiltins: import_lazy_zod.z.array(import_lazy_zod.z.string()).optional(),
97
97
  /**
98
98
  * List of disabled global variables
99
99
  * Defaults vary by preset
100
100
  */
101
- disabledGlobals: import_zod.z.array(import_zod.z.string()).optional(),
101
+ disabledGlobals: import_lazy_zod.z.array(import_lazy_zod.z.string()).optional(),
102
102
  /**
103
103
  * Allow console.log/warn/error
104
104
  * Defaults vary by preset
105
105
  */
106
- allowConsole: import_zod.z.boolean().optional(),
106
+ allowConsole: import_lazy_zod.z.boolean().optional(),
107
107
  /**
108
108
  * Maximum nesting depth for sanitized output values
109
109
  * Prevents deeply nested objects from causing stack overflow
110
110
  * @default varies by preset (secure: 50)
111
111
  */
112
- maxSanitizeDepth: import_zod.z.number().positive().optional(),
112
+ maxSanitizeDepth: import_lazy_zod.z.number().positive().optional(),
113
113
  /**
114
114
  * Maximum properties per object in sanitized output values
115
115
  * Limits array sizes and object keys in return values
116
116
  * @default varies by preset (secure: 2000)
117
117
  */
118
- maxSanitizeProperties: import_zod.z.number().positive().optional()
118
+ maxSanitizeProperties: import_lazy_zod.z.number().positive().optional()
119
119
  }).default(() => DEFAULT_VM_OPTIONS);
120
- var codeCallDirectCallsOptionsSchema = import_zod.z.object({
120
+ var codeCallDirectCallsOptionsSchema = import_lazy_zod.z.object({
121
121
  /**
122
122
  * Enable/disable the `codecall.invoke` meta-tool.
123
123
  */
124
- enabled: import_zod.z.boolean(),
124
+ enabled: import_lazy_zod.z.boolean(),
125
125
  /**
126
126
  * Optional allowlist of tool names.
127
127
  */
128
- allowedTools: import_zod.z.array(import_zod.z.string()).optional(),
128
+ allowedTools: import_lazy_zod.z.array(import_lazy_zod.z.string()).optional(),
129
129
  /**
130
130
  * Optional advanced filter function.
131
131
  * Signature: (tool: DirectCallsFilterToolInfo) => boolean
132
132
  */
133
133
  filter: directCallsFilterSchema.optional()
134
134
  });
135
- var embeddingStrategySchema = import_zod.z.enum(["tfidf", "ml"]).default("tfidf");
136
- var synonymExpansionConfigSchema = import_zod.z.object({
135
+ var embeddingStrategySchema = import_lazy_zod.z.enum(["tfidf", "ml"]).default("tfidf");
136
+ var synonymExpansionConfigSchema = import_lazy_zod.z.object({
137
137
  /**
138
138
  * Enable/disable synonym expansion for TF-IDF search.
139
139
  * When enabled, queries are expanded with synonyms to improve relevance.
140
140
  * For example, "add user" will also match tools containing "create user".
141
141
  * @default true
142
142
  */
143
- enabled: import_zod.z.boolean().default(true),
143
+ enabled: import_lazy_zod.z.boolean().default(true),
144
144
  /**
145
145
  * Additional synonym groups beyond the defaults.
146
146
  * Each group is an array of related terms that should be treated as equivalent.
147
147
  * @example [['customer', 'client', 'buyer'], ['order', 'purchase', 'transaction']]
148
148
  */
149
- additionalSynonyms: import_zod.z.array(import_zod.z.array(import_zod.z.string())).optional(),
149
+ additionalSynonyms: import_lazy_zod.z.array(import_lazy_zod.z.array(import_lazy_zod.z.string())).optional(),
150
150
  /**
151
151
  * Replace default synonyms entirely with additionalSynonyms.
152
152
  * @default false
153
153
  */
154
- replaceDefaults: import_zod.z.boolean().default(false),
154
+ replaceDefaults: import_lazy_zod.z.boolean().default(false),
155
155
  /**
156
156
  * Maximum number of synonym expansions per term.
157
157
  * Prevents query explosion for terms with many synonyms.
158
158
  * @default 5
159
159
  */
160
- maxExpansionsPerTerm: import_zod.z.number().positive().default(5)
160
+ maxExpansionsPerTerm: import_lazy_zod.z.number().positive().default(5)
161
161
  }).default({ enabled: true, replaceDefaults: false, maxExpansionsPerTerm: 5 });
162
162
  var DEFAULT_EMBEDDING_OPTIONS = {
163
163
  strategy: "tfidf",
@@ -166,7 +166,7 @@ var DEFAULT_EMBEDDING_OPTIONS = {
166
166
  useHNSW: false,
167
167
  synonymExpansion: { enabled: true, replaceDefaults: false, maxExpansionsPerTerm: 5 }
168
168
  };
169
- var codeCallEmbeddingOptionsSchema = import_zod.z.object({
169
+ var codeCallEmbeddingOptionsSchema = import_lazy_zod.z.object({
170
170
  /**
171
171
  * Embedding strategy to use for tool search
172
172
  * - 'tfidf': Lightweight, synchronous TF-IDF based search (no ML models required)
@@ -178,18 +178,18 @@ var codeCallEmbeddingOptionsSchema = import_zod.z.object({
178
178
  * Model name for ML-based embeddings (only used when strategy='ml')
179
179
  * @default 'Xenova/all-MiniLM-L6-v2'
180
180
  */
181
- modelName: import_zod.z.string().optional(),
181
+ modelName: import_lazy_zod.z.string().optional(),
182
182
  /**
183
183
  * Cache directory for ML models (only used when strategy='ml')
184
184
  * @default './.cache/transformers'
185
185
  */
186
- cacheDir: import_zod.z.string().optional(),
186
+ cacheDir: import_lazy_zod.z.string().optional(),
187
187
  /**
188
188
  * Enable HNSW index for faster search (only used when strategy='ml')
189
189
  * When enabled, provides O(log n) search instead of O(n) brute-force
190
190
  * @default false
191
191
  */
192
- useHNSW: import_zod.z.boolean().optional(),
192
+ useHNSW: import_lazy_zod.z.boolean().optional(),
193
193
  /**
194
194
  * Synonym expansion configuration for TF-IDF search.
195
195
  * When enabled, queries like "add user" will match tools for "create user".
@@ -197,7 +197,7 @@ var codeCallEmbeddingOptionsSchema = import_zod.z.object({
197
197
  * Set to false to disable, or provide a config object to customize.
198
198
  * @default { enabled: true }
199
199
  */
200
- synonymExpansion: import_zod.z.union([import_zod.z.literal(false), synonymExpansionConfigSchema]).optional()
200
+ synonymExpansion: import_lazy_zod.z.union([import_lazy_zod.z.literal(false), synonymExpansionConfigSchema]).optional()
201
201
  }).optional().transform((opts) => ({
202
202
  strategy: opts?.strategy ?? DEFAULT_EMBEDDING_OPTIONS.strategy,
203
203
  modelName: opts?.modelName ?? DEFAULT_EMBEDDING_OPTIONS.modelName,
@@ -205,53 +205,53 @@ var codeCallEmbeddingOptionsSchema = import_zod.z.object({
205
205
  useHNSW: opts?.useHNSW ?? DEFAULT_EMBEDDING_OPTIONS.useHNSW,
206
206
  synonymExpansion: opts?.synonymExpansion ?? DEFAULT_EMBEDDING_OPTIONS.synonymExpansion
207
207
  }));
208
- var codeCallSidecarOptionsSchema = import_zod.z.object({
208
+ var codeCallSidecarOptionsSchema = import_lazy_zod.z.object({
209
209
  /**
210
210
  * Enable pass-by-reference support via sidecar
211
211
  * When enabled, large strings are automatically lifted to a sidecar
212
212
  * and resolved at the callTool boundary
213
213
  * @default false
214
214
  */
215
- enabled: import_zod.z.boolean().default(false),
215
+ enabled: import_lazy_zod.z.boolean().default(false),
216
216
  /**
217
217
  * Maximum total size of all stored references in bytes
218
218
  * @default 16MB (from security level)
219
219
  */
220
- maxTotalSize: import_zod.z.number().positive().optional(),
220
+ maxTotalSize: import_lazy_zod.z.number().positive().optional(),
221
221
  /**
222
222
  * Maximum size of a single reference in bytes
223
223
  * @default 4MB (from security level)
224
224
  */
225
- maxReferenceSize: import_zod.z.number().positive().optional(),
225
+ maxReferenceSize: import_lazy_zod.z.number().positive().optional(),
226
226
  /**
227
227
  * Threshold in bytes to trigger extraction from source code
228
228
  * Strings larger than this are lifted to the sidecar
229
229
  * @default 64KB (from security level)
230
230
  */
231
- extractionThreshold: import_zod.z.number().positive().optional(),
231
+ extractionThreshold: import_lazy_zod.z.number().positive().optional(),
232
232
  /**
233
233
  * Maximum expanded size when resolving references for tool calls
234
234
  * @default 8MB (from security level)
235
235
  */
236
- maxResolvedSize: import_zod.z.number().positive().optional(),
236
+ maxResolvedSize: import_lazy_zod.z.number().positive().optional(),
237
237
  /**
238
238
  * Whether to allow composite handles from string concatenation
239
239
  * If false, concatenating references throws an error
240
240
  * @default false (strict mode)
241
241
  */
242
- allowComposites: import_zod.z.boolean().optional(),
242
+ allowComposites: import_lazy_zod.z.boolean().optional(),
243
243
  /**
244
244
  * Maximum script length (in characters) when sidecar is disabled
245
245
  * Prevents large inline data from being embedded in script
246
246
  * If null, no limit is enforced
247
247
  * @default 64KB
248
248
  */
249
- maxScriptLengthWhenDisabled: import_zod.z.number().positive().nullable().default(64 * 1024)
249
+ maxScriptLengthWhenDisabled: import_lazy_zod.z.number().positive().nullable().default(64 * 1024)
250
250
  }).default(() => ({
251
251
  enabled: false,
252
252
  maxScriptLengthWhenDisabled: 64 * 1024
253
253
  }));
254
- var codeCallPluginOptionsObjectSchema = import_zod.z.object({
254
+ var codeCallPluginOptionsObjectSchema = import_lazy_zod.z.object({
255
255
  /**
256
256
  * CodeCall mode
257
257
  * @default 'codecall_only'
@@ -263,17 +263,17 @@ var codeCallPluginOptionsObjectSchema = import_zod.z.object({
263
263
  * When unset (default), all tools in the server are affected.
264
264
  * @example ['ecommerce'] — only hide ecommerce app tools, keep calc tools visible
265
265
  */
266
- appIds: import_zod.z.array(import_zod.z.string()).optional(),
266
+ appIds: import_lazy_zod.z.array(import_lazy_zod.z.string()).optional(),
267
267
  /**
268
268
  * Default number of tools to return in search results
269
269
  * @default 8
270
270
  */
271
- topK: import_zod.z.number().positive().default(8),
271
+ topK: import_lazy_zod.z.number().positive().default(8),
272
272
  /**
273
273
  * Maximum number of tool definitions to include
274
274
  * @default 8
275
275
  */
276
- maxDefinitions: import_zod.z.number().positive().default(8),
276
+ maxDefinitions: import_lazy_zod.z.number().positive().default(8),
277
277
  /**
278
278
  * Optional filter function for including tools.
279
279
  * Signature: (tool: IncludeToolsFilterToolInfo) => boolean
@@ -1386,7 +1386,7 @@ EnclaveService = __decorateClass([
1386
1386
  var import_sdk2 = require("@frontmcp/sdk");
1387
1387
 
1388
1388
  // plugins/plugin-codecall/src/tools/search.schema.ts
1389
- var import_zod2 = require("zod");
1389
+ var import_lazy_zod2 = require("@frontmcp/lazy-zod");
1390
1390
  var searchToolDescription = `Find tools by splitting user request into atomic actions.
1391
1391
 
1392
1392
  DECOMPOSE: "delete users and send email" \u2192 queries: ["delete user", "send email"]
@@ -1406,30 +1406,30 @@ OUTPUT: Flat deduplicated tool list. relevanceScore: 0.5+=good, 0.7+=strong matc
1406
1406
 
1407
1407
  FLOW: search \u2192 describe \u2192 execute/invoke`;
1408
1408
  var searchToolInputSchema = {
1409
- queries: import_zod2.z.array(import_zod2.z.string().min(2).max(256)).min(1).max(10).describe("Atomic action queries. Split complex requests into simple actions."),
1410
- appIds: import_zod2.z.array(import_zod2.z.string()).max(10).optional().describe("Filter by app IDs"),
1411
- excludeToolNames: import_zod2.z.array(import_zod2.z.string()).max(50).optional().describe("Skip already-known tool names"),
1412
- topK: import_zod2.z.number().int().positive().max(50).optional().default(10).describe("Results per query (default 10)"),
1413
- minRelevanceScore: import_zod2.z.number().min(0).max(1).optional().default(0.1).describe("Minimum relevance threshold (default 0.1)")
1409
+ queries: import_lazy_zod2.z.array(import_lazy_zod2.z.string().min(2).max(256)).min(1).max(10).describe("Atomic action queries. Split complex requests into simple actions."),
1410
+ appIds: import_lazy_zod2.z.array(import_lazy_zod2.z.string()).max(10).optional().describe("Filter by app IDs"),
1411
+ excludeToolNames: import_lazy_zod2.z.array(import_lazy_zod2.z.string()).max(50).optional().describe("Skip already-known tool names"),
1412
+ topK: import_lazy_zod2.z.number().int().positive().max(50).optional().default(10).describe("Results per query (default 10)"),
1413
+ minRelevanceScore: import_lazy_zod2.z.number().min(0).max(1).optional().default(0.1).describe("Minimum relevance threshold (default 0.1)")
1414
1414
  };
1415
- var searchToolOutputSchema = import_zod2.z.object({
1416
- tools: import_zod2.z.array(
1417
- import_zod2.z.object({
1418
- name: import_zod2.z.string().describe('Tool name (e.g., "users:list")'),
1419
- appId: import_zod2.z.string().optional().describe("App ID"),
1420
- description: import_zod2.z.string().describe("What this tool does"),
1421
- relevanceScore: import_zod2.z.number().min(0).max(1).describe("Match score (0-1)"),
1422
- matchedQueries: import_zod2.z.array(import_zod2.z.string()).describe("Which queries matched this tool")
1415
+ var searchToolOutputSchema = import_lazy_zod2.z.object({
1416
+ tools: import_lazy_zod2.z.array(
1417
+ import_lazy_zod2.z.object({
1418
+ name: import_lazy_zod2.z.string().describe('Tool name (e.g., "users:list")'),
1419
+ appId: import_lazy_zod2.z.string().optional().describe("App ID"),
1420
+ description: import_lazy_zod2.z.string().describe("What this tool does"),
1421
+ relevanceScore: import_lazy_zod2.z.number().min(0).max(1).describe("Match score (0-1)"),
1422
+ matchedQueries: import_lazy_zod2.z.array(import_lazy_zod2.z.string()).describe("Which queries matched this tool")
1423
1423
  })
1424
1424
  ).describe("Deduplicated tools sorted by relevance"),
1425
- warnings: import_zod2.z.array(
1426
- import_zod2.z.object({
1427
- type: import_zod2.z.enum(["excluded_tool_not_found", "no_results", "low_relevance"]).describe("Warning type"),
1428
- message: import_zod2.z.string().describe("Warning message"),
1429
- affectedTools: import_zod2.z.array(import_zod2.z.string()).optional().describe("Affected tool names")
1425
+ warnings: import_lazy_zod2.z.array(
1426
+ import_lazy_zod2.z.object({
1427
+ type: import_lazy_zod2.z.enum(["excluded_tool_not_found", "no_results", "low_relevance"]).describe("Warning type"),
1428
+ message: import_lazy_zod2.z.string().describe("Warning message"),
1429
+ affectedTools: import_lazy_zod2.z.array(import_lazy_zod2.z.string()).optional().describe("Affected tool names")
1430
1430
  })
1431
1431
  ).describe("Search warnings"),
1432
- totalAvailableTools: import_zod2.z.number().int().nonnegative().describe("Total tools in index")
1432
+ totalAvailableTools: import_lazy_zod2.z.number().int().nonnegative().describe("Total tools in index")
1433
1433
  });
1434
1434
 
1435
1435
  // plugins/plugin-codecall/src/tools/search.tool.ts
@@ -1523,61 +1523,86 @@ SearchTool = __decorateClass([
1523
1523
  ], SearchTool);
1524
1524
 
1525
1525
  // plugins/plugin-codecall/src/tools/describe.tool.ts
1526
+ var import_lazy_zod4 = require("@frontmcp/lazy-zod");
1526
1527
  var import_sdk3 = require("@frontmcp/sdk");
1527
- var import_v4 = require("zod/v4");
1528
- var import_zod4 = require("zod");
1529
1528
 
1530
- // plugins/plugin-codecall/src/tools/describe.schema.ts
1531
- var import_zod3 = require("zod");
1532
- var import_protocol = require("@frontmcp/protocol");
1533
- var describeToolDescription = `Get input/output schemas for tools from search results.
1534
-
1535
- INPUT: toolNames: string[] - tool names from search
1536
- OUTPUT per tool: inputSchema (JSON Schema), outputSchema (JSON Schema), usageExamples (up to 5 callTool examples)
1537
-
1538
- IMPORTANT: If notFound array is non-empty \u2192 re-search with corrected queries.
1539
- FLOW: search \u2192 describe \u2192 execute/invoke`;
1540
- var describeToolInputSchema = {
1541
- toolNames: import_zod3.z.array(import_zod3.z.string()).min(1).superRefine((toolNames, ctx) => {
1542
- const seen = /* @__PURE__ */ new Set();
1543
- const duplicates = /* @__PURE__ */ new Set();
1544
- for (const name of toolNames) {
1545
- if (seen.has(name)) {
1546
- duplicates.add(name);
1547
- }
1548
- seen.add(name);
1549
- }
1550
- if (duplicates.size > 0) {
1551
- ctx.addIssue({
1552
- code: import_zod3.z.ZodIssueCode.custom,
1553
- message: `Duplicate tool names are not allowed: ${Array.from(duplicates).join(", ")}`
1554
- });
1555
- }
1556
- }).describe(
1557
- 'Array of unique tool names (from codecall:search results) to fetch their detailed schemas and usage examples. Example: ["users:list", "billing:getInvoice"]'
1558
- )
1529
+ // plugins/plugin-codecall/src/errors/tool-call.errors.ts
1530
+ var TOOL_CALL_ERROR_CODES = {
1531
+ NOT_FOUND: "NOT_FOUND",
1532
+ VALIDATION: "VALIDATION",
1533
+ EXECUTION: "EXECUTION",
1534
+ TIMEOUT: "TIMEOUT",
1535
+ ACCESS_DENIED: "ACCESS_DENIED",
1536
+ SELF_REFERENCE: "SELF_REFERENCE"
1559
1537
  };
1560
- var describeToolOutputSchema = import_zod3.z.object({
1561
- tools: import_zod3.z.array(
1562
- import_zod3.z.object({
1563
- name: import_zod3.z.string().describe("Tool name to be used in callTool() within codecall:execute scripts"),
1564
- appId: import_zod3.z.string().describe("The app ID this tool belongs to"),
1565
- description: import_zod3.z.string().describe("Detailed description of what this tool does"),
1566
- inputSchema: import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()).nullable().describe("JSON Schema object describing the tool input parameters"),
1567
- outputSchema: import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()).nullable().describe("JSON Schema object describing the tool output structure"),
1568
- annotations: import_protocol.ToolAnnotationsSchema.optional().describe("MCP tool annotations (metadata)"),
1569
- usageExamples: import_zod3.z.array(
1570
- import_zod3.z.object({
1571
- description: import_zod3.z.string().describe("Description of what this example demonstrates"),
1572
- code: import_zod3.z.string().describe(
1573
- 'JavaScript code example showing how to call this tool using callTool(). Format: const result = await callTool("tool:name", { ...params });'
1574
- )
1575
- })
1576
- ).max(5).describe("Up to 5 practical examples of how to use this tool in a codecall:execute script")
1577
- })
1578
- ).describe("Array of tool descriptions with schemas and usage examples"),
1579
- notFound: import_zod3.z.array(import_zod3.z.string()).optional().describe("Tool names that were requested but not found in the index. Check these for typos.")
1580
- });
1538
+ function createToolCallError(code, toolName, rawMessage) {
1539
+ const sanitizedMessage = getSanitizedMessage(code, toolName, rawMessage);
1540
+ return Object.freeze({
1541
+ code,
1542
+ message: sanitizedMessage,
1543
+ toolName
1544
+ });
1545
+ }
1546
+ function getSanitizedMessage(code, toolName, rawMessage) {
1547
+ switch (code) {
1548
+ case TOOL_CALL_ERROR_CODES.NOT_FOUND:
1549
+ return `Tool "${toolName}" was not found`;
1550
+ case TOOL_CALL_ERROR_CODES.VALIDATION:
1551
+ return rawMessage ? sanitizeValidationMessage(rawMessage) : `Input validation failed for tool "${toolName}"`;
1552
+ case TOOL_CALL_ERROR_CODES.EXECUTION:
1553
+ return `Tool "${toolName}" execution failed`;
1554
+ case TOOL_CALL_ERROR_CODES.TIMEOUT:
1555
+ return `Tool "${toolName}" execution timed out`;
1556
+ case TOOL_CALL_ERROR_CODES.ACCESS_DENIED:
1557
+ return `Access denied for tool "${toolName}"`;
1558
+ case TOOL_CALL_ERROR_CODES.SELF_REFERENCE:
1559
+ return `Cannot call CodeCall tools from within AgentScript`;
1560
+ default:
1561
+ return `An error occurred while calling "${toolName}"`;
1562
+ }
1563
+ }
1564
+ function sanitizeValidationMessage(message) {
1565
+ let sanitized = message.replace(/(?:\/[\w.-]+)+|(?:[A-Za-z]:\\[\w\\.-]+)+/g, "[path]");
1566
+ sanitized = sanitized.replace(/\bat line \d+/gi, "");
1567
+ sanitized = sanitized.replace(/\bline \d+/gi, "");
1568
+ sanitized = sanitized.replace(/:\d+:\d+/g, "");
1569
+ sanitized = sanitized.replace(/\n\s*at .*/g, "");
1570
+ if (sanitized.length > 200) {
1571
+ sanitized = sanitized.substring(0, 200) + "...";
1572
+ }
1573
+ return sanitized.trim();
1574
+ }
1575
+ var SelfReferenceError = class extends Error {
1576
+ code = TOOL_CALL_ERROR_CODES.SELF_REFERENCE;
1577
+ toolName;
1578
+ constructor(toolName) {
1579
+ super(`Self-reference attack: Attempted to call CodeCall tool "${toolName}" from within AgentScript`);
1580
+ this.name = "SelfReferenceError";
1581
+ this.toolName = toolName;
1582
+ Object.freeze(this);
1583
+ }
1584
+ };
1585
+
1586
+ // plugins/plugin-codecall/src/security/self-reference-guard.ts
1587
+ var CODECALL_TOOL_PREFIX = "codecall:";
1588
+ var BLOCKED_CODECALL_TOOLS = Object.freeze(
1589
+ /* @__PURE__ */ new Set(["codecall:search", "codecall:describe", "codecall:execute", "codecall:invoke"])
1590
+ );
1591
+ function isBlockedSelfReference(toolName) {
1592
+ const normalizedName = toolName.toLowerCase().trim();
1593
+ if (normalizedName.startsWith(CODECALL_TOOL_PREFIX)) {
1594
+ return true;
1595
+ }
1596
+ if (BLOCKED_CODECALL_TOOLS.has(toolName)) {
1597
+ return true;
1598
+ }
1599
+ return false;
1600
+ }
1601
+ function assertNotSelfReference(toolName) {
1602
+ if (isBlockedSelfReference(toolName)) {
1603
+ throw new SelfReferenceError(toolName);
1604
+ }
1605
+ }
1581
1606
 
1582
1607
  // plugins/plugin-codecall/src/utils/describe.utils.ts
1583
1608
  var INTENT_PATTERNS = {
@@ -1867,83 +1892,57 @@ function extractResultFromCallToolResult(mcpResult) {
1867
1892
  return content;
1868
1893
  }
1869
1894
 
1870
- // plugins/plugin-codecall/src/errors/tool-call.errors.ts
1871
- var TOOL_CALL_ERROR_CODES = {
1872
- NOT_FOUND: "NOT_FOUND",
1873
- VALIDATION: "VALIDATION",
1874
- EXECUTION: "EXECUTION",
1875
- TIMEOUT: "TIMEOUT",
1876
- ACCESS_DENIED: "ACCESS_DENIED",
1877
- SELF_REFERENCE: "SELF_REFERENCE"
1878
- };
1879
- function createToolCallError(code, toolName, rawMessage) {
1880
- const sanitizedMessage = getSanitizedMessage(code, toolName, rawMessage);
1881
- return Object.freeze({
1882
- code,
1883
- message: sanitizedMessage,
1884
- toolName
1885
- });
1886
- }
1887
- function getSanitizedMessage(code, toolName, rawMessage) {
1888
- switch (code) {
1889
- case TOOL_CALL_ERROR_CODES.NOT_FOUND:
1890
- return `Tool "${toolName}" was not found`;
1891
- case TOOL_CALL_ERROR_CODES.VALIDATION:
1892
- return rawMessage ? sanitizeValidationMessage(rawMessage) : `Input validation failed for tool "${toolName}"`;
1893
- case TOOL_CALL_ERROR_CODES.EXECUTION:
1894
- return `Tool "${toolName}" execution failed`;
1895
- case TOOL_CALL_ERROR_CODES.TIMEOUT:
1896
- return `Tool "${toolName}" execution timed out`;
1897
- case TOOL_CALL_ERROR_CODES.ACCESS_DENIED:
1898
- return `Access denied for tool "${toolName}"`;
1899
- case TOOL_CALL_ERROR_CODES.SELF_REFERENCE:
1900
- return `Cannot call CodeCall tools from within AgentScript`;
1901
- default:
1902
- return `An error occurred while calling "${toolName}"`;
1903
- }
1904
- }
1905
- function sanitizeValidationMessage(message) {
1906
- let sanitized = message.replace(/(?:\/[\w.-]+)+|(?:[A-Za-z]:\\[\w\\.-]+)+/g, "[path]");
1907
- sanitized = sanitized.replace(/\bat line \d+/gi, "");
1908
- sanitized = sanitized.replace(/\bline \d+/gi, "");
1909
- sanitized = sanitized.replace(/:\d+:\d+/g, "");
1910
- sanitized = sanitized.replace(/\n\s*at .*/g, "");
1911
- if (sanitized.length > 200) {
1912
- sanitized = sanitized.substring(0, 200) + "...";
1913
- }
1914
- return sanitized.trim();
1915
- }
1916
- var SelfReferenceError = class extends Error {
1917
- code = TOOL_CALL_ERROR_CODES.SELF_REFERENCE;
1918
- toolName;
1919
- constructor(toolName) {
1920
- super(`Self-reference attack: Attempted to call CodeCall tool "${toolName}" from within AgentScript`);
1921
- this.name = "SelfReferenceError";
1922
- this.toolName = toolName;
1923
- Object.freeze(this);
1924
- }
1925
- };
1895
+ // plugins/plugin-codecall/src/tools/describe.schema.ts
1896
+ var import_lazy_zod3 = require("@frontmcp/lazy-zod");
1897
+ var import_protocol = require("@frontmcp/protocol");
1898
+ var describeToolDescription = `Get input/output schemas for tools from search results.
1926
1899
 
1927
- // plugins/plugin-codecall/src/security/self-reference-guard.ts
1928
- var CODECALL_TOOL_PREFIX = "codecall:";
1929
- var BLOCKED_CODECALL_TOOLS = Object.freeze(
1930
- /* @__PURE__ */ new Set(["codecall:search", "codecall:describe", "codecall:execute", "codecall:invoke"])
1931
- );
1932
- function isBlockedSelfReference(toolName) {
1933
- const normalizedName = toolName.toLowerCase().trim();
1934
- if (normalizedName.startsWith(CODECALL_TOOL_PREFIX)) {
1935
- return true;
1936
- }
1937
- if (BLOCKED_CODECALL_TOOLS.has(toolName)) {
1938
- return true;
1939
- }
1940
- return false;
1941
- }
1942
- function assertNotSelfReference(toolName) {
1943
- if (isBlockedSelfReference(toolName)) {
1944
- throw new SelfReferenceError(toolName);
1945
- }
1946
- }
1900
+ INPUT: toolNames: string[] - tool names from search
1901
+ OUTPUT per tool: inputSchema (JSON Schema), outputSchema (JSON Schema), usageExamples (up to 5 callTool examples)
1902
+
1903
+ IMPORTANT: If notFound array is non-empty \u2192 re-search with corrected queries.
1904
+ FLOW: search \u2192 describe \u2192 execute/invoke`;
1905
+ var describeToolInputSchema = {
1906
+ toolNames: import_lazy_zod3.z.array(import_lazy_zod3.z.string()).min(1).superRefine((toolNames, ctx) => {
1907
+ const seen = /* @__PURE__ */ new Set();
1908
+ const duplicates = /* @__PURE__ */ new Set();
1909
+ for (const name of toolNames) {
1910
+ if (seen.has(name)) {
1911
+ duplicates.add(name);
1912
+ }
1913
+ seen.add(name);
1914
+ }
1915
+ if (duplicates.size > 0) {
1916
+ ctx.addIssue({
1917
+ code: import_lazy_zod3.z.ZodIssueCode.custom,
1918
+ message: `Duplicate tool names are not allowed: ${Array.from(duplicates).join(", ")}`
1919
+ });
1920
+ }
1921
+ }).describe(
1922
+ 'Array of unique tool names (from codecall:search results) to fetch their detailed schemas and usage examples. Example: ["users:list", "billing:getInvoice"]'
1923
+ )
1924
+ };
1925
+ var describeToolOutputSchema = import_lazy_zod3.z.object({
1926
+ tools: import_lazy_zod3.z.array(
1927
+ import_lazy_zod3.z.object({
1928
+ name: import_lazy_zod3.z.string().describe("Tool name to be used in callTool() within codecall:execute scripts"),
1929
+ appId: import_lazy_zod3.z.string().describe("The app ID this tool belongs to"),
1930
+ description: import_lazy_zod3.z.string().describe("Detailed description of what this tool does"),
1931
+ inputSchema: import_lazy_zod3.z.record(import_lazy_zod3.z.string(), import_lazy_zod3.z.unknown()).nullable().describe("JSON Schema object describing the tool input parameters"),
1932
+ outputSchema: import_lazy_zod3.z.record(import_lazy_zod3.z.string(), import_lazy_zod3.z.unknown()).nullable().describe("JSON Schema object describing the tool output structure"),
1933
+ annotations: import_protocol.ToolAnnotationsSchema.optional().describe("MCP tool annotations (metadata)"),
1934
+ usageExamples: import_lazy_zod3.z.array(
1935
+ import_lazy_zod3.z.object({
1936
+ description: import_lazy_zod3.z.string().describe("Description of what this example demonstrates"),
1937
+ code: import_lazy_zod3.z.string().describe(
1938
+ 'JavaScript code example showing how to call this tool using callTool(). Format: const result = await callTool("tool:name", { ...params });'
1939
+ )
1940
+ })
1941
+ ).max(5).describe("Up to 5 practical examples of how to use this tool in a codecall:execute script")
1942
+ })
1943
+ ).describe("Array of tool descriptions with schemas and usage examples"),
1944
+ notFound: import_lazy_zod3.z.array(import_lazy_zod3.z.string()).optional().describe("Tool names that were requested but not found in the index. Check these for typos.")
1945
+ });
1947
1946
 
1948
1947
  // plugins/plugin-codecall/src/tools/describe.tool.ts
1949
1948
  var DescribeTool = class extends import_sdk3.ToolContext {
@@ -1996,8 +1995,8 @@ var DescribeTool = class extends import_sdk3.ToolContext {
1996
1995
  if (tool.inputSchema && typeof tool.inputSchema === "object" && Object.keys(tool.inputSchema).length > 0) {
1997
1996
  try {
1998
1997
  const firstValue = Object.values(tool.inputSchema)[0];
1999
- if (firstValue instanceof import_zod4.ZodType) {
2000
- return (0, import_v4.toJSONSchema)(import_zod4.z.object(tool.inputSchema));
1998
+ if (firstValue instanceof import_lazy_zod4.ZodType) {
1999
+ return (0, import_lazy_zod4.toJSONSchema)(import_lazy_zod4.z.object(tool.inputSchema));
2001
2000
  }
2002
2001
  } catch {
2003
2002
  }
@@ -2017,9 +2016,9 @@ var DescribeTool = class extends import_sdk3.ToolContext {
2017
2016
  if (!schema) {
2018
2017
  return null;
2019
2018
  }
2020
- if (schema instanceof import_zod4.ZodType) {
2019
+ if (schema instanceof import_lazy_zod4.ZodType) {
2021
2020
  try {
2022
- return (0, import_v4.toJSONSchema)(schema);
2021
+ return (0, import_lazy_zod4.toJSONSchema)(schema);
2023
2022
  } catch {
2024
2023
  return null;
2025
2024
  }
@@ -2027,9 +2026,9 @@ var DescribeTool = class extends import_sdk3.ToolContext {
2027
2026
  if (typeof schema === "object" && schema !== null && !Array.isArray(schema)) {
2028
2027
  const obj = schema;
2029
2028
  const firstValue = Object.values(obj)[0];
2030
- if (firstValue instanceof import_zod4.ZodType) {
2029
+ if (firstValue instanceof import_lazy_zod4.ZodType) {
2031
2030
  try {
2032
- return (0, import_v4.toJSONSchema)(import_zod4.z.object(obj));
2031
+ return (0, import_lazy_zod4.toJSONSchema)(import_lazy_zod4.z.object(obj));
2033
2032
  } catch {
2034
2033
  return null;
2035
2034
  }
@@ -2117,7 +2116,7 @@ DescribeTool = __decorateClass([
2117
2116
  var import_sdk5 = require("@frontmcp/sdk");
2118
2117
 
2119
2118
  // plugins/plugin-codecall/src/tools/execute.schema.ts
2120
- var import_zod5 = require("zod");
2119
+ var import_lazy_zod5 = require("@frontmcp/lazy-zod");
2121
2120
  var MIN_EXECUTE_SCRIPT_LENGTH = 'return callTool("a",{})'.length;
2122
2121
  var executeToolDescription = `Execute AgentScript (safe JS subset) for multi-tool orchestration.
2123
2122
 
@@ -2141,72 +2140,72 @@ ERRORS: NOT_FOUND | VALIDATION | EXECUTION | TIMEOUT | ACCESS_DENIED
2141
2140
  STATUS: ok | syntax_error | illegal_access | runtime_error | tool_error | timeout
2142
2141
  LIMITS: 10K iter/loop, 30s timeout, 100 calls max`;
2143
2142
  var executeToolInputSchema = {
2144
- script: import_zod5.z.string().min(MIN_EXECUTE_SCRIPT_LENGTH).max(100 * 1024).describe(
2143
+ script: import_lazy_zod5.z.string().min(MIN_EXECUTE_SCRIPT_LENGTH).max(100 * 1024).describe(
2145
2144
  "JavaScript code to execute in the sandbox. Must return a value (implicitly or via explicit return). Use callTool(name, input) to invoke tools."
2146
2145
  ),
2147
- allowedTools: import_zod5.z.array(import_zod5.z.string()).optional().describe(
2146
+ allowedTools: import_lazy_zod5.z.array(import_lazy_zod5.z.string()).optional().describe(
2148
2147
  'Optional whitelist of tool names that can be called from this script. If not provided, all indexed tools are available. Example: ["users:list", "billing:getInvoice"]'
2149
2148
  )
2150
2149
  };
2151
- var syntaxErrorPayloadSchema = import_zod5.z.object({
2152
- message: import_zod5.z.string(),
2153
- location: import_zod5.z.object({
2154
- line: import_zod5.z.number(),
2155
- column: import_zod5.z.number()
2150
+ var syntaxErrorPayloadSchema = import_lazy_zod5.z.object({
2151
+ message: import_lazy_zod5.z.string(),
2152
+ location: import_lazy_zod5.z.object({
2153
+ line: import_lazy_zod5.z.number(),
2154
+ column: import_lazy_zod5.z.number()
2156
2155
  }).optional()
2157
2156
  });
2158
- var illegalAccessErrorPayloadSchema = import_zod5.z.object({
2159
- message: import_zod5.z.string(),
2160
- kind: import_zod5.z.union([
2161
- import_zod5.z.literal("IllegalBuiltinAccess"),
2162
- import_zod5.z.literal("DisallowedGlobal"),
2163
- import_zod5.z.string()
2157
+ var illegalAccessErrorPayloadSchema = import_lazy_zod5.z.object({
2158
+ message: import_lazy_zod5.z.string(),
2159
+ kind: import_lazy_zod5.z.union([
2160
+ import_lazy_zod5.z.literal("IllegalBuiltinAccess"),
2161
+ import_lazy_zod5.z.literal("DisallowedGlobal"),
2162
+ import_lazy_zod5.z.string()
2164
2163
  // same as your original type: 'A' | 'B' | string
2165
2164
  ])
2166
2165
  });
2167
- var runtimeErrorPayloadSchema = import_zod5.z.object({
2168
- source: import_zod5.z.literal("script"),
2169
- message: import_zod5.z.string(),
2170
- name: import_zod5.z.string().optional(),
2171
- stack: import_zod5.z.string().optional()
2166
+ var runtimeErrorPayloadSchema = import_lazy_zod5.z.object({
2167
+ source: import_lazy_zod5.z.literal("script"),
2168
+ message: import_lazy_zod5.z.string(),
2169
+ name: import_lazy_zod5.z.string().optional(),
2170
+ stack: import_lazy_zod5.z.string().optional()
2172
2171
  });
2173
- var toolErrorPayloadSchema = import_zod5.z.object({
2174
- source: import_zod5.z.literal("tool"),
2175
- toolName: import_zod5.z.string(),
2176
- toolInput: import_zod5.z.unknown(),
2177
- message: import_zod5.z.string(),
2178
- code: import_zod5.z.string().optional(),
2179
- details: import_zod5.z.unknown().optional()
2172
+ var toolErrorPayloadSchema = import_lazy_zod5.z.object({
2173
+ source: import_lazy_zod5.z.literal("tool"),
2174
+ toolName: import_lazy_zod5.z.string(),
2175
+ toolInput: import_lazy_zod5.z.unknown(),
2176
+ message: import_lazy_zod5.z.string(),
2177
+ code: import_lazy_zod5.z.string().optional(),
2178
+ details: import_lazy_zod5.z.unknown().optional()
2180
2179
  });
2181
- var timeoutErrorPayloadSchema = import_zod5.z.object({
2182
- message: import_zod5.z.string()
2180
+ var timeoutErrorPayloadSchema = import_lazy_zod5.z.object({
2181
+ message: import_lazy_zod5.z.string()
2183
2182
  });
2184
- var codeCallOkResultSchema = import_zod5.z.object({
2185
- status: import_zod5.z.literal("ok"),
2186
- result: import_zod5.z.unknown(),
2187
- logs: import_zod5.z.array(import_zod5.z.string()).optional()
2183
+ var codeCallOkResultSchema = import_lazy_zod5.z.object({
2184
+ status: import_lazy_zod5.z.literal("ok"),
2185
+ result: import_lazy_zod5.z.unknown(),
2186
+ logs: import_lazy_zod5.z.array(import_lazy_zod5.z.string()).optional()
2188
2187
  });
2189
- var codeCallSyntaxErrorResultSchema = import_zod5.z.object({
2190
- status: import_zod5.z.literal("syntax_error"),
2188
+ var codeCallSyntaxErrorResultSchema = import_lazy_zod5.z.object({
2189
+ status: import_lazy_zod5.z.literal("syntax_error"),
2191
2190
  error: syntaxErrorPayloadSchema
2192
2191
  });
2193
- var codeCallIllegalAccessResultSchema = import_zod5.z.object({
2194
- status: import_zod5.z.literal("illegal_access"),
2192
+ var codeCallIllegalAccessResultSchema = import_lazy_zod5.z.object({
2193
+ status: import_lazy_zod5.z.literal("illegal_access"),
2195
2194
  error: illegalAccessErrorPayloadSchema
2196
2195
  });
2197
- var codeCallRuntimeErrorResultSchema = import_zod5.z.object({
2198
- status: import_zod5.z.literal("runtime_error"),
2196
+ var codeCallRuntimeErrorResultSchema = import_lazy_zod5.z.object({
2197
+ status: import_lazy_zod5.z.literal("runtime_error"),
2199
2198
  error: runtimeErrorPayloadSchema
2200
2199
  });
2201
- var codeCallToolErrorResultSchema = import_zod5.z.object({
2202
- status: import_zod5.z.literal("tool_error"),
2200
+ var codeCallToolErrorResultSchema = import_lazy_zod5.z.object({
2201
+ status: import_lazy_zod5.z.literal("tool_error"),
2203
2202
  error: toolErrorPayloadSchema
2204
2203
  });
2205
- var codeCallTimeoutResultSchema = import_zod5.z.object({
2206
- status: import_zod5.z.literal("timeout"),
2204
+ var codeCallTimeoutResultSchema = import_lazy_zod5.z.object({
2205
+ status: import_lazy_zod5.z.literal("timeout"),
2207
2206
  error: timeoutErrorPayloadSchema
2208
2207
  });
2209
- var executeToolOutputSchema = import_zod5.z.discriminatedUnion("status", [
2208
+ var executeToolOutputSchema = import_lazy_zod5.z.discriminatedUnion("status", [
2210
2209
  codeCallOkResultSchema,
2211
2210
  codeCallSyntaxErrorResultSchema,
2212
2211
  codeCallIllegalAccessResultSchema,
@@ -2500,7 +2499,7 @@ ExecuteTool = __decorateClass([
2500
2499
  var import_sdk6 = require("@frontmcp/sdk");
2501
2500
 
2502
2501
  // plugins/plugin-codecall/src/tools/invoke.schema.ts
2503
- var import_zod6 = require("zod");
2502
+ var import_lazy_zod6 = require("@frontmcp/lazy-zod");
2504
2503
  var import_protocol2 = require("@frontmcp/protocol");
2505
2504
  var invokeToolDescription = `Call ONE tool directly. Returns standard MCP CallToolResult.
2506
2505
 
@@ -2513,10 +2512,10 @@ ERRORS: tool_not_found (\u2192 re-search) | validation_error | execution_error |
2513
2512
 
2514
2513
  FLOW: search \u2192 describe \u2192 invoke`;
2515
2514
  var invokeToolInputSchema = {
2516
- tool: import_zod6.z.string().describe(
2515
+ tool: import_lazy_zod6.z.string().describe(
2517
2516
  'The name of the tool to invoke (e.g., "users:getById", "billing:getInvoice"). Must be a tool you discovered via codecall:search.'
2518
2517
  ),
2519
- input: import_zod6.z.record(import_zod6.z.string(), import_zod6.z.unknown()).describe(
2518
+ input: import_lazy_zod6.z.record(import_lazy_zod6.z.string(), import_lazy_zod6.z.unknown()).describe(
2520
2519
  "The input parameters for the tool. Structure must match the tool's input schema (check codecall:describe for schema details)."
2521
2520
  )
2522
2521
  };