| id | code-execution | |||||
|---|---|---|---|---|---|---|
| title | Code Execution | |||||
| sidebar_label | Code Execution | |||||
| sidebar_position | 3 | |||||
| description | Execute JavaScript or TypeScript to orchestrate multiple MCP tools | |||||
| keywords |
|
The code_execution tool enables orchestrating multiple upstream MCP tools in a single request using sandboxed JavaScript (ES2020+) or TypeScript.
Code execution allows AI agents to:
- Chain multiple tool calls together
- Process and transform tool outputs
- Implement complex logic and conditionals
- Reduce round-trip latency
Enable code execution in your config:
{
"enable_code_execution": true,
"code_execution_timeout_ms": 120000,
"code_execution_max_tool_calls": 0,
"code_execution_pool_size": 10
}| Option | Type | Default | Description |
|---|---|---|---|
enable_code_execution |
boolean | false |
Enable the code execution tool |
code_execution_timeout_ms |
integer | 120000 |
Execution timeout (2 minutes) |
code_execution_max_tool_calls |
integer | 0 |
Max tool calls (0 = unlimited) |
code_execution_pool_size |
integer | 10 |
Number of VM instances to pool |
mcpproxy code exec --code="({ result: input.value * 2 })" --input='{"value": 21}'mcpproxy code exec --language typescript --code="const x: number = 42; ({ result: x })"mcpproxy code exec --code="call_tool('github', 'get_user', {username: input.user})" --input='{"user":"octocat"}'{
"code": "string (required) - JavaScript or TypeScript code to execute",
"language": "string (optional) - 'javascript' (default) or 'typescript'",
"input": "object (optional) - Input data available as 'input' variable"
}Execute a tool on an upstream server:
var result = call_tool('github', 'create_issue', {
repo: 'owner/repo',
title: 'Bug report',
body: 'Description'
});Log a message (visible in tool response):
log('Processing started');The last expression in the code is returned as the tool result:
// Return an object
({
success: true,
data: result
})// input: { "a": 5, "b": 3 }
({ sum: input.a + input.b })// Get user info then create an issue
var user = call_tool('github', 'get_user', { username: input.username });
var issue = call_tool('github', 'create_issue', {
repo: input.repo,
title: 'Issue from ' + user.name,
body: 'Created by code execution'
});
({ user: user, issue: issue })var files = call_tool('filesystem', 'list_directory', { path: input.path });
if (files.length > 100) {
({ status: 'too_many_files', count: files.length });
} else {
var results = [];
for (var i = 0; i < files.length; i++) {
if (files[i].endsWith('.md')) {
results.push(files[i]);
}
}
({ markdown_files: results });
}try {
var result = call_tool('api', 'fetch_data', { url: input.url });
({ success: true, data: result });
} catch (e) {
({ success: false, error: e.message });
}- Code runs in isolated JavaScript VM (goja)
- No access to file system
- No access to network (except via call_tool)
- No access to process environment
- Memory limits enforced
- Tools inherit quarantine status
- Rate limiting applied
- Response size limits enforced
Increase the timeout or optimize your code:
{
"code_execution_timeout_ms": 300000
}Modern JavaScript syntax (ES2020+) is fully supported, including arrow functions, const/let, template literals, destructuring, optional chaining, and nullish coalescing:
// All of these work
const result = () => call_tool('server', 'tool');
const name = user?.profile?.name ?? 'unknown';
const msg = `Hello, ${name}!`;
const { data, error } = response;Verify the server and tool names:
mcpproxy tools list --server=server-nameSet language: "typescript" to write code with type annotations. TypeScript types are automatically stripped before execution using esbuild, with near-zero transpilation overhead (<5ms).
- Type annotations:
const x: number = 42 - Interfaces:
interface User { name: string; age: number; } - Type aliases:
type StringOrNumber = string | number - Generics:
function identity<T>(arg: T): T { return arg; } - Enums:
enum Direction { Up = "UP", Down = "DOWN" } - Namespaces and type assertions
mcpproxy code exec --language typescript \
--code="interface User { name: string; }
const user: User = { name: input.username };
({ greeting: 'Hello ' + user.name })" \
--input='{"username": "Alice"}'- TypeScript support uses type-stripping only (no type checking or semantic validation)
- Valid JavaScript is also valid TypeScript
- Transpilation errors return the
TRANSPILE_ERRORerror code with line/column information - See
docs/code_execution/overview.mdin the repository for comprehensive TypeScript documentation
- Keep code simple: Complex logic is harder to debug
- Handle errors: Use try/catch for tool calls
- Minimize tool calls: Batch operations when possible
- Use logging: Add log() calls for debugging
- Test locally: Use CLI to test before integrating