Code mode · MCP · Tool search
Code mode for AI agents
camelRun by camelAI hosts AI agents that call tools from code: one step, many calls, one result.camelRun by camelAI hosts AI agents that call their tools from code. The model writes a few lines of JavaScript that filter and call many tools in one step, your MCP servers included, and reads back the script's result.
camelRun runs: model turns and js_execYour tools
Plan restocks for everything below target.
const rows = await tools.read_inventory({});
const low = rows.filter(row => row.stock < row.target);
return await Promise.all(low.map(row => tools.plan_restock({sku: row.sku, quantity: row.target - row.stock})));camelRun runs: model turns and js_execYour tools
How it works
The model writes JavaScript that calls your tools
Your tools stay in your app. Here they're two Python functions over a cafe's stock list in SQLite. In js_exec, each tool is a function the model can call in a loop, after a filter, or all at once.
- 01
Loops and filters run in code
The script reads all fourteen rows and keeps the ten below target. The model gets the script's result, not every row.
- 02
The calls go out together
Promise.allsends all ten restocks at once, inside one step of the agent's turn. - 03
Calls from code are on the record
The run lists the calls the script made, each with
js_exec'stoolCallIdand aninnerCallIdof its own.
js_exectoolCallIdtoolu_01M4kQ8vZ2cWn7RtYb3xJp
| tool | innerCallId | ok |
|---|---|---|
| read_inventory | toolu_01M4kQ8vZ2cWn7RtYb3xJp…:1 | true |
| plan_restock | toolu_01M4kQ8vZ2cWn7RtYb3xJp…:2 | true |
| plan_restock | toolu_01M4kQ8vZ2cWn7RtYb3xJp…:3 | true |
| plan_restock | toolu_01M4kQ8vZ2cWn7RtYb3xJp…:11 | true |
from camelai_run import Agents, ToolContext, tool @tool
async def read_inventory():
"""Read inventory and target stock from the application's SQLite database."""
return [dict(row) for row in db.execute("SELECT * FROM inventory ORDER BY sku")]
@tool
def plan_restock(sku: str, quantity: int, context: ToolContext):
"""Set one SKU's local restock quantity. Does not place orders."""
if type(quantity) is not int or not 1 <= quantity <= 100:
raise ValueError("Invalid restock quantity")
if not db.execute("SELECT 1 FROM inventory WHERE sku = ?", (sku, )).fetchone():
raise ValueError("Unknown SKU")
# The call's stable key: a retried call rewrites the same row.
db.execute("INSERT OR REPLACE INTO restock VALUES (?, ?, ?)", (sku, quantity, context.idempotency_key))
db.commit()
return {"planned": True, "sku": sku, "quantity": quantity}
async with Agents() as agents:
agent = await agents.upsert("inventory", instructions="You manage cafe stock. Plan restocks without purchasing anything.",
tools= [read_inventory, plan_restock], **({"model": os.environ["AGENT_MODEL"]} if os.environ.get("AGENT_MODEL") else {}))Code mode MCP
Code mode for MCP servers
Each tool on an MCP server you add is a function the agent's code can call, named tools.<server>__<tool>, and a big catalog leaves the model's context free for the job.
You decide, per server or per tool, and the console's agent page shows which way each tool is offered.
- direct
- the model calls it as a tool of its own; never from
js_exec - codemode
- only from code the model runs in
js_exec - both
- as a tool of its own, or from code in
js_exec
Tools the model gets (117)
Tools marked codemode or both can be called from code the model runs in js_exec. To keep one out of js_exec, set its exposure to "direct": on the tool in your code, or on the server in its definition. How
Read inventory and target stock from the application's SQLite database.
Set one SKU's local restock quantity. Does not place orders.
Find products in the supplier's catalog by name or SKU.
Price per case for one product, with volume breaks.
Days from order to delivery for one product.
Open delivery slots for the next two weeks.
Sales for one day, item by item.
Best sellers between two dates.
Tool search
MCP tool search for agents with many tools
Give one agent the servers for its whole job. Its code finds the right tool with tools.search, reads the schema with tools.describe, and calls it in the same script.
await tools.search("price per case for oat milk")
- 1
name: "supplier__get_price"
description: "Price per case for one product, with volume breaks."
input: "{ sku: string }"
- 2
name: "supplier__list_price_breaks"
description: "Case prices by quantity for one product."
input: "{ sku: string }"
- 3
name: "supplier__get_case_size"
description: "Units in one case of a product."
input: "{ sku: string }"
- Thousands of tools, nothing up front
- Only tool names enter the code's environment, so a catalog of thousands stays out of the script's way until it asks.
- Best matches first
- Each result comes back with its name, description and input, the most relevant at the top.
- Ranked by meaning
- On hosted camelRun, search ranks by what a tool does as well as by its keywords.
Test it yourself
Run the model's code yourself to test your tools
agent.client.execute runs a script with the agent's tools, outside the model's history. Write the code the model would write, run it from your app, and see what your tools did.
# Code the model could have written, run in the agent's sandbox with its tools (no model call).
result = await agent.client.execute("""
const rows = await tools.read_inventory({});
const low = rows.filter(row => row.stock < row.target);
return await Promise.all(low.map(row => tools.plan_restock({sku: row.sku, quantity: row.target - row.stock})));
""")| sku | quantity | sku | quantity |
|---|---|---|---|
| BEAN-01 | 32 | MILK-05 | 27 |
| COCO-08 | 15 | OAT-02 | 24 |
| CROI-11 | 20 | SUG-09 | 40 |
| DECAF-12 | 9 | SYRP-06 | 10 |
| FILT-13 | 80 | TEA-07 | 15 |
Code mode and tool search questions
- q1What is code mode for MCP?
- Code mode lets an AI agent write code that calls its MCP tools as functions, instead of calling each tool itself. The name comes from Cloudflare's Code Mode. On camelRun every agent gets it by default: the model writes JavaScript in
js_exec, where each MCP tool istools.<server>__<tool>(). - q2Is code mode the same as programmatic tool calling?
- They're the same idea: the model writes code that calls its tools, the calls run inside that code, and the model reads the code's result rather than every tool result. On camelRun that code is JavaScript, run in
js_exec. - q3Why let the model write code to call tools?
- Code can loop, filter and call several tools in one step. The model writes the job once, the calls run together, and it reads back the result instead of every row along the way. A large tool catalog also stays out of the prompt until the code asks for a tool.
- q4How does MCP tool search work?
- The agent's code calls
tools.searchwith a few words and gets the best matches first, each with its name, description and input.tools.namespaceslists the servers with their tool counts. On hosted camelRun the ranking uses meaning as well as keywords. - q5Does code mode work with my MCP servers?
- Yes. Connect your MCP servers in the agent's definition or in its own server list, and their tools can be called from code. Servers with up to 10 tools are offered both ways by default and bigger ones from code only. Set exposure on the server entry, or on a single tool in its
tools/list, to change that. - q6Which tools does the model call directly?
- Every tool you mark direct, and every tool that needs a person's approval. An agent made with
codeMode: falsecalls all of its tools directly, which suits an agent that answers in a line, such as a classifier. - q7What language does the model write in code mode?
- JavaScript. Your tools stay in your own app, in TypeScript or Python with camelRun's SDKs, and the model's code calls them by name: one at a time, in a loop, or together with
Promise.all. - q8Is it safe to let the model run code?
- Yes. The model's code runs in a sandbox that can reach nothing else: it can call the agent's tools and work with its files, and your tools run in your own app.
More on tools for AI agents
- OverviewcamelRunThe runtime overview: the agent loop, channels, scale and prices.
- camelRunMCP agentsAI agents that call remote MCP servers with credentials the model never sees, and that are MCP servers themselves for Claude, Cursor and other clients.
- camelRunMulti-agent orchestrationAn AI agent fans out tasks to sub-agents that work in parallel or in the background, and every answer folds back into its reply.
- CompareCloudflare Agents alternativecamelRun next to Cloudflare's Agents SDK: an AI agent per user, like a Durable Object. camelRun runs the loop and keeps history, files and schedules; your Worker serves the tools.
- camelRunHuman-in-the-loop AI agentsAgents that ask a person before a risky step: an approval, a question, a form or a page to visit. The agent sleeps while it waits, for days, then carries on from the same step.
- camelRunMulti-tenant AI agentsGive every user or conversation of your app its own AI agent. Each tool call says whom it is for, browsers read only their own agent, and each customer can bring its own model keys.
- camelRunDurable AI agentsAgents whose history, files and unfinished work live in camelRun, so a turn carries on through deploys and crashes without sending a tool call twice.
- GuideAgent Harness vs Framework vs Runtime vs Sandbox, ExplainedWhere an agent's loop, its hosting and the code the model writes each belong.
- DocsTools in camelRunYour own tools, MCP and OpenAPI sources, built-ins, and tools from code.
Build an agent with code mode
Every agent on camelRun can write code from its first turn. Get an API key, hand it your tools, and give it a job.
$0.01 per agent-hour while an agent is in a run. Tokens on your own provider keys cost $0, and on ours the provider's price, no markup on tokens.
Read https://run.camelai.com/SKILL.md and set up camelRun in this project. Ask me what the agent should do.
Paste into Claude Code, Codex, Cursor or any coding agent. It asks what your agent should do, then builds it.