* feat: give MCP agent control over sub-research iterations and search engine
The MCP agent can now configure sub-research tools with optional parameters:
- **iterations** (1-15): Control how many search rounds the sub-strategy
runs. Use fewer (2-3) for quick checks, more (10-15) for exhaustive
research. Previously hardcoded to 8 for focused-iteration.
- **search_engine**: Override which search engine the sub-research uses.
For example, the agent can now run `focused_research` with
`search_engine: "pubmed"` to do deep iterative research specifically
against PubMed, or `"arxiv"` for scientific papers. Previously,
sub-research always used the primary configured engine (usually SearXNG),
losing access to specialized databases.
This lets the agent make smarter delegation decisions, e.g.:
ACTION: focused_research
ARGUMENTS: {"query": "mRNA cancer vaccine clinical trials",
"iterations": 5, "search_engine": "pubmed"}
The system prompt is updated to teach the agent about these options.
Override engines are properly cleaned up after use.
* refine: prefer more iterations over breadth, raise limit to 25
Updated system prompt and tool descriptions to guide the agent toward
using more iterations (10-20+) rather than broader queries. Raised the
iteration clamp from 15 to 25 to support exhaustive deep dives.
* docs: note web_search gives precise control over search queries
Highlight in the system prompt that web_search is also useful for
crafting specific search queries with exact phrases, date ranges, or
site filters — giving the agent more direct control over what reaches
the search engine.
* refactor: simplify MCP tools — web_search default, only focused_research for deep work
Removed source_research and quick_research tools from the MCP agent.
These were legacy strategies that added confusion without clear value:
- source_research (source-based) overlapped with focused_research
- quick_research (standard) was an old strategy with no clear advantage
The agent now has a cleaner toolset:
- web_search: primary tool for most queries, gives precise control
- focused_research: deep iterative research with configurable iterations
and search_engine override (e.g. pubmed, arxiv)
- search_[engine]: quick single queries against specific databases
- download_content: fetch full article text
System prompt rewritten to emphasize web_search as the default action
and focused_research for complex topics needing depth.
* prompt: recommend specialized engines for domain-specific questions
Added explicit guidance in the system prompt mapping question domains
to the best engine: medical → pubmed, scientific → arxiv, background →
wikipedia, news → wikinews. This helps the agent pick the right tool
instead of defaulting to web_search for everything.
* fix: increase observation limits 10x so agent sees full sub-research output
OBSERVATION_MAX_LENGTH: 5000 → 50000
HISTORY_OBSERVATION_MAX_LENGTH: 1000 → 10000
The previous limits severely truncated focused_research output — the
agent would run 8+ iterations of deep PubMed research but only see
1000 chars of the result when synthesizing the final answer. Now the
agent retains much more context from sub-research for better synthesis.
* feat: enable semantic_scholar and openalex for auto search by default
Added use_in_auto_search=true to both settings files so the MCP agent
can use them as specialized search tools. Updated system prompt to
mention them alongside arxiv and pubmed.
* fix(test): update tool count after removing source_research and quick_research
* prompt: guide agent to do quick searches first before focused_research
* prompt: recommend search_arxiv as quick first step for scientific topics
* fix: address all 8 review rounds — prompt, tests, docs, limits, progress
- Rewrote system prompt: one clear decision table, no contradictions
- Fixed docstring (1-15 → 1-25), progress message shows actual engine
- Added comments explaining MCP is for large-context LLMs (32k+)
- Added 10 tests for iterations/search_engine/clamping/cleanup
- Updated docs/mcp-server.md for removed tools
19 KiB
MCP Server Guide
LDR provides an MCP (Model Context Protocol) server that exposes its research capabilities to AI assistants like Claude Desktop, Claude Code, and OpenClaw. MCP is an open protocol by Anthropic that lets AI applications call external tools over a standardized interface.
The MCP server exposes 8 research tools — 5 research tools and 3 discovery tools — over STDIO transport only (local use, no network exposure). MCP support is an optional dependency that must be installed separately.
Quick Start
Installation
pip install "local-deep-research[mcp]"
Claude Desktop Configuration
Add the following to your claude_desktop_config.json:
{
"mcpServers": {
"local-deep-research": {
"command": "ldr-mcp",
"env": {
"LDR_LLM_PROVIDER": "openai",
"LDR_LLM_OPENAI_API_KEY": "sk-..."
}
}
}
}
Claude Code Configuration
Add to your .mcp.json (project-level) or ~/.claude/mcp.json (global):
{
"mcpServers": {
"local-deep-research": {
"command": "ldr-mcp",
"env": {
"LDR_LLM_PROVIDER": "ollama",
"LDR_LLM_OLLAMA_URL": "http://localhost:11434"
}
}
}
}
OpenClaw Configuration
Add LDR as a skill in your openclaw.json:
{
"mcpServers": {
"local-deep-research": {
"command": "ldr-mcp",
"env": {
"LDR_LLM_PROVIDER": "openai",
"LDR_LLM_OPENAI_API_KEY": "sk-..."
}
}
}
}
The configuration format is the same as Claude Desktop. See the OpenClaw MCP documentation for details on skill registration.
Verify Installation
Run ldr-mcp in a terminal. It should start and wait for STDIO input (no output means it's working). Press Ctrl+C to stop.
First Research
Open Claude Desktop and try:
Use quick_research to find information about quantum computing applications
Configuration
The MCP server uses the same settings system as the main LDR application. There are no dedicated MCP-specific environment variables. All configuration is done through standard LDR_* environment variables, set in the Claude Desktop config's env block.
Environment Variables
LLM Settings:
| Variable | Description | Example |
|---|---|---|
LDR_LLM_PROVIDER |
LLM provider | openai, ollama, anthropic |
LDR_LLM_MODEL |
Model name | gpt-4, llama3:8b, claude-sonnet-4-20250514 |
LDR_LLM_OPENAI_API_KEY |
OpenAI API key | sk-... |
LDR_LLM_TEMPERATURE |
Generation temperature | 0.7 |
Search Settings:
| Variable | Description | Example |
|---|---|---|
LDR_SEARCH_TOOL |
Default search engine | auto, arxiv, wikipedia |
LDR_SEARCH_SEARCH_STRATEGY |
Default strategy | source-based, focused-iteration |
LDR_SEARCH_ITERATIONS |
Default iteration count | 2 |
LDR_SEARCH_QUESTIONS_PER_ITERATION |
Questions per iteration | 3 |
Note: The strategy variable uses a double underscore (
SEARCH_SEARCH_STRATEGY) because the settings key issearch.search_strategy.
Optional Search API Keys:
| Variable | Description |
|---|---|
LDR_TAVILY_API_KEY |
Tavily search API key |
LDR_BRAVE_SEARCH_API_KEY |
Brave Search API key |
LDR_SERPAPI_API_KEY |
SerpAPI key |
Example Configurations
OpenAI (default):
{
"mcpServers": {
"local-deep-research": {
"command": "ldr-mcp",
"env": {
"LDR_LLM_PROVIDER": "openai",
"LDR_LLM_MODEL": "gpt-4",
"LDR_LLM_OPENAI_API_KEY": "sk-..."
}
}
}
}
Ollama (fully local, no API key needed):
{
"mcpServers": {
"local-deep-research": {
"command": "ldr-mcp",
"env": {
"LDR_LLM_PROVIDER": "ollama",
"LDR_LLM_MODEL": "llama3:8b"
}
}
}
}
Anthropic:
{
"mcpServers": {
"local-deep-research": {
"command": "ldr-mcp",
"env": {
"LDR_LLM_PROVIDER": "anthropic",
"LDR_LLM_MODEL": "claude-sonnet-4-20250514",
"LDR_LLM_ANTHROPIC_API_KEY": "sk-ant-..."
}
}
}
}
Logging
All log output goes to stderr (stdout is reserved for the JSON-RPC protocol). The log level is hardcoded to INFO — there is no environment variable to change it.
Available Tools
Research Tools
quick_research
Fast research summary. Typically takes 1-5 minutes.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
query |
string | Yes | Research question (max 10,000 chars) |
search_engine |
string | No | Search engine to use (e.g., "arxiv", "wikipedia", "auto") |
strategy |
string | No | Research strategy (e.g., "source-based", "rapid") |
iterations |
integer | No | Number of search iterations (1-10) |
questions_per_iteration |
integer | No | Questions per iteration (1-10) |
Returns:
{
"status": "success",
"summary": "Research summary text...",
"findings": ["finding1", "finding2"],
"sources": ["https://example.com/source1"],
"iterations": 3,
"formatted_findings": "Formatted markdown findings..."
}
Best for: fast fact-checking, simple queries, getting a quick overview.
detailed_research
Comprehensive research analysis. Typically takes 5-15 minutes.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
query |
string | Yes | Research question (max 10,000 chars) |
search_engine |
string | No | Search engine to use |
strategy |
string | No | Research strategy |
iterations |
integer | No | Number of search iterations (1-20) |
questions_per_iteration |
integer | No | Questions per iteration (1-10) |
Returns:
{
"status": "success",
"query": "original query",
"research_id": "unique-id",
"summary": "Detailed summary...",
"findings": ["finding1", "finding2"],
"sources": ["https://example.com/source1"],
"iterations": 5,
"formatted_findings": "Formatted markdown findings...",
"metadata": {"timestamp": "...", "search_tool": "...", "strategy": "..."}
}
Best for: in-depth analysis, nuanced topics, comprehensive coverage.
generate_report
Full structured markdown report with sections, citations, and bibliography. Typically takes 10-30 minutes.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
query |
string | Yes | Research topic (max 10,000 chars) |
search_engine |
string | No | Search engine to use |
searches_per_section |
integer | No | Searches per report section (1-10, default 2) |
Returns:
{
"status": "success",
"content": "# Report Title\n\n## Section 1\n...",
"metadata": {"timestamp": "...", "query": "..."}
}
Best for: publication-quality structured reports with proper citations.
analyze_documents
Search and analyze documents in a local collection using RAG. Typically takes 30 seconds - 2 minutes.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
query |
string | Yes | Search query (max 10,000 chars) |
collection_name |
string | Yes | Engine ID of the collection (e.g., "collection_3"). Use list_search_engines() to find available collections. |
max_results |
integer | No | Maximum documents to retrieve (1-100, default 10) |
Returns:
{
"status": "success",
"summary": "Summary of findings from documents...",
"documents": [{"content": "...", "metadata": {"source": "file.pdf", "page": 1}}],
"collection": "my-papers",
"document_count": 5
}
The data flow is: collection_name → FAISS index lookup → semantic similarity search → LLM summarization.
Best for: searching uploaded PDFs and documents in local collections. Use list_search_engines() to discover available collection IDs.
search
Raw search results without LLM processing. Typically takes 5-30 seconds. No LLM cost.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
query |
string | Yes | Search query (max 10,000 chars) |
engine |
string | Yes | Search engine to use (e.g., "arxiv", "wikipedia", "searxng"). Use list_search_engines() to see options. |
max_results |
integer | No | Maximum results to return (1-100, default 10) |
Returns:
{
"status": "success",
"query": "quantum computing",
"engine": "arxiv",
"result_count": 10,
"results": [
{
"title": "Quantum Computing: An Overview",
"link": "https://arxiv.org/abs/2301.12345",
"snippet": "We present a comprehensive overview..."
}
]
}
Common engines: arxiv (academic papers), pubmed (medical literature), wikipedia (encyclopedic), searxng (meta-search), openclaw (legal case law), github (code/repos), semantic_scholar (citations). Use list_search_engines() for the full list.
Best for: raw search results for your own analysis, quick lookups, checking what sources are available before running full research. Especially useful for monitoring and subscriptions — check for new content regularly without LLM cost.
Discovery Tools
These tools return instantly and are useful for exploring available options.
list_search_engines
Returns available search engines with their descriptions, strengths, weaknesses, and whether they require an API key or run locally.
list_strategies
Returns available research strategies with their names and descriptions.
get_configuration
Returns the current server configuration including LLM provider, model, temperature, and search defaults. API keys are intentionally excluded from the response.
Research Strategies Guide
LDR supports 19+ research strategies. Here are the most commonly used ones via MCP:
| Strategy | Speed | Accuracy | Best For |
|---|---|---|---|
rapid |
Fast | Lower | Breaking news, simple facts |
source-based |
Medium | High | Topics needing authoritative citations |
focused-iteration |
Medium | Highest (~95%) | Complex technical topics |
mcp (ReAct) |
Varies | High | Multi-step reasoning, when AI decides approach |
parallel |
Fast | Medium | Broad coverage, multiple angles |
evidence |
Slow | Very High | Verification-critical research |
Use list_strategies() to see all available strategies and their descriptions.
ReAct (Agentic) Strategy
The mcp strategy (also called "agentic") uses the ReAct pattern (Reasoning + Acting). Unlike fixed-pipeline strategies, the LLM decides what to do at each step.
How It Works
The ReAct loop follows this pattern:
- THOUGHT — The LLM reasons about what it knows and what it needs
- ACTION — It selects a tool to call (e.g.,
web_search,focused_research) - OBSERVATION — It receives the tool results (truncated to 5,000 chars)
- Repeat — Until the LLM has enough information to answer
Available Tools in the ReAct Agent
General search:
web_search— Quick web search using the default engine
Deep research (sub-strategies, bounded by max_depth=2):
focused_research— Iterative deep analysis from multiple angles. Supports optionaliterations(1-25) andsearch_engineoverride parameters.
Specialized search engines:
search_{engine}— Specialized engine search (e.g.,search_arxiv,search_wikipedia,search_pubmed,search_github)
Content fetching:
download_content— Fetch full text from a URL (max 10,000 chars)
External MCP server tools:
{server_name}.{tool_name}— Tools from connected external MCP servers (if configured)
Constants
| Constant | Value |
|---|---|
| Max iterations | 10 |
| Observation truncation | 5,000 chars |
| Max argument length | 10,000 chars |
| Download max length | 10,000 chars |
| Recursion depth limit | 2 |
| MCP discovery timeout | 30s |
| MCP tool call timeout | 60s |
When to Use
- Multi-step reasoning where different tools are needed at different stages
- Queries that need a mix of web search, specialized engines, and deep research
- Complex topics where the AI should dynamically decide the research approach
MCP Client (Connecting External MCP Servers)
LDR can also act as an MCP client, connecting to external MCP servers and making their tools available to the ReAct strategy.
Configuration
Configure external MCP servers via the mcp.servers setting. Each server needs:
{
"name": "my-server",
"command": "node",
"args": ["path/to/server.js"],
"env": {
"API_KEY": "..."
}
}
Config schema:
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | No | Server name for logging (default: "unnamed") |
command |
string | Yes | Executable to run |
args |
list[string] | No | Command arguments |
env |
dict[string, string] | No | Environment variables |
Command Whitelist
For security, only these commands are allowed:
node, npx, python, python3, uv, uvx, docker
Any other command will be rejected with an error.
Connection Details
- Transport: STDIO (same as the LDR MCP server itself)
- Retry logic: 5 attempts with exponential backoff (base 0.1s, max 2.0s, factor 2.0x)
- Graceful degradation: Failed servers are skipped; tools from working servers remain available
- Timeouts: 30s for tool discovery, 60s for tool calls
Tool Naming
External MCP tools appear in the ReAct agent as {server_name}.{tool_name}. For example, a tool called search on a server named my-server becomes my-server.search.
Error Handling
All tool calls return structured error responses when something goes wrong. Errors are classified into these categories:
| Error Type | Cause | User-Facing Message |
|---|---|---|
validation_error |
Bad parameters (empty query, out-of-range values) | Specific message (e.g., "Query cannot be empty") |
auth_error |
Invalid or missing API key (401) | "...failed (auth_error). Check server logs." |
service_unavailable |
Provider or search engine down (503) | "...failed (service_unavailable). Check server logs." |
timeout |
Operation took too long | "...failed (timeout). Check server logs." |
rate_limit |
API quota exceeded (429) | "...failed (rate_limit). Check server logs." |
connection_error |
Network connectivity issue | "...failed (connection_error). Check server logs." |
model_not_found |
Model doesn't exist (404) | "...failed (model_not_found). Check server logs." |
unknown |
Unclassified error | "...failed (unknown). Check server logs." |
All errors are logged to stderr with full detail. User-facing messages are sanitized — no stack traces or API keys are exposed.
Security Model
- STDIO-only transport — The server runs
mcp.run(transport="stdio"), which cannot be accessed over a network. Only the parent process (e.g., Claude Desktop, Claude Code, OpenClaw) can communicate with it. - No authentication needed — OS-level process isolation provides security. The parent process controls access.
- API keys never returned —
get_configurationintentionally excludes API keys from its response. - Error messages sanitized — No internal details, stack traces, or credentials in error responses.
- Input validation — All parameters have strict bounds and type checking.
- Per-call settings overrides — Settings overrides from tool parameters are in-memory only and not persisted.
@no_db_settings— Prevents database settings access from MCP calls.
Security Note: This MCP server is designed for local use only. Do not expose it over a network without implementing proper security controls (OAuth, rate limiting). See the MCP Security Guide for network deployment requirements.
Docker Deployment
The MCP server uses STDIO transport, which requires direct process communication with the host AI assistant (e.g., Claude Desktop). This means it must run on the host machine, not inside a Docker container.
- MCP server (
ldr-mcp) — install and run on the host machine only - Web service (
ldr-web) — can run in Docker
The Docker image does not include MCP extras, and adding them would not help — the STDIO transport cannot bridge the container boundary to reach Claude Desktop.
Usage Examples
Prompt Patterns
Quick fact-checking:
Use quick_research to find: What is the current population of Tokyo?
Deep analysis:
Use detailed_research with focused-iteration strategy to analyze:
What are the latest advances in solid-state battery technology?
Full report:
Generate a report on the impact of AI on drug discovery using source-based strategy
Document search:
Search collection 'research-papers' for: machine learning optimization techniques
Agentic research:
Use the mcp strategy to research the environmental impact of cryptocurrency mining,
considering both proof-of-work and proof-of-stake systems
Individual search engines (no LLM cost, fast):
Search arxiv for recent papers on diffusion models
Search pubmed for CRISPR clinical trials 2024
Search wikipedia for quantum error correction
Search openclaw for copyright fair use precedents
The search tool is especially useful for monitoring and subscriptions — check for new content on a topic regularly without burning LLM tokens. An AI agent can call search to get raw results, then decide whether to run a full detailed_research only when something interesting appears.
Tips
- Use
searchfor fast, free lookups before committing to a full research run - Start with
quick_researchto test your setup, then upgrade todetailed_researchfor depth - Use
focused-iterationstrategy for highest accuracy on technical topics - Lower temperature (0.3-0.5) for factual research, higher (0.8-1.2) for creative exploration (valid range: 0.0-2.0)
- Call
list_search_enginesandlist_strategiesfirst to see what's available in your configuration - Use
get_configurationto verify your LLM and search settings are correct
Troubleshooting
| Problem | Solution |
|---|---|
| Server won't start | Verify MCP extras are installed: pip install "local-deep-research[mcp]" |
| "API key" errors | Check env vars in your Claude Desktop config (e.g., LDR_LLM_OPENAI_API_KEY) |
| "Invalid strategy" error | Run list_strategies() to see valid strategy names |
| "Unknown search engine" error | Run list_search_engines() to see available engines |
| No results returned | Try a different search_engine or make your query more specific |
| Server logs | Check stderr output. Log level is hardcoded to INFO. |
Related Documentation
- API Quickstart — HTTP and Python API access
- Search Engines Guide — Available search engines and configuration
- Configuration Reference — All LDR settings
- Features Overview — All LDR features
- CLI Tools — Command-line tools including
ldr-mcp