deep-research
Conduct multi-round deep web research using keywords and topics to gather comprehensive information from general, news, and finance sources.
Instructions
Deep web information search tool that can conduct multi-round in-depth research based on keywords and topics
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| question | Yes | User question | |
| reference | No | Reference materials | |
| keywords | No | Search keywords, please provide 1~5 keywords. Each keyword must: include complete subject and predicate, avoid pronouns and references, have independent search value, avoid logical overlap between keywords, and be directly relevant to the question | |
| topic | No | Search topic | general |
| rounds | No | Current search round, defaults to 1 |
Input Schema (JSON Schema)
{
"properties": {
"keywords": {
"description": "Search keywords, please provide 1~5 keywords. Each keyword must: include complete subject and predicate, avoid pronouns and references, have independent search value, avoid logical overlap between keywords, and be directly relevant to the question",
"items": {
"type": "string"
},
"maxItems": 5,
"minItems": 0,
"type": "array"
},
"question": {
"description": "User question",
"type": "string"
},
"reference": {
"description": "Reference materials",
"type": "string"
},
"rounds": {
"default": 1,
"description": "Current search round, defaults to 1",
"type": "number"
},
"topic": {
"default": "general",
"description": "Search topic",
"enum": [
"general",
"news",
"finance"
],
"type": "string"
}
},
"required": [
"question"
],
"type": "object"
}
Implementation Reference
- src/index.ts:113-146 (handler)The primary handler function for the 'deep-research' tool. It checks for API key, parses input schema, performs parallel Tavily searches for provided keywords, accumulates search results, generates a specialized prompt, and returns it as tool output.async function deepResearch(args: unknown): Promise<ServerResult> { if (!CONFIG.TAVILY_API_KEY) { return { isError: true, content: [ { type: 'text', text: 'Please configure the `TAVILY_API_KEY` environment variable, get it from https://tavily.com/', }, ], }; } const { question, reference = '', keywords = [], topic, rounds } = DeepResearchToolSchema.parse(args); let searchResults = reference; if (keywords.length) { const results = await Promise.allSettled(keywords.map((keyword) => searchTavily(keyword, { topic }))); searchResults += results .filter((result): result is PromiseFulfilledResult<string> => result.status === 'fulfilled') .map((result) => result.value) .join('\n'); } return { content: [ { type: 'text', text: generatePrompt(question, searchResults, rounds), }, ], }; }
- src/index.ts:97-110 (schema)Zod schema defining the input parameters for the 'deep-research' tool, including question, optional reference and keywords, topic, and rounds.const DeepResearchToolSchema = z.object({ question: z.string().describe('User question'), reference: z.string().optional().describe('Reference materials'), keywords: z .array(z.string()) .min(0) .max(CONFIG.MAX_SEARCH_KEYWORDS) .optional() .describe( `Search keywords, please provide 1~${CONFIG.MAX_SEARCH_KEYWORDS} keywords. Each keyword must: include complete subject and predicate, avoid pronouns and references, have independent search value, avoid logical overlap between keywords, and be directly relevant to the question`, ), topic: z.enum(['general', 'news', 'finance']).default('general').describe('Search topic'), rounds: z.number().default(1).describe('Current search round, defaults to 1'), });
- src/index.ts:162-173 (registration)Registration of the 'deep-research' tool: advertises it in ListTools response with name, description, and input schema; wires the deepResearch handler to CallTool requests.mcpServer.server.setRequestHandler(ListToolsRequestSchema, () => ({ tools: [ { name: 'deep-research', description: 'Deep web information search tool that can conduct multi-round in-depth research based on keywords and topics', inputSchema: zodToJsonSchema(DeepResearchToolSchema), }, ], })); mcpServer.server.setRequestHandler(CallToolRequestSchema, (request) => deepResearch(request.params.arguments));
- src/index.ts:25-35 (helper)Helper function to perform a single Tavily search for a keyword, formats results with titles and content snippets.async function searchTavily(keyword: string, options: TavilySearchOptions): Promise<string> { const tvly = tavily({ apiKey: CONFIG.TAVILY_API_KEY }); const response = await tvly.search(keyword, options); let result = `## Search Results for \`${response.query}\`\n`; response.results.forEach((searchResult, index) => { result += `### Reference ${index + 1}:\n`; result += `Title: ${searchResult.title}\n`; result += `Content: ${searchResult.content}\n`; }); return result; }
- src/index.ts:37-94 (helper)Helper function that generates a detailed system prompt for the LLM to decide whether to search more or answer based on accumulated results, enforcing iterative research behavior.function generatePrompt(question: string, searchResults: string, rounds: number): string { return `# Role Definition You are a professional information search and analysis expert, specializing in: - Analyzing core information needs from user queries - Designing precise search strategies - Synthesizing and distilling information - Providing accurate and comprehensive answers # User Question ${question} # Current Environment Current Search Round: ${rounds} Maximum Search Rounds: ${CONFIG.MAX_PLANNING_ROUNDS} Current Time: ${new Date().toLocaleString()} # Known Information ${searchResults ?? 'No reference information available'} # Analysis Steps 1. Resource Sufficiency Assessment - Carefully analyze if existing information is sufficient to answer the user's question - Identify information gaps or areas requiring additional verification 2. Search Strategy (if needed) - Identify specific information points that need supplementation - Design precise search keywords (each keyword must meet these requirements): * Include complete subject and predicate * Avoid pronouns and references * Have independent search value * Avoid logical overlap between keywords - Keyword quantity limit: 1~${CONFIG.MAX_SEARCH_KEYWORDS} 3. Continue Search (if needed) - Use current "Known Information" as reference parameter - Set rounds parameter to ${rounds + 1} - Output only search keywords, without any other content 4. Direct Answer (if information is sufficient) - Provide complete answer based on available information - Ensure the answer is accurate, comprehensive, and logically clear # Output Requirements ## If Further Search is Needed - Output only the list of search keywords - One keyword per line - Do not include any other explanations or notes ## If Direct Answer is Possible - Provide a clear, structured answer - Reference relevant sources when necessary - Clearly indicate any uncertain information # Constraints - Current round has reached ${rounds}/${CONFIG.MAX_PLANNING_ROUNDS}, must provide direct answer if maximum rounds exceeded - Search keywords must be independent and precise, no ambiguity allowed - Prohibited to output content unrelated to search strategy`; }