Skip to main content

Class 12: Beyond Tool Calls: Code Execution as an Alternative

Duration: ~30 minutes | Difficulty: Advanced | Prerequisites: Class 11 completed.

This closing lesson is analysis only, so you can read it without opening the project.


By the end of this lesson you will be able to describe the pattern that Anthropic published in November 2025 as "Code Execution with MCP". You will also be able to translate it into the frameworks this course used: Spring AI, LangChain4j and LangGraph4j. And you will know which parts of our agent would carry over to that pattern, and which would need rewriting. This is the only lesson without new code. It helps you decide what to watch over the next twelve to eighteen months.

The lessons before this one used the canonical tool-calling shape. At the start of each turn, the agent:

  • receives a list of tools
  • picks one and fills its arguments
  • sends the call
  • reads the result

That shape is built into every framework this course used: Spring AI, LangChain4j and LangGraph4j. Anthropic's November 2025 post argues that the shape is wrong for large workloads. Reading that argument carefully helps us look again at the agent we built.

Our MCP course's closing lesson, Beyond Tool Enumeration, reads the same Anthropic post from the MCP side. This lesson covers the framework side. It asks what the pattern means when your agent runs on Spring AI, LangChain4j or LangGraph4j instead of behind an MCP server. It also checks, lesson by lesson, how much of this course's work transfers.

The Argument​

Anthropic published Code Execution with MCP on November 4, 2025. The post is named after MCP, and its argument applies more widely: to any agent framework that lists its tools for the model to read on every turn.

The argument has two parts.

The first part is that the tool list sent on every turn is the largest token cost in production agent workloads. With ten tools, the list costs a few hundred tokens. With fifty, it costs several thousand. A large deployment connects one agent to ten or twenty services, through five or six MCP servers, AI SDK tool collections or LangChain Tool instances. There the tool catalog can pass thirty thousand tokens before the user's first message. Every conversation pays that cost on every turn. Over thirty turns, the agent reads its whole toolkit thirty times, and each turn uses only the one tool it picks.

The second part is that calling one tool per turn sends every intermediate result through the model's context. Suppose a tool returns a hundred rows, and the agent only needs one summary statistic from them. The model still reads all hundred rows. When tool A's result has to go into tool B, the model reads tool A's output and then writes it into tool B's input, so it pays twice for data it only passes along. Real workloads have long chains of these steps, and each one pays to move data through the model's context.

The diagram shows the two patterns side by side. Both let the agent do the same things, and they differ in where the data travels:

The proposed alternative stops sending the tool list. The agent runs in a sandbox that can execute code. There the tools, including the ones your GraphQL backend exposes, are code modules that the agent can import. The agent writes and runs code that imports the tools it needs and calls them as ordinary functions. Intermediate results stay inside the sandbox, and the model sees only what the code prints. Anthropic's post describes its reference implementation, including the runtime and the language. Check the post itself for those details, because they change over time.

Anthropic published a benchmark with the post, and the benchmark is why people took the pattern seriously. On a realistic agent workload, the usual tool-calling pattern used about 150,000 tokens, and the code-execution pattern used about 2,000. Anthropic reports that as a reduction of 98.7%. According to the authors, three causes contribute:

  • removing the tool list
  • keeping intermediate results out of the conversation
  • letting the model chain several calls in one code block

The published numbers do not say how much each cause contributed. The size of the reduction is likely to keep this pattern in front of teams building agents through 2026.

Why this is more than a prediction

Two facts make this argument stronger than the usual predictions about how agents will work.

First, agents that write and execute code already exist. Coding agents such as Claude Code work this way, and Anthropic's post reports measurements from a real workload.

Second, the pattern has since shipped in production infrastructure under the name "code mode". Cloudflare documents Code Mode MCP server patterns as an official pattern page in its Agents platform. Anthropic added the idea to the Messages API as programmatic tool calling, where the model writes code that calls your tools inside a managed execution container. Whether it becomes the main pattern depends partly on whether the savings hold at scale. The early numbers have been discussed in public, and the reaction has been mostly positive.

How the Pattern Looks, and What the JVM Adds and Lacks​

The pattern was published in TypeScript. We look at that form first, because that code exists and runs today with tooling you can install. The Java further down is a sketch of a possible port, and no SDK generates it today. Keep the two apart as you read. Here is the kind of block that the agent writes and a sandbox runs. It imports a typed SDK generated from the schema:

// The published pattern's native shape (Anthropic's TypeScript framing):
import { search, movies } from "@app/graphql-sdk";

const named = (await search({ query: "star" })).filter((r) => r.__typename === "Movie");
const topSciFi = (await movies({ filter: { genre: "SCIFI", minRating: 8.0 } })).content;
const overlap = named.filter((m) => topSciFi.some((t) => t.id === m.id));
console.log(overlap.slice(0, 5).map((m) => ({ title: m.title, rating: m.rating })));

That block does two lookups, a filter, an intersection and a printed summary in one turn. The conversation receives only the printed result. The intermediate arrays stay in the sandbox, and that is where the large token saving comes from.

Sketching the same artifact on the JVM is easy, because this course already built the pieces, although the SDK below does not exist yet. The typed SDK would be a generated Java client over the allow-listed operations. Each catalog entry would become a method. Its signature would come from the same schema walk as Class 2's tool definitions. Its return type would be a record that mirrors a fragment, as in Class 8:

// The theoretical Java mirror: what a generated SDK over the catalog would expose.
public interface MovieDbSdk {
List<SearchResult> search(String query);
MoviePage movies(MovieFilter filter, Integer page, Integer size, MovieSort sort);
MovieCard movie(String id);
}

Descriptions become Javadoc, and the allow-list decides what the SDK contains. Everything from Classes 2 through 4 still applies underneath: persisted operations, identity in the header, and the server's final checks. The reason is that the SDK's method bodies do exactly what the callback's call path does.

Translating the runtime is harder on the JVM, which is why this lesson stays theoretical for this stack. The pattern needs a sandbox, a place to run code that the model wrote. The sandbox has to be cheap enough to use on every turn. It also has to stop the code from reading your files, opening network connections you did not intend, or running until the machine runs out of resources.

TypeScript deployments can install a sandbox. V8 isolates, Deno and hosted worker sandboxes all provide that boundary, with resource limits and a restricted set of built-in functions, and a team only has to connect one. The JVM offers building blocks instead, and with each of them you design the resource limits and the security boundary yourself.

Each JVM candidate has a drawback:

  • GraalVM's polyglot contexts and isolates can host guest code with memory and CPU limits. Running model-written Java through them means compiling on every turn, and deciding for yourself which classes and system calls the guest code may reach.
  • Embedding a scripting engine avoids the compilation cost, and it changes the language the model writes. The typed SDK that made this pattern attractive is a Java artifact, so part of its benefit is lost.
  • A container per execution gives the strongest isolation, at the cost of starting a container for every turn of every conversation.

All of this is possible, and new platform pieces keep arriving. As of mid-2026, adopting this pattern on the JVM still means designing and maintaining that sandbox as part of your own system. Which Artifacts You Maintain below helps you weigh that investment.

How GraphQL Fits, Specifically​

This course built two ways to expose the schema: Class 2's default-deny, role-scoped allow-list catalog, and Class 3's search, introspect and execute meta-tools. Both are ways to curate a tool list. The code-execution pattern removes the tool list, so it is a different kind of design from both.

The canonical patterns show a tool catalog to the model. They curate the catalog in different ways, with a per-operation allow-list, role scoping or dynamic discovery. They all answer the same question: what should the agent see in its tool list?

The code-execution pattern gives the agent an SDK. The SDK is generated from your schema, with the same descriptions, types and constraints that the other patterns relied on. In the published TypeScript form, the tool catalog becomes a module's exports, and each tool description becomes a comment. In the Java version sketched above, they become an interface's methods and their Javadoc.

Which Artifacts You Maintain​

Schema descriptions still do the same work, and possibly more. In the canonical pattern, a description appears in the tool catalog that the agent reads on every turn. In the code-execution pattern, it appears as the doc comment on the SDK method: TSDoc in TypeScript, Javadoc on the JVM. The model reads that comment when it looks at the module.

The model reads the description while it writes the call, where in the canonical pattern it read the description while choosing from a list. So the description has to be precise enough for the model to write the call correctly the first time. The Class 1 guidance applies fully here: descriptions give direct instructions, state defaults and point to related fields. It may matter even more, because fewer later steps catch the model's mistakes.

Operation allow-lists become package access. In the canonical pattern, we decided which operations the agent could call by curating the tool catalog. In the code-execution pattern, we decide it by curating the SDK package, so role-scoped SDKs replace role-scoped tool catalogs. You publish graphql-sdk-support, graphql-sdk-finance and graphql-sdk-admin as separate artifacts: npm packages in TypeScript, Maven modules on the JVM. The agent runtime loads the one for the agent's role into the sandbox.

Server-side enforcement still applies. The SDK in the sandbox makes GraphQL calls with the same persisted documents, because its method bodies are the callback's call path. The gateway sees those calls and applies the same validation, authorization, and depth and complexity caps as before. The Class 4 patterns stay as they are. What changes is where the curation happens: the agent framework does less of it, and the gateway does the same amount.

The @defer and tool-streaming work from Class 9 changes form. In the code-execution pattern, the agent's call to a @defer query becomes iteration over the stream that the SDK function returns. In TypeScript that stream is an async iterable, and on the JVM it is a Flux or a Reactive Streams Publisher. Streaming stays useful, and it appears as iteration in code, where the canonical pattern delivered partial updates through the agent loop. Showing partial results in a chat UI as they arrive now has to pass through the sandbox boundary. The stream at the protocol level stays the same, and the code that consumes it changes.

The cost accounting from Class 10 still works, because it reads the token usage that the provider reports for every model call, whichever way the agent reaches the API. The model-side cost drops, because the conversation is much shorter. A shorter conversation makes the per-run cost easier to keep under budget, and the code that measures and enforces the cost stays the same.

Most of what we built in this course transfers to the code-execution pattern unchanged. The parts that need work are the ones at the agent-framework boundary, which moves to the SDK code generator. The same agent built over REST or OpenAPI would transfer less well, because the typed schema is the part that carries over.

The Middle Option​

There is a third design between the full tool catalog and full code execution: provider-side tool search. The Claude API's tool search tool loads tool definitions on demand, so the model searches the catalog and reads only the part it needs. That removes most of the cost of the tool list on each turn, and the agent still calls tools the same way.

We already built this design. Class 7 did three things with Spring AI's ToolSearchToolCallingAdvisor over the same catalog:

  • turned it on
  • compared the three indexes that rank the catalog
  • measured 350 agent runs to find what it saves and what it costs in completed tasks

Our MCP course's closing lesson, Beyond Tool Enumeration, covers the same idea from the MCP side, where the catalog comes from one or more servers. If the tool list is your main cost, and passing data through the conversation is affordable, tool search is the cheaper change.

What to Watch For​

Three signals would show whether the industry is moving to the code-execution pattern. As of mid-2026 the first has partly arrived, and the other two have not. Watch for them, and for now keep your design ready for either outcome.

The first signal is platform and framework support, and the platform part has arrived.

  • Anthropic shipped programmatic tool calling in the Messages API: the code_execution tool plus allowed_callers on custom tools. It works without a beta header.
  • Cloudflare documents Code Mode as an official pattern for its Agents platform, and "code mode" has become the common name for the trend.
  • For GraphQL, WunderGraph presented "Search and Execute with Code Mode Backed by the Graph" at GraphQLConf 2026.

The framework part is still open. The main agent frameworks, Spring AI and LangChain4j included, still treat code execution as a pattern you assemble yourself. None of them offers it as a built-in agent feature with typed-SDK presets. If that changes by late 2026, plan around it.

The second signal is support in code generators. The pattern needs a typed SDK built for agents to use:

  • output with rich TSDoc comments
  • error shapes that the agent can handle without a round trip through the conversation
  • hooks for introspection at runtime
  • sensible default selection sets

GraphQL Code Generator, Ariadne Codegen and Apollo's clients can all be configured to do this today. As of this writing, none of them ships a "for agents" preset. The first major code generator to publish one would show that the industry has decided. For example, if graphql-codegen --preset agent-typescript produced an SDK ready for a sandbox, the ecosystem would have committed to the pattern.

The third signal is the output of the GraphQL AI Working Group. Everything the working group has produced so far serves the usual tool-calling pattern:

  • the semantic introspection RFC
  • the @mock directive, published as GAP-10
  • the schema-retrieval embedding work
  • the benchmark suite, which is arriving through pull requests

The group may start publishing guidance for typed SDKs. That guidance would cover:

  • conventions for default selection sets in generated code
  • the right shape of error unions
  • how an SDK should expose @defer streaming

It would show that the standards work is following the industry. Watch the working group's meeting recaps for that signal.

The agent we built can move in either direction, whichever way these signals go. The schema keeps its value, the description work transfers, and the gateway enforces its rules whatever client the agent uses. The work that would need redoing is in Class 2, the tool-catalog generator, and in parts of Class 5 through Class 7, the framework-specific bindings. Those parts are small enough to rewrite when the time comes, and the rest of the course's work stays useful with either pattern.

Summary​

The code-execution pattern replaces the tool catalog sent on every turn with a sandbox. There the agent imports a typed SDK and writes ordinary code. Intermediate results stay inside the sandbox, and the conversation carries only the prompt, the code and what the code printed.

Anthropic's benchmark, from roughly 150,000 tokens down to roughly 2,000 on one workload, made the industry take the pattern seriously. The pattern has since shipped as Cloudflare's Code Mode and as Anthropic's programmatic tool calling. For a GraphQL backend, the schema stays the contract either way. Descriptions become the SDK's doc comments, and role-scoped tool catalogs become role-scoped SDK artifacts. Every server-side control from Class 4 applies unchanged, including validation, authorization, and the depth and complexity caps. The server sees the same operations, however the agent was built. Most of what this course built transfers. The parts that would need rewriting are the tool-catalog generator and the framework bindings, which are the thinnest layers in the architecture by design.

GraphQL was designed before agents existed, for other reasons. Agents turned out to need a contract that is typed, documented, introspectable and validated, and GraphQL has had those properties since 2015. That is the practical reason to spend your effort on the schema. The SDK, the agent framework, the model and the protocol each changed at least once while we wrote this course. The schema descriptions you improve today keep their value, whichever calling convention the industry settles on.

Further Reading​

What's Next​

To continue, deploy the agent from the framework track against your own schema. Put the Class 4 safety controls in place first, and make the Class 11 suite pass before real users rely on the agent. If your agents run behind MCP clients, our MCP course covers the same topics for the protocol itself. Its closing lesson, Beyond Tool Enumeration, continues this lesson's discussion of tool search and code execution from the MCP side.