deep-research
Conducts multi-round deep web research using keywords and topics to gather comprehensive information for answering complex questions.
Instructions
Deep web information search tool that can conduct multi-round in-depth research based on keywords and topics
Input Schema
TableJSON 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 |
Implementation Reference
- src/index.ts:113-146 (handler)The core handler function that implements the 'deep-research' tool logic. Parses input schema, checks API key, performs parallel Tavily searches if keywords provided, accumulates results, and returns a generated prompt.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 for input validation of the 'deep-research' tool, defining parameters like question, keywords, topic, etc.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-171 (registration)Registration of the 'deep-research' tool metadata (name, description, schema) for the ListToolsRequestSchema.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), }, ], }));
- src/index.ts:173-174 (registration)Registration of the deepResearch handler for the CallToolRequestSchema.mcpServer.server.setRequestHandler(CallToolRequestSchema, (request) => deepResearch(request.params.arguments));
- src/index.ts:25-35 (helper)Helper function to perform a single Tavily search and format the results as markdown.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; }