@@ -46,36 +46,42 @@ Model → Agent: code_execution({code: "...", input: {...}})
4646Implement conditional branching, loops, and error handling that would require multiple model invocations.
4747
4848``` javascript
49- // Conditional logic
50- const user = call_tool (' github' , ' get_user' , {username: input .username });
51- if (! user .ok ) {
52- return {error: ' User not found' };
53- }
49+ // Wrap the body in an IIFE so early-exit `return`s are legal — a bare
50+ // top-level `return` is a SyntaxError. The IIFE's value is the result.
51+ (() => {
52+ // Conditional logic
53+ const user = call_tool (' github' , ' get_user' , {username: input .username });
54+ if (! user .ok ) {
55+ return {error: ' User not found' };
56+ }
5457
55- // Loop with accumulation
56- const results = [];
57- for (const repoName of input .repos ) {
58- const repo = call_tool (' github' , ' get_repo' , {name: repoName});
59- if (repo .ok ) {
60- results .push (repo .result );
58+ // Loop with accumulation
59+ const results = [];
60+ for (const repoName of input .repos ) {
61+ const repo = call_tool (' github' , ' get_repo' , {name: repoName});
62+ if (repo .ok ) {
63+ results .push (repo .result );
64+ }
6165 }
62- }
63- return {repos : results, count : results . length } ;
66+ return {repos : results, count : results . length };
67+ })() ;
6468```
6569
6670### 3. Data Transformation
6771Transform, filter, and aggregate data from multiple tool calls before returning results.
6872
6973``` javascript
70- const repos = call_tool (' github' , ' list_repos' , {user: input .username });
71- if (! repos .ok ) return repos;
74+ (() => {
75+ const repos = call_tool (' github' , ' list_repos' , {user: input .username });
76+ if (! repos .ok ) return repos;
7277
73- // Filter and transform
74- const activeRepos = repos .result
75- .filter (r => ! r .archived && r .pushed_at > input .since )
76- .map (r => ({name: r .name , stars: r .stargazers_count , language: r .language }));
78+ // Filter and transform
79+ const activeRepos = repos .result
80+ .filter (r => ! r .archived && r .pushed_at > input .since )
81+ .map (r => ({name: r .name , stars: r .stargazers_count , language: r .language }));
7782
78- return {repos: activeRepos, total: activeRepos .length };
83+ return {repos: activeRepos, total: activeRepos .length };
84+ })();
7985```
8086
8187## How It Works
@@ -232,11 +238,12 @@ The `code_execution` tool will appear in the tools list when an LLM agent connec
232238``` json
233239{
234240 "name" : " code_execution" ,
235- "description" : " Execute JavaScript code that orchestrates multiple upstream MCP tools..." ,
241+ "description" : " Execute JavaScript or TypeScript code that orchestrates multiple upstream MCP tools..." ,
236242 "inputSchema" : {
237243 "type" : " object" ,
238244 "properties" : {
239- "code" : {"type" : " string" , "description" : " JavaScript source code..." },
245+ "code" : {"type" : " string" , "description" : " JavaScript or TypeScript source code..." },
246+ "language" : {"type" : " string" , "enum" : [" javascript" , " typescript" ], "description" : " Source language; defaults to javascript. TypeScript types are stripped before execution (GA, Spec 033 FR-001)." },
240247 "input" : {"type" : " object" , "description" : " Input data accessible as global input variable..." },
241248 "options" : {"type" : " object" , "description" : " Execution options..." }
242249 },
@@ -250,85 +257,95 @@ The `code_execution` tool will appear in the tools list when an LLM agent connec
250257### Pattern 1: Sequential Tool Calls
251258
252259``` javascript
253- // Fetch user, then fetch their repos
254- const userRes = call_tool (' github' , ' get_user' , {username: input .username });
255- if (! userRes .ok ) {
256- return {error: userRes .error .message };
257- }
260+ // Wrap the body in an IIFE so early-exit `return`s are legal — a bare
261+ // top-level `return` is a SyntaxError. The IIFE's value is the result.
262+ (() => {
263+ // Fetch user, then fetch their repos
264+ const userRes = call_tool (' github' , ' get_user' , {username: input .username });
265+ if (! userRes .ok ) {
266+ return {error: userRes .error .message };
267+ }
258268
259- const reposRes = call_tool (' github' , ' list_repos' , {user: input .username });
260- if (! reposRes .ok ) {
261- return {error: reposRes .error .message };
262- }
269+ const reposRes = call_tool (' github' , ' list_repos' , {user: input .username });
270+ if (! reposRes .ok ) {
271+ return {error: reposRes .error .message };
272+ }
263273
264- return {
265- user: userRes .result ,
266- repos: reposRes .result ,
267- repo_count: reposRes .result .length
268- };
274+ return {
275+ user: userRes .result ,
276+ repos: reposRes .result ,
277+ repo_count: reposRes .result .length
278+ };
279+ })();
269280```
270281
271282### Pattern 2: Conditional Logic
272283
273284``` javascript
274- // Try primary server, fallback to secondary
275- let result = call_tool (' primary-db' , ' query' , {sql: input .query });
285+ (() => {
286+ // Try primary server, fallback to secondary
287+ let result = call_tool (' primary-db' , ' query' , {sql: input .query });
276288
277- if (! result .ok ) {
278- // Primary failed, try backup
279- result = call_tool (' backup-db' , ' query' , {sql: input .query });
280- }
289+ if (! result .ok ) {
290+ // Primary failed, try backup
291+ result = call_tool (' backup-db' , ' query' , {sql: input .query });
292+ }
281293
282- return result .ok ? result .result : {error: ' Both databases unavailable' };
294+ return result .ok ? result .result : {error: ' Both databases unavailable' };
295+ })();
283296```
284297
285298### Pattern 3: Loop with Aggregation
286299
287300``` javascript
288- // Fetch details for multiple items
289- const results = [];
290- const errors = [];
291-
292- for (const id of input .ids ) {
293- const res = call_tool (' api-server' , ' get_item' , {id});
294-
295- if (res .ok ) {
296- results .push (res .result );
297- } else {
298- errors .push ({id, error: res .error });
301+ (() => {
302+ // Fetch details for multiple items
303+ const results = [];
304+ const errors = [];
305+
306+ for (const id of input .ids ) {
307+ const res = call_tool (' api-server' , ' get_item' , {id});
308+
309+ if (res .ok ) {
310+ results .push (res .result );
311+ } else {
312+ errors .push ({id, error: res .error });
313+ }
299314 }
300- }
301315
302- return {
303- success: results,
304- failed: errors,
305- success_count: results .length ,
306- error_count: errors .length
307- };
316+ return {
317+ success: results,
318+ failed: errors,
319+ success_count: results .length ,
320+ error_count: errors .length
321+ };
322+ })();
308323```
309324
310325### Pattern 4: Data Transformation
311326
312327``` javascript
313- // Get repos and compute statistics
314- const reposRes = call_tool (' github' , ' list_repos' , {user: input .username });
315- if (! reposRes .ok ) return reposRes;
316-
317- const repos = reposRes .result ;
318- const totalStars = repos .reduce ((sum , r ) => sum + (r .stargazers_count ?? 0 ), 0 );
319- const languages = {};
320-
321- for (const repo of repos) {
322- const lang = repo .language ?? ' Unknown' ;
323- languages[lang] = (languages[lang] ?? 0 ) + 1 ;
324- }
328+ (() => {
329+ // Get repos and compute statistics
330+ const reposRes = call_tool (' github' , ' list_repos' , {user: input .username });
331+ if (! reposRes .ok ) return reposRes;
332+
333+ const repos = reposRes .result ;
334+ const totalStars = repos .reduce ((sum , r ) => sum + (r .stargazers_count ?? 0 ), 0 );
335+ const languages = {};
336+
337+ for (const repo of repos) {
338+ const lang = repo .language ?? ' Unknown' ;
339+ languages[lang] = (languages[lang] ?? 0 ) + 1 ;
340+ }
325341
326- return {
327- total_repos: repos .length ,
328- total_stars: totalStars,
329- avg_stars: Math .round (totalStars / repos .length ),
330- languages
331- };
342+ return {
343+ total_repos: repos .length ,
344+ total_stars: totalStars,
345+ avg_stars: Math .round (totalStars / repos .length ),
346+ languages
347+ };
348+ })();
332349` ` `
333350
334351## Error Handling
@@ -348,12 +365,14 @@ code_execution({code: "throw new Error('Something went wrong')"})
348365### Tool Call Errors
349366
350367` ` ` javascript
351- // Tool returns error - handled in JavaScript
352- var res = call_tool (' github' , ' get_user' , {username: ' nonexistent-user-12345' });
353- if (! res .ok ) {
354- return {error: ' User not found: ' + res .error .message };
355- }
356- return res .result ;
368+ (() => {
369+ // Tool returns error - handled in JavaScript
370+ var res = call_tool (' github' , ' get_user' , {username: ' nonexistent-user-12345' });
371+ if (! res .ok ) {
372+ return {error: ' User not found: ' + res .error .message };
373+ }
374+ return res .result ;
375+ })();
357376` ` `
358377
359378### Timeout Errors
@@ -440,16 +459,20 @@ mcpproxy code exec --language typescript \
440459
441460### 2. Handle Errors Gracefully
442461` ` ` javascript
443- // Bad: Assumes success
444- var user = call_tool (' github' , ' get_user' , {username: input .username });
445- return user .result .name ; // Crashes if user.ok is false
446-
447- // Good: Checks response
448- var user = call_tool (' github' , ' get_user' , {username: input .username });
449- if (! user .ok ) {
450- return {error: user .error .message };
451- }
452- return {name: user .result .name };
462+ // Bad: Assumes success (and a bare top-level `return` is itself a SyntaxError)
463+ (() => {
464+ var user = call_tool (' github' , ' get_user' , {username: input .username });
465+ return user .result .name ; // Crashes if user.ok is false
466+ })();
467+
468+ // Good: Checks response, early-exit returns kept legal inside the IIFE
469+ (() => {
470+ var user = call_tool (' github' , ' get_user' , {username: input .username });
471+ if (! user .ok ) {
472+ return {error: user .error .message };
473+ }
474+ return {name: user .result .name };
475+ })();
453476` ` `
454477
455478### 3. Set Appropriate Timeouts
0 commit comments