Skip to content

Commit f3af697

Browse files
Dumbrisclaude
andcommitted
docs(code-exec): reconcile overview with GA language param + IIFE rule (MCP-38)
Addresses CodexReviewer findings 2 & 3 on PR #753: - Add the GA `language` property (javascript|typescript) to the MCP code_execution inputSchema sample (Spec 033 FR-001). - Wrap every top-level-`return` example in an IIFE so the snippets match the cookbook's "bare top-level return is a SyntaxError" rule. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DUkH485Cuokg7Rc2mxP4Cp
1 parent d708e02 commit f3af697

1 file changed

Lines changed: 118 additions & 95 deletions

File tree

docs/code_execution/overview.md

Lines changed: 118 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -46,36 +46,42 @@ Model → Agent: code_execution({code: "...", input: {...}})
4646
Implement 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
6771
Transform, 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

Comments
 (0)