MCP Code Execution: Calling Tools Like a Code Library
When an MCP setup grows from three servers to thirty, tool definitions and intermediate results can consume more context than the reasoning itself. Code Execution with MCP exposes tools through a discoverable code interface, processes data in an execution environment, and returns only the information the model needs.
Compare the data paths
Direct MCP calls
all definitions enter context → model calls tool → full result enters context → model filters
Code Execution with MCP
discover interface → sandbox code calls tool → filter and aggregate locally → conclusion enters context
| Dimension | Direct calls | Code Execution approach |
|---|---|---|
| Discovery | Preloaded schemas | Browse or search on demand |
| Intermediate data | Model context | Execution environment |
| Composition | Multiple model turns | Loops, functions, and conditions |
| State | Conversation history | Files and runtime variables |
| Infrastructure | MCP client | MCP client plus a hardened sandbox |
Anthropic reported a reduction from 150,000 to 2,000 tokens for one example task. Treat that as a measured example, not a promise. Your result depends on definition size, response volume, and call-chain length.
Map MCP servers to a code directory
A small, predictable directory makes progressive discovery possible:
servers/
├── google-drive/
│ ├── getDocument.ts
│ └── getSheet.ts
├── salesforce/
│ ├── findProspect.ts
│ └── updateRecord.ts
└── index.ts
Each file exposes the input type, purpose, and wrapped call:
import { callMCPTool } from '../../client';
export interface GetDocumentInput {
documentId: string;
}
export interface GetDocumentResponse {
content: string;
modifiedAt: string;
}
/** Read one Google Drive document. Do not use for folders. */
export async function getDocument(input: GetDocumentInput): Promise<GetDocumentResponse> {
return callMCPTool('google_drive__get_document', input);
}
The agent lists servers/, opens only relevant wrappers, and avoids loading the entire MCP catalogue.
Example: update CRM from meeting notes
import * as drive from './servers/google-drive';
import * as crm from './servers/salesforce';
const transcript = await drive.getDocument({ documentId: 'doc-123' });
const summary = transcript.content
.split('\n')
.filter(line => line.startsWith('Decision:') || line.startsWith('Owner:'))
.join('\n');
await crm.updateRecord({
objectType: 'SalesMeeting',
recordId: 'meeting-456',
data: {
Notes: summary,
SourceModifiedAt: transcript.modifiedAt
}
});
The transcript stays in the execution environment. The model decides what counts as useful information; code performs the mechanical filtering and update.
Security comes before token savings
Never run model-generated code inside the application server process. At minimum, enforce:
| Control | Minimum boundary |
|---|---|
| Filesystem | Temporary workspace, read-only by default, explicit output path |
| Network | Necessary MCP endpoints only, deny arbitrary egress |
| Credentials | Short-lived and least-privilege; no durable secrets in source |
| Resources | CPU, memory, time, and output-size limits |
| Tool access | Task-scoped grants; separate read and write; approve high-risk writes |
| Audit | Generated code, tool calls, result summary, and final mutation |
“Intermediate data did not enter the LLM” does not mean “the data was completely safe.” It still passed through the execution environment, MCP server, and logging path. Apply classification and retention rules at each layer.
Make writes idempotent
A batch loop can multiply one error into hundreds of writes. A write tool should expose a stable result shape:
type WriteResult = {
idempotencyKey: string;
status: 'created' | 'already_applied' | 'rejected';
evidenceId?: string;
};
Use this execution order:
- Read first, calculate second, write last.
- Generate an idempotency key before each mutation.
- Produce a dry-run diff for high-risk operations.
- Cap batch size.
- Record successful items after a partial failure instead of replaying everything.
When not to use this pattern
- There are only three to five tools and responses are small.
- The model must inspect every intermediate item to make a judgement.
- The team does not have a trustworthy code sandbox.
- Irreversible writes lack approval and idempotency controls.
- Execution infrastructure costs more than the tokens it saves.
Production acceptance checklist
- Tool definitions can be discovered without full preload.
- A 10,000-row response is filtered before it reaches the model.
- A sandbox timeout ends the task with an explicit failure.
- Mutations support dry run, approval, and idempotency.
- Traces connect generated code, MCP calls, and business outcomes.
- Real tasks compare token use, P95 latency, correctness, and operational cost.
Practice task
Build a flow that finds overdue customers in a spreadsheet and creates CRM follow-ups:
- Create minimal TypeScript wrappers for the Sheet and CRM tools.
- Filter rows overdue by more than 14 days and above a chosen balance.
- Produce dry-run JSON without writing to CRM.
- Require approval before the batch mutation.
- Verify that rerunning the task creates no duplicates.
Related reading
Official references
📚 Related resources
❓ Common questions
Open a question to review the practical answer.
What's the core difference between code execution and direct MCP tool calling?
Direct calling preloads every tool definition and routes each intermediate result through the model; code execution presents MCP servers as code APIs on a filesystem — the agent reads definitions on demand and writes code, so data flows inside the execution environment and the model only sees final results.
Where does the 150k-to-2k token reduction figure come from?
From Anthropic's official engineering post "Code execution with MCP" (Nov 4, 2025): token usage on the demonstrated task dropped from 150,000 to 2,000, a 98.7% saving.
When is code execution not worth it?
With few tools and small results, direct calling is simpler; if the model must reason over intermediate data, it belongs in context anyway. The pattern requires sandboxing, resource limits, and monitoring — operational costs you must weigh against token savings.
Are code execution with MCP and Programmatic Tool Calling the same thing?
The former is an architecture pattern where you run your own execution environment; PTC is its productized API form on the Claude Developer Platform — Claude writes Python in a managed sandbox, with a measured 37% average token reduction (43,588 to 27,297) on complex research tasks.