By Sagar Shankaran, Founder of CallSphere
Use tools and MCP servers in Claude Message Batches safely: strict schemas, auth, error handling, and custom_id-based idempotency across many requests.
Key takeaways
Tools turn a batch from a text generator into a workhorse: each of your hundred thousand requests can call a function, hit an API, or run code on Anthropic's side. But the batch model — fire, wait hours, pull results — changes the rules for how tools behave. There is no human watching a tool call resolve in real time, no easy mid-flight retry, and a tool with side effects can do real damage when it runs fifty thousand times unattended. This post is about wiring tools and MCP into batch requests so they stay safe, recoverable, and idempotent.
custom_id so a resubmitted request cannot double-charge or double-write.is_error results the model can react to, and reconcile tool-call outcomes separately from message-level batch outcomes.The cleanest tools to use in a batch are the ones you never have to execute yourself. Server-side tools — code execution and web search and fetch — run on Anthropic's infrastructure. You declare them in the tools array, and Claude runs the tool loop internally; the result that lands in your batch output already incorporates whatever the tool produced. There is no pause, no client callback, no partial state to manage across the hours your batch is in flight.
Request(
custom_id=f"analyze-{row_id}",
params=MessageCreateParamsNonStreaming(
model="claude-opus-4-8",
max_tokens=4096,
messages=[{"role": "user",
"content": f"Compute summary statistics for: {csv_blob}"}],
tools=[{"type": "code_execution_20260120", "name": "code_execution"}],
),
)For batch workloads that need computation or fresh information per item — running a calculation, checking a current fact — server-side tools are almost always the right call. They keep the entire interaction inside the single async request, which is exactly what the batch model wants.
Client-side tools and MCP servers introduce a tool the platform cannot execute for you — your code, or your MCP endpoint, has to run it. In an interactive session that is a simple loop. In a batch, the boundary is harder: the request is processed once, asynchronously, and there is no live channel for you to return a tool result mid-flight. The Claude API does support an mcp_servers parameter that lets Claude connect directly to remote MCP servers, which keeps the resolution server-side — that is the pattern to reach for when you need MCP capabilities inside a batch.
The Model Context Protocol is an open standard that connects Claude to external tools and data through MCP servers, letting a single tool definition expose a whole capability surface. When you wire a remote MCP server into a batched request, Claude calls it over the connection during processing, and the resolved result is folded into the output you eventually pull — no client round trip required.
Hear it before you finish reading
Talk to a live CallSphere AI voice agent in your browser — 60 seconds, no signup.
flowchart TD
A["Batched request\nwith mcp_servers"] --> B["Claude processes async"]
B --> C{"Tool needed?"}
C -->|No| D["Compose answer"]
C -->|Yes, server-side| E["Claude calls remote\nMCP server over connection"]
E --> F["MCP server authenticates\n+ returns structured data"]
F --> G{"Tool error?"}
G -->|is_error| H["Model adapts\nor records failure"]
G -->|ok| D
H --> D
D --> I["Result written\nto batch store by custom_id"]A tool schema that works on your five test prompts can break on the ten-thousandth real one. The fix is to constrain the input space tightly. Use enum for any field with a fixed value set, mark strict: true to guarantee the parameters validate against your schema, and set additionalProperties: false so the model cannot invent fields your handler does not expect.
tool = {
"name": "lookup_account",
"description": "Fetch an account record. Call this when the message "
"references a specific account by ID or email.",
"strict": True,
"input_schema": {
"type": "object",
"properties": {
"identifier": {"type": "string"},
"id_type": {"type": "string", "enum": ["account_id", "email"]},
},
"required": ["identifier", "id_type"],
"additionalProperties": False,
},
}Note the description: it states when to call the tool, not just what it does. Recent Claude models are conservative about reaching for tools, and a prescriptive trigger condition in the description measurably improves the should-call rate across a diverse batch.
Batches fail partially, and the remedy is resubmission. That means any tool with a side effect — charging a card, sending a message, writing a row — can run more than once for the same logical item. The defense is idempotency, and the batch hands you a perfect idempotency key for free: the custom_id. Derive a deterministic key from it and make your tool handler a no-op on repeats.
def handle_charge(tool_input, custom_id):
idem_key = f"charge:{custom_id}" # stable across resubmits
if store.seen(idem_key):
return store.prior_result(idem_key) # no double charge
result = payments.charge(**tool_input, idempotency_key=idem_key)
store.record(idem_key, result)
return resultWith this in place, resubmitting an expired or errored request is safe by construction. The first execution does the work; every replay returns the recorded result. This is the single most important property to get right when tools have side effects in a batch.
Tool errors and batch errors are different things, and you reconcile them separately. A tool that fails should return a result with is_error: true and an informative message, so the model can adapt or record the failure inside its response. That is a layer below the batch: the request itself may still succeed at the message level even though a tool call inside it failed.
tool_result = {
"type": "tool_result",
"tool_use_id": block.id,
"content": "Error: account 'xyz' not found.",
"is_error": True,
}So your post-batch reconciliation has two passes. First, the message-level pass on request_counts and result.type. Second, an application-level pass over the succeeded messages to detect tool failures the model surfaced in its output. A batch can read "100% succeeded" while 3% of items hit a tool error — only the second pass catches that.
Still reading? Stop comparing — try CallSphere live.
CallSphere ships complete AI voice agents per industry — 14 tools for healthcare, 10 agents for real estate, 4 specialists for salons. See how it actually handles a call before you book a demo.
custom_id, a resubmission double-acts. This is the highest-severity batch tooling bug.enum, strict, or additionalProperties: false lets the model emit inputs your handler chokes on at scale.enum on fixed fields, strict: true, additionalProperties: false.custom_id in every side-effecting handler.is_error in the succeeded outputs.| Tool type | Who executes | Fits a batch? |
|---|---|---|
| Code execution (server-side) | Anthropic | Excellent — fully self-contained |
| Web search / fetch (server-side) | Anthropic | Excellent — fresh data, no client loop |
Remote MCP server (mcp_servers) | Your endpoint, called server-side | Good — resolution stays off the client |
| Local client-side tool | Your code, post-hoc | Awkward — no live channel mid-batch |
The Model Context Protocol is an open standard, introduced in November 2024, that connects Claude to external tools and data through MCP servers, so one connection can expose an entire capability surface to the model.
Not on a live channel — batch requests are processed asynchronously with no callback to your client mid-flight. Use a server-side tool or wire a remote MCP server via the mcp_servers parameter so the tool resolves on Anthropic's side and the result lands in your batch output.
Because batches fail partially and you fix them by resubmission, any side-effecting tool can run twice for the same item. An idempotency key derived from custom_id makes the replay a safe no-op.
Message-level success and tool-level failure are independent. Do a second reconciliation pass over the succeeded results to find tool calls the model surfaced as is_error in its response.
Safe tool wiring, strict schemas, and idempotent handlers are the backbone of any production agent — batch or real-time. CallSphere brings the same Claude tooling discipline to voice and chat: assistants that answer every call, call tools mid-conversation, and book work 24/7. See it live at callsphere.ai.
Source & attribution: This is an independent, original explainer inspired by Anthropic's coverage on the Claude blog. Claude, Claude Code, Claude Cowork, Claude Opus, and the Model Context Protocol are products and trademarks of Anthropic. CallSphere is not affiliated with or endorsed by Anthropic.

Written by
Sagar Shankaran· Founder, CallSphere
LinkedInSagar Shankaran is the founder of CallSphere, where he builds production AI voice and chat agents deployed across healthcare, hospitality, real estate, and home services. He writes about agentic AI, LLM engineering, and shipping voice agents that handle real calls in production.
See how AI voice agents work for your industry. Live demo available -- no signup required.
One reschedule text hits your scheduler, package balance, tutor shift and invoice. Here is what MCP changed for tutoring and test-prep center owners in 2026.
Anthropic's Claude Fable 5 and Mythos 5 explained: pricing, availability, frontier benchmarks, the dual-model safeguard architecture, and what they mean for AI agents.
Where Claude Code, MCP, and multi-agent systems are taking GTM engineering next, and how to prepare your team now for standing and multi-agent workflows.
Where Claude Cowork and the Claude agent ecosystem are heading next — standing agents, MCP, skills as a moat — and the concrete moves to prepare your team now.
The metrics, leading signals, and anti-metrics that prove Claude Cowork is working — acceptance rate, time-to-outcome, and why usage counts mislead.
Shipping an agentic GTM workflow is easy; proving it works is hard. The metrics, signals, and eval loops that show a Claude Code rebuild is paying off.
© 2026 CallSphere Inc. All rights reserved.
Made within San Francisco
Watch how CallSphere handles real customer calls, schedules appointments, and processes payments — live.
Try Live DemoBook a DemoCalculate Your ROI