Skip to main content

Code Mode

Code Mode is a method of interacting with MCP tools programmatically instead of calling them directly. Code Mode is particularly useful when working with many enabled extensions, as it can help manage context window usage more efficiently.

info

This functionality requires the built-in Code Mode extension to be enabled.

Code Mode controls how tools are discovered and called:

  • Tools from enabled extensions are discovered on-demand and loaded into context as needed
  • Multiple tool calls are batched in one execution
  • Intermediate results are chained (output from one tool as input to the next)

How Code Mode Works​

The Code Mode extension is an MCP server that uses the MCP protocol to expose three foundational meta-tools. When Code Mode is enabled, goose switches to Code Mode. For every request, the LLM writes JavaScript code that goose executes in a fresh goose-owned Boa context to:

  • Discover available tools from your enabled extensions (if needed)
  • Learn how to work with the tools it needs for the current task
  • Call those tools programmatically to complete the task

Traditional vs. Code Mode Tool Calling​

Traditional MCP tool calling and Code Mode are two different approaches to the same goal: giving goose access to tools.

AspectTraditionalCode Mode
Tool DiscoveryAll tools from enabled extensions, for example:
• shell
• write
• github__list_issues
• github__get_pull_request
• slack__send_message
• ... potentially many more
Code Mode extension's meta-tools:
• list_functions
• get_function_details
• execute_javascript

The LLM uses these tools to discover tools from other enabled extensions as needed
Tool Calling• Sequential tool calls
• Each result sent to the LLM before the next call
• May require tool discovery calls
• Multiple tool calls batched in one execution
• Intermediate results are chained and processed locally
Context WindowEvery LLM call includes all tool definitions from enabled extensionsEvery LLM call includes the 3 meta-tool definitions, plus any tool definitions previously discovered in the session
Best For• 1-3 enabled extensions
• Simple tasks using 1-2 tools
• 5+ extensions
• Well-defined multi-step workflows
Text-Only Results

Code Mode only supports text content from tool results. Images, binary data, and other content types are ignored.

JavaScript interface​

Call list_functions to discover exact tool names and short descriptions, then get_function_details with {"functions": ["extension__first_tool"]} to inspect original JSON input and output schemas. Recursive schemas remain JSON data. Use the returned names exactly, including unprefixed names for first-class tools.

Pass JavaScript to execute_javascript with an async function run() entry point:

async function run() {
const results = await Promise.all([
tools.call("extension__first_tool", { query: "example" }),
tools.call("extension__second_tool", { limit: 5 })
]);
return results.map(result => result.summary);
}

Await tool calls and batch independent operations. Return or log only information needed for the next step. Tool arguments must be JSON objects; results must be JSON values or undefined. Cyclic objects, functions, symbols, and BigInt are unsupported. Console output, JSON depth and item counts, JavaScript instructions, loop iterations, and recursion are bounded.

The runtime provides JavaScript built-ins, tools.call, and captured console.log, info, warn, error, and debug methods. It has no direct filesystem, shell, network, environment, or package access. Tool calls retain the extension lease, permission flow, cancellation, and mutation handling used by goose. Only assistant-visible text results reach the script.

Each execution uses a separate worker and context. The extension timeout and cancellation stop execution and cancel in-flight tool calls. JavaScript state is discarded between calls. Optional tool_graph metadata remains available for desktop display; saved TypeScript calls can still be displayed.

Additional Resources​