Light
Dark
Product

Programmatic Tool Calling with any LLM

December 1, 2025

Last week, Anthropic released built-in programmatic tool calling support in the Claude API. Although the idea of having agents take actions by running arbitrary code is not new (e.g., the CodeAct research paper, and Cloudflare’s Code Mode extension for MCP), agents have historically relied on picking single tools to execute in sequence from a pre-defined toolset specified at inference time (e.g., tools provided by an MCP server), rather than dynamic code execution.

However, as LLMs become extremely adept at coding, agents can rely more heavily on dynamic code execution rather than basic tool calling. Programmatic tool calling allows agents to write and execute code that invokes tools, mixing dynamic code generation with pre-defined tools. This pattern is extremely powerful as it allows general-purpose agents to define and execute workflows themselves, rather than requiring developers to pre-define them. In other words, programmatic tool calling allows agents to write their own workflows.

Adding Programmatic Tool Calling to the Letta API

The Letta API now supports programmatic tool calling for any LLM model. Agents with the run_code_with_tools tool attached can write scripts that directly invoke other tools attached to the agent. This includes:

  • MCP tools (tools executed by external MCP servers)
  • Custom tools (user-defined tools executed by Letta)
  • Built-in tools (memory/filesystem/utility tools supported by Letta)

Letta tools are executed server-side, so clients don't need to take any action to enable programmatic tool calling. If a tool exists on the Letta API, it can be called programmatically with any LLM without any client-side changes.

When run_code_with_tools is attached, the agent can write a Python script that invokes any tool attached to the agent. For example, the agent can write and execute a script like:

This allows the agent to write scripts that dynamically call available tools. For example, the agent below has MCP tools for executing SQL queries on an external database and searching the web. This means the agent can write a script that loops through the results of a database query and passes each result into a web search. Below, we ask the agent to search the web for each mock user in the database:

The code generated by the agent calls the MCP tool execute_sql to get the list of employees, then calls the MCP tool web_search_exa to search for each employee in a loop (generated code shown below):

Programmatic tool calling is implemented at the harness layer in Letta, so it can be used with any LLM connected to the Letta API.

Why Use Programmatic Tool Calling?

Programmatic tool calling allows agents to run tools much more efficiently and define arbitrary workflows that combine tool calls within scripts.

Supporting Workflows & Chained Tools within General-Purpose Agent Harnesses

Many LLM applications have components that function more like workflows than agents — for example, passing the output of one MCP tool call as the input to another. As a result, many LLM frameworks support hard-coded workflows to augment agents. Programmatic tool calling allows the agent itself to define workflows as needed. For example, the agent can simply run a script like:

to define a map-reduce workflow pattern that composes tools. Combined with skills (which can store code snippets defining workflows), this allows general-purpose agents to execute pre-defined workflows similar to standard LLM frameworks.

Context Efficiency: Transforming and Combining Tool Outputs

External tools (e.g., MCP tools) often return messy or poorly structured output. With programmatic tool calling, the agent can post-process output data to avoid polluting the LLM context.

LLM Costs: Reducing LLM Invocations and Token Usage

Programmatic tool calling enables parallel tool calling, as the program can invoke many tools concurrently. In the example below, the agent creates memory blocks for every user in the database (10 total) with a single LLM invocation and tool call by programmatically calling the memory tool:

Programmatic Tool Calling for Stateful Agents

Since the Letta API is designed around stateful agents, many agents have stateful tools that operate on the agent's state (e.g., memory or files).

With programmatic tool calling, stateful tools still run within the scope of the caller agent that invoked run_code_with_tools. This means the tools use environment variables scoped to that agent and can access the agent's ID through a special LETTA_AGENT_ID environment variable. You can also directly invoke a tool for an agent via the SDK.

Next Steps

To get started with programmatic tool calling, attach run_code_with_tools to your Letta agents. This is an experimental feature, so you may need to add additional prompting to get your agents to use the tool effectively.

Jul 7, 2025
Agent Memory: How to Build Agents that Learn and Remember

Traditional LLMs operate in a stateless paradigm—each interaction exists in isolation, with no knowledge carried forward from previous conversations. Agent memory solves this problem.

Jul 3, 2025
Anatomy of a Context Window: A Guide to Context Engineering

As AI agents become more sophisticated, understanding how to design and manage their context windows (via context engineering) has become crucial for developers.

May 14, 2025
Memory Blocks: The Key to Agentic Context Management

Memory blocks offer an elegant abstraction for context window management. By structuring the context into discrete, functional units, we can give LLM agents more consistent, usable memory.

Feb 13, 2025
RAG is not Agent Memory

Although RAG provides a way to connect LLMs and agents to more data than what can fit into context, traditional RAG is insufficient for building agent memory.

Feb 6, 2025
Stateful Agents: The Missing Link in LLM Intelligence

Introducing “stateful agents”: AI systems that maintain persistent memory and actually learn during deployment, not just during training.

Nov 14, 2024
The AI agents stack

Understanding the AI agents stack landscape.

Nov 7, 2024
New course on Letta with DeepLearning.AI

DeepLearning.AI has released a new course on agent memory in collaboration with Letta.

Sep 23, 2024
Announcing Letta

We are excited to publicly announce Letta.

Sep 23, 2024
MemGPT is now part of Letta

The MemGPT open source project is now part of Letta.

Oct 23, 2025
Letta Evals: Evaluating Agents that Learn

Introducing Letta Evals: an open-source evaluation framework for systematically testing stateful agents.

Oct 14, 2025
Rearchitecting Letta’s Agent Loop: Lessons from ReAct, MemGPT, & Claude Code

Introducing Letta's new agent architecture, optimized for frontier reasoning models.

Sep 30, 2025
Introducing Claude Sonnet 4.5 and the memory omni-tool in Letta

Letta agents can now take full advantage of Sonnet 4.5’s advanced memory tool capabilities to dynamically manage their own memory blocks.

Jul 24, 2025
Introducing Letta Filesystem

Today we're announcing Letta Filesystem, which provides an interface for agents to organize and reference content from documents like PDFs, transcripts, documentation, and more.

Apr 17, 2025
Announcing Letta Client SDKs for Python and TypeScript

We've releasing new client SDKs (support for TypeScript and Python) and upgraded developer documentation

Apr 2, 2025
Agent File

Introducing Agent File (.af): An open file format for serializing stateful agents with persistent memory and behavior.

Jan 15, 2025
Introducing the Agent Development Environment

Introducing the Letta Agent Development Environment (ADE): Agents as Context + Tools

Dec 13, 2024
Letta v0.6.4 release

Letta v0.6.4 adds Python 3.13 support and an official TypeScript SDK.

Nov 6, 2024
Letta v0.5.2 release

Letta v0.5.2 adds tool rules, which allows you to constrain the behavior of your Letta agents similar to graphs.

Oct 23, 2024
Letta v0.5.1 release

Letta v0.5.1 adds support for auto-loading entire external tool libraries into your Letta server.

Oct 14, 2024
Letta v0.5 release

Letta v0.5 adds dynamic model (LLM) listings across multiple providers.

Oct 3, 2024
Letta v0.4.1 release

Letta v0.4.1 adds support for Composio, LangChain, and CrewAI tools.

Dec 2, 2025
Skill Learning: Bringing Continual Learning to CLI Agents

Today we’re releasing Skill Learning, a way to dynamically learn skills through experience. With Skill Learning, agents can use their past experience to actually improve, rather than degrade, over time.

Nov 7, 2025
Can Any Model Use Skills? Adding Skills to Context-Bench

Today we're releasing Skill Use, a new evaluation suite inside of Context-Bench that measures how well models discover and load relevant skills from a library to complete tasks.

Oct 30, 2025
Context-Bench: Benchmarking LLMs on Agentic Context Engineering

We are open-sourcing Context-Bench, which evaluates how well language models can chain file operations, trace entity relationships, and manage multi-step information retrieval in long-horizon tasks.

Aug 27, 2025
Introducing Recovery-Bench: Evaluating LLMs' Ability to Recover from Mistakes

We're excited to announce Recovery-Bench, a benchmark and evaluation method for measuring how well agents can recover from errors and corrupted states.

Aug 12, 2025
Benchmarking AI Agent Memory: Is a Filesystem All You Need?

Letta Filesystem scores 74.0% of the LoCoMo benchmark by simply storing conversational histories in a file, beating out specialized memory tool libraries.

Aug 5, 2025
Building the #1 open source terminal-use agent using Letta

We built the #1 open-source agent for terminal use, achieving 42.5% overall score on Terminal-Bench ranking 4th overall and 2nd among agents using Claude 4 Sonnet.

May 29, 2025
Letta Leaderboard: Benchmarking LLMs on Agentic Memory

We're excited to announce the Letta Leaderboard, a comprehensive benchmark suite that evaluates how effectively LLMs manage agentic memory.

Apr 21, 2025
Sleep-time Compute

Sleep-time compute is a new way to scale AI capabilities: letting models "think" during downtime. Instead of sitting idle between tasks, AI agents can now use their "sleep" time to process information and form new connections by rewriting their memory state.