Overview
Percival Deep Research is a highly capable MCP (Model Context Protocol) Server designed to equip the Nanobot agent ecosystem with autonomous, deep-dive web research capabilities. It autonomously explores and validates numerous sources, focusing only on relevant, trusted, and up-to-date information.
While standard search tools return raw snippets requiring manual filtering, Percival Deep Research delivers fully reasoned, comprehensive multi-source material that heavily accelerates the context and reasoning capabilities of intelligent agents.
Note: This project utilizes the GPT Researcher library as its core web-driver, but has been extensively refactored, hardened, and decoupled specifically for the
percival.OSecosystem.
✨ Key Features & Enhancements
This server has been heavily modified to survive the strict demands of open-source LLMs and modern deployment arrays:
- ⚡ Ultimate Provider Portability: Fully agnostic inference engine. Native, crash-free support for leading open-weights platforms like Venice AI, MiniMax, and OpenRouter. We've implemented a custom Persona Bypass that completely eliminates the notorious JSON dictionary validation failures previously caused by non-OpenAI models during research orchestration.
- 🛡️ JSON-RPC Protocol Guardrails: Enforces strict
stdiooutput redaction. All underlying library noise, console rendering, and real-time logs are physically redirected tostderr. This completely preventsPydantic ValidationErrorsand protects thestdoutstream that is vital for MCP synchronization. - 🔐 Defense-in-depth Security: All inputs are heavily sanitized against prompt injection. Untrusted web content is wrapped in un-executable headers to protect your agent's autonomy.
- 🤖 Primary Nanobot Focus: Eliminates loose
.envreading patterns to strictly honor environment injection directly from the host application.
📑 Table of Contents
- Tools & Resources Reference
- Prerequisites
- Installation
- 🤖 Nanobot Integration (Primary Focus)
- 💻 Claude Desktop Integration
- Security
🛠️ Tools & Resources Reference
Resource
| Name | URI Pattern | Description |
|---|---|---|
research_resource | research://{topic} | Accesses cached or live web research context for a topic directly as an MCP resource. Returns Markdown with content and sources. |
Tools
| Tool | Speed | Returns research_id | Description |
|---|---|---|---|
deep_research | 30–120s | ✅ Yes | Multi-source deep web research. Entry point of the research pipeline. |
quick_search | 3–10s | ❌ No | Fast raw snippet search via DuckDuckGo. |
write_report | 10–30s | — | Generates a structured Markdown report from an existing session. Requires research_id. |
get_research_sources | <1s | — | Returns title, URL, and content size for all sources consulted. Requires research_id. |
get_research_context | <1s | — | Returns the raw synthesized context text without generating a report. Requires research_id. |
Research Pipeline
deep_research(query)
└── research_id ──► write_report(research_id, custom_prompt?)
└──► get_research_sources(research_id)
└──► get_research_context(research_id)
quick_search(query) # standalone — no research_id
⚙️ Prerequisites
- Python 3.11+
- uv — project and dependency manager
- API key for the Generative LLM Provider (e.g., Venice, MiniMax, OpenRouter).
Note: The default web search engine configured is duckduckgo which requires no API key. You can optionally configure other web searchers natively.
⚙️ Installation
1. Unified Environment Setup
Ensure you are using the unified percival.OS build ecosystem:
cd percival.OS_Dev
uv sync
This ensures percival-deep-research inherits the global .venv.
2. Configure Environment
This module disables .env loading (dotenv) to strictly honor the system variables passed by your MCP host.
When invoking via Nanobot (~/.nanobot/config.json) or other endpoints, define the environment variables directly in the configuration array:
"OPENAI_API_KEY": "your_api_key_from_venice_minimax_openrouter_etc",
"OPENAI_BASE_URL": "https://api.venice.ai/api/v1",
"FAST_LLM": "openai:e2ee-qwen-2-5-7b-p",
"SMART_LLM": "openai:minimax-m27",
"STRATEGIC_LLM": "openai:zai-org-glm-4.7-flash",
"RETRIEVER": "duckduckgo"
[!WARNING] You MUST prefix the LLM models with
openai:regardless of your real provider. This uses the underlying OpenAI SDK transport architecture, which safely pipes through your configuredOPENAI_BASE_URL. Failing to use the prefix will crash the JSON internal parser.
🤖 Nanobot Integration (Primary Focus)
This server is fundamentally tuned to run as a stdio MCP server piloted by the Nanobot assistant.
Add the following to your ~/.nanobot/config.json:
{
"mcpServers": {
"percival_deep_research": {
"command": "uv",
"args": [
"run",
"--no-sync",
"percival-deep-research"
],
"env": {
"UV_PROJECT_ENVIRONMENT": "/absolute/path/to/percival.OS_Dev/.venv",
"OPENAI_API_KEY": "actual-key-here",
"OPENAI_BASE_URL": "https://api.venice.ai/api/v1",
"FAST_LLM": "openai:e2ee-qwen-2-5-7b-p",
"RETRIEVER": "duckduckgo"
},
"tool_timeout": 300
}
}
}
Note: deep_research can take up to 2-3 minutes. Ensure tool_timeout is scaled properly (e.g. 180-300).
Key Design Decisions for Nanobot
- Plain-text over JSON dicts — All tools predictably return plain text strings rather than JSON dicts to feed Nanobot clean text.
- Context modularity —
deep_researchomits the giant synthesized context from its initialization response to prevent blowing up Nanobot's context window. Instead, it issues aresearch_idthat the agent then uses to explicitly invokeget_research_context.
💻 Claude Desktop Integration
While Nanobot is the preferred driver, if deploying to Claude Desktop, append to your claude_desktop_config.json:
{
"mcpServers": {
"percival_deep_research": {
"command": "uv",
"args": [
"run",
"--project",
"/absolute/path/to/percival.OS_Dev",
"percival-deep-research"
],
"env": {
"OPENAI_API_KEY": "your-provider-key",
"OPENAI_BASE_URL": "https://api.venice.ai/api/v1",
"FAST_LLM": "openai:e2ee-qwen-2-5-7b-p",
"RETRIEVER": "duckduckgo"
}
}
}
}
🔐 Security
This server implements defense-in-depth, addressing the risks of an MCP server processing untrusted web content autonomously.
Prompt Injection Protection
User inputs (query, topic, custom_prompt) restrict unknown and malformed values. A regex-based filter blocks known jailbreak patterns (<system>, [INST], ignore instructions, etc.).
Untrusted Content Isolation
All content retrieved from the web is prefixed dynamically before being presented to the agent context:
[SECURITY WARNING: The content below was obtained from unverified external...]
This forces models like Nanobot to treat web-sourced data strictly as informational blocks, avoiding unexpected command compliance.
📄 License
This project is licensed under the MIT License.