How to Use DeerFlow from Claude Code with the claude-to-deerflow Skill
Problem
I was working in Claude Code and needed to do research on a new library. I had to:
- Leave Claude Code terminal
- Open DeerFlow web interface
- Type my research question
- Wait for the response
- Copy the results back to Claude Code
This context switching was frustrating. Every time I needed DeerFlow’s research capabilities, I lost my flow. I wondered: could I just call DeerFlow directly from Claude Code?
What I Found
I discovered the claude-to-deerflow skill in the DeerFlow repository. It lets Claude Code communicate with a running DeerFlow instance through HTTP calls.
The architecture looks like this:
┌─────────────┐ ┌──────────────────┐ ┌─────────────┐│ Claude Code │────────▶│ claude-to-deerflow│────────▶│ DeerFlow ││ Terminal │◀────────│ Skill │◀────────│ Agent │└─────────────┘ └──────────────────┘ └─────────────┘ HTTP APIThis means I can send research tasks to DeerFlow and get streaming responses without leaving my terminal.
Installation
First, I installed the skill:
npx skills add https://github.com/bytedance/deer-flow --skill claude-to-deerflowI got this output:
Skill installed: claude-to-deerflowLocation: ~/.claude/skills/claude-to-deerflow/Then I made sure DeerFlow was running:
curl -s http://localhost:2026/healthExpected output:
{"status": "healthy"}First Attempt
I tried the skill in Claude Code:
/claude-to-deerflowBut I got an error:
Error: DEERFLOW_URL not configuredUnable to connect to DeerFlow at undefinedI realized I needed to set environment variables. I checked the skill documentation and found three options:
export DEERFLOW_URL=http://localhost:2026export DEERFLOW_GATEWAY_URL=http://localhost:2026export DEERFLOW_LANGGRAPH_URL=http://localhost:2026/api/langgraphAfter setting these, the skill worked.
Understanding the API
The skill uses DeerFlow’s LangGraph API. I tested the basic operations manually to understand how they work.
Health Check
curl -s "$DEERFLOW_GATEWAY_URL/health"Output:
{"status": "healthy", "version": "0.1.0"}List Available Models
curl -s "$DEERFLOW_GATEWAY_URL/api/models"Output:
{ "models": [ {"id": "claude-3-5-sonnet", "name": "Claude 3.5 Sonnet"}, {"id": "gpt-4o", "name": "GPT-4o"} ]}List Available Skills
curl -s "$DEERFLOW_GATEWAY_URL/api/skills"List Available Agents
curl -s "$DEERFLOW_GATEWAY_URL/api/agents"Sending Messages to DeerFlow
The core functionality is sending messages and receiving streaming responses. This took me a few tries to get right.
Step 1: Create a Thread
curl -s -X POST "$DEERFLOW_LANGGRAPH_URL/threads" \ -H "Content-Type: application/json" \ -d '{}'Output:
{"thread_id": "abc123-def456-ghi789"}Step 2: Send a Message with Streaming
curl -s -N -X POST "$DEERFLOW_LANGGRAPH_URL/threads/abc123-def456-ghi789/runs/stream" \ -H "Content-Type: application/json" \ -d '{ "assistant_id": "lead_agent", "input": { "messages": [ { "type": "human", "content": [{"type": "text", "text": "Research the latest features in Python 3.12"}] } ] }, "stream_mode": ["values", "messages-tuple"], "context": { "thinking_enabled": true, "is_plan_mode": true, "subagent_enabled": false } }'The response comes as Server-Sent Events (SSE):
event: metadatadata: {"run_id": "run-xyz789"}
event: valuesdata: {"messages": [...]}
event: messages-tupledata: {"type": "ai", "content": "Python 3.12 includes several new features..."}
event: enddata: {}Step 3: Parse the Response
To get the final response, I need to:
- Find the last
event: valuesblock - Parse the
dataJSON - Get the last message with
type: "ai" - Extract the
contentfield
Execution Modes
DeerFlow supports different execution modes through the context parameter:
┌────────────┬──────────────────┬───────────────┬──────────────────┬─────────────────────────┐│ Mode │ thinking_enabled │ is_plan_mode │ subagent_enabled │ Use Case │├────────────┼──────────────────┼───────────────┼──────────────────┼─────────────────────────┤│ Flash │ false │ false │ false │ Quick questions ││ Standard │ true │ false │ false │ Normal tasks ││ Pro │ true │ true │ false │ Complex planning ││ Ultra │ true │ true │ true │ Multi-agent research │└────────────┴──────────────────┴───────────────┴──────────────────┴─────────────────────────┘Flash Mode (Quick Questions)
{ "thinking_enabled": false, "is_plan_mode": false, "subagent_enabled": false}Pro Mode (Complex Planning)
{ "thinking_enabled": true, "is_plan_mode": true, "subagent_enabled": false}Ultra Mode (Multi-Agent Research)
{ "thinking_enabled": true, "is_plan_mode": true, "subagent_enabled": true}Managing Threads
Threads persist conversation history. I can retrieve them later.
Get Thread History
curl -s "$DEERFLOW_LANGGRAPH_URL/threads/abc123-def456-ghi789/history"List All Threads
curl -s -X POST "$DEERFLOW_LANGGRAPH_URL/threads/search" \ -H "Content-Type: application/json" \ -d '{"limit": 20}'Uploading Files for Analysis
DeerFlow can analyze uploaded files:
curl -s -X POST "$DEERFLOW_GATEWAY_URL/api/threads/abc123-def456-ghi789/uploads" \ -F "files=@/path/to/document.pdf"Common Issues I Encountered
Issue 1: Connection Refused
When I tried to connect, I got:
curl: (7) Failed to connect to localhost port 2026This meant DeerFlow wasn’t running. I started it:
cd deer-flowpython -m deer_flow --port 2026Issue 2: Wrong API Endpoint
I initially used the wrong endpoint:
curl -s http://localhost:2026/api/chatThe correct endpoints are:
# Gateway APIhttp://localhost:2026/api/modelshttp://localhost:2026/api/skillshttp://localhost:2026/api/agents
# LangGraph APIhttp://localhost:2026/api/langgraph/threadshttp://localhost:2026/api/langgraph/threads/{thread_id}/runs/streamIssue 3: Malformed Message Format
My first message attempt failed:
{ "messages": ["Research Python 3.12"] # Wrong: string, not object}The correct format requires proper message objects:
{ "messages": [ { "type": "human", "content": [{"type": "text", "text": "Research Python 3.12"}] } ]}Python Integration Example
I created a helper script to simplify integration:
import httpximport os
DEERFLOW_LANGGRAPH_URL = os.getenv( "DEERFLOW_LANGGRAPH_URL", "http://localhost:2026/api/langgraph")
async def send_to_deerflow(message: str, mode: str = "pro"): """Send a message to DeerFlow and stream the response."""
# Mode configurations context_configs = { "flash": { "thinking_enabled": False, "is_plan_mode": False, "subagent_enabled": False }, "standard": { "thinking_enabled": True, "is_plan_mode": False, "subagent_enabled": False }, "pro": { "thinking_enabled": True, "is_plan_mode": True, "subagent_enabled": False }, "ultra": { "thinking_enabled": True, "is_plan_mode": True, "subagent_enabled": True } }
context = context_configs.get(mode, context_configs["pro"])
async with httpx.AsyncClient(timeout=60.0) as client: # Create thread thread_resp = await client.post( f"{DEERFLOW_LANGGRAPH_URL}/threads", json={} ) thread_id = thread_resp.json()["thread_id"]
# Stream response async with client.stream( "POST", f"{DEERFLOW_LANGGRAPH_URL}/threads/{thread_id}/runs/stream", json={ "assistant_id": "lead_agent", "input": { "messages": [{ "type": "human", "content": [{"type": "text", "text": message}] }] }, "stream_mode": ["values", "messages-tuple"], "context": context } ) as response: async for line in response.aiter_lines(): if line.startswith("data:"): yield line[5:]Usage:
import asynciofrom deerflow_client import send_to_deerflow
async def main(): async for chunk in send_to_deerflow( "Research the best practices for async Python", mode="pro" ): print(chunk)
asyncio.run(main())Why This Integration Matters
| Feature | Without Integration | With claude-to-deerflow |
|---|---|---|
| Research while coding | Switch tools | Stay in terminal |
| Complex workflows | Manual context copy | Direct delegation |
| File analysis | Upload separately | Upload from terminal |
| Persistent memory | Separate systems | Shared DeerFlow memory |
The main benefit is workflow continuity. When I’m coding in Claude Code and need research, I don’t break my focus. I send the task to DeerFlow and continue working while it processes.
Summary
In this post, I showed how to integrate DeerFlow with Claude Code using the claude-to-deerflow skill. The key steps are:
- Install the skill with
npx skills add - Set environment variables for DeerFlow endpoints
- Create threads and send messages through the LangGraph API
- Parse SSE streaming responses
- Choose the right execution mode for your task
The integration eliminates context switching between tools. DeerFlow becomes an extension of Claude Code, accessible through a single command.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments