Claude Agent SDK Cold Email: Build Claude-Native Outreach Agents with FoxReach
Native MCP, 200k-token context, extended thinking, and prompt caching - the Anthropic stack is the sharpest tool in 2026 for cold email agents that need tone-sensitive copywriting and long-context research. Working code for the full pipeline on the Claude Agent SDK.
Usama Navid
Founder, FoxReach
Why Claude Agent SDK for cold email
Claude's advantage for cold email is tone and context. The 200k-token window lets you feed an entire LinkedIn profile plus the prospect's last 20 blog posts plus three earnings calls into one message without summarization. Sonnet 4 produces the best default-tone copywriter in the current model lineup. Extended thinking gives measurably better openers on tone-sensitive outreach.
The Claude Agent SDK (anthropic Python SDK with agent primitives) is the lowest-abstraction way to use these features. No framework in between. You get new Anthropic releases (extended thinking, MCP support, prompt caching) on day one. If Claude is your primary model, skip LangChain and go direct.
Prerequisites
Python 3.10+
Anthropic SDK 0.40+ supports MCP and extended thinking.
An Anthropic API key
Generate at console.anthropic.com. Start with Sonnet 4 tier for development.
A FoxReach API key
Free plan works. Settings → API Keys.
Quick setup
Install the SDK and register the FoxReach MCP server. The SDK handles MCP tool discovery, tool use formatting, and streaming in the same API.
pip install anthropic foxreachimport os
import anthropic
client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
message = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=2048,
mcp_servers=[
{
"type": "url",
"url": "https://api.foxreach.io/mcp",
"name": "foxreach",
"authorization_token": os.environ["FOXREACH_API_KEY"],
},
],
messages=[
{
"role": "user",
"content": "Create a draft campaign called 'SaaS CTOs April' in FoxReach and add a 3-step sequence - intro, value prop, soft ask. 3 days between each.",
},
],
)
for block in message.content:
if block.type == "text":
print(block.text)
elif block.type == "mcp_tool_use":
print(f"Tool: {block.name} Args: {block.input}")Run it and Claude chains tool calls - campaigns.create, then three sequences.create - and reports the outcome. No agent framework in between, no tool wrappers to write. The MCP server handles tool discovery; Claude handles tool-use protocol negotiation.
Long context for research
The cheap move is to summarize research before handing it to Claude. Don't. Claude's 200k window is the advantage; using it fully produces noticeably sharper openers. Feed the raw LinkedIn profile, the recent blog posts, the earnings transcript excerpt, and the Crunchbase funding note as separate document blocks. Claude picks the right detail for the opener.
message = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": "Write a 60-word cold email to this person. Open with one specific, citable fact from the research below."},
{"type": "text", "text": f"LinkedIn profile:\n{profile_text}"},
{"type": "text", "text": f"Recent blog posts:\n{posts_text}"},
{"type": "text", "text": f"Funding history:\n{crunchbase_text}"},
{"type": "text", "text": f"Template to personalize:\n{template_text}"},
],
},
],
)Streaming with tool use
For user-facing agents (a Slack bot, a custom UI), stream the response. The Anthropic SDK streams text blocks, tool-use events, and thinking blocks separately - you can show typing while tool calls resolve in parallel.
with client.messages.stream(
model="claude-sonnet-4-6",
max_tokens=2048,
mcp_servers=[{"type": "url", "url": "https://api.foxreach.io/mcp", "name": "foxreach", "authorization_token": api_key}],
messages=[{"role": "user", "content": "Show me my active campaigns."}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
final = stream.get_final_message()
for block in final.content:
if block.type == "mcp_tool_use":
print(f"\n[Called {block.name}]")Prompt caching
For agents that run many campaigns against the same system prompt and tool definitions, enable prompt caching. Anthropic caches the cached blocks for 5 minutes by default; subsequent calls re-use them at ~10% of the full token cost. For a 5k-token system + tool definitions block called 100 times per hour, this is a real saving.
message = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=2048,
system=[
{
"type": "text",
"text": SYSTEM_PROMPT,
"cache_control": {"type": "ephemeral"},
},
],
mcp_servers=[{"type": "url", "url": "https://api.foxreach.io/mcp", "name": "foxreach", "authorization_token": api_key}],
messages=[{"role": "user", "content": user_request}],
)Cache hits are reported in message.usage.cache_read_input_tokens. Log this in production to confirm caching is actually landing.
Common pitfalls
Overcompressing the research step
Claude's strength is long context - 200k tokens. If you summarize research into 500 tokens before handing it to Claude, you throw away the advantage. Pass the raw research as-is when it fits; Claude will find the right detail.
Missing the extended-thinking budget
For complex copywriting where tone matters, enable extended thinking. It costs more per token but produces measurably better opens. Set thinking.budget_tokens to 2000-4000 for copywriting nodes.
Re-sending the full prompt on every tool call
Without prompt caching, every agent loop sends the full system prompt + tool definitions again. That is expensive at scale. Enable cache_control on the system block - see the Prompt caching section.
Calling Claude sync in an async agent
The anthropic Python SDK has both sync and async clients. Mixing them causes event-loop leaks. Pick one per agent (AsyncAnthropic for most agent use cases) and stay consistent.
Frequently asked questions
How is Claude Agent SDK different from LangChain for cold email?
The Claude Agent SDK (anthropic-agent or the newer Claude Agent Protocol) is Anthropic-native: you build agents with tool use, streaming, and MCP support directly through the Anthropic API without an intermediate framework. LangChain abstracts over multiple LLM providers; Claude Agent SDK is optimized for Claude alone and ships new Anthropic features first.
Does the Claude Agent SDK support MCP out of the box?
Yes. Claude Desktop and the Claude Agent SDK share the same MCP client internals. Point the SDK at api.foxreach.io/mcp with your Bearer token and all 23 FoxReach MCP tools appear automatically. No adapter library needed.
Which Claude model is best for cold email copywriting?
Claude Sonnet 4 for copywriting - tone-sensitive work lives here, and the price/quality ratio is the best in the lineup. Claude Haiku 4.5 is great for classification (reply intent, lead qualification). Reserve Claude Opus for complex multi-step reasoning - it is overkill for most cold email tasks.
Can I mix Claude and GPT inside one agent?
You can - both SDKs can be imported in one Python process and called independently. Most teams route specific node types (copywriter vs classifier) to specific models. Stay within one provider per agent for simpler observability unless you have a measured reason to mix.
How do I handle very long research documents?
Claude's 200k context window lets you feed in entire LinkedIn profiles, recent blog posts, Crunchbase exports, and earnings transcripts in one message. For anything larger, use the Files API to upload the doc once and reference it across conversations. Prompt caching makes re-reading the same doc on subsequent tool calls nearly free.
See also
Ship your Claude-native outbound agent today
Free plan, no credit card. API key in under 60 seconds.