Skip to main content
Glama
qpd-v

MCP Web Research Server

by qpd-v

deep_research

Explore in-depth research topics by extracting and analyzing web content with controlled depth, branching, and relevance scoring. Supports real-time web research with structured data integration.

Instructions

Perform deep research on a topic with content extraction and analysis

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
maxBranchingNoMaximum number of related paths to explore
maxDepthNoMaximum depth of related content exploration
minRelevanceScoreNoMinimum relevance score for including content
timeoutNoResearch timeout in milliseconds
topicYesResearch topic or question

Implementation Reference

  • Core handler implementing the deep_research tool logic: initializes ResearchSession, performs parallel searches on derived queries, deduplicates results, processes top and remaining URLs, completes session, and returns formatted ResearchResult with timings.
    public async startResearch(topic: string, options: DeepResearchOptions = {}): Promise<ResearchResult> {
        const startTime = Date.now();
        const timings: { [key: string]: number } = {};
    
        console.log('[Performance] Starting research for topic:', topic);
        console.log('[Performance] Options:', options);
    
        // Create new research session
        const session = new ResearchSession(topic, {
            maxDepth: options.maxDepth,
            maxBranching: options.maxBranching,
            timeout: options.timeout,
            minRelevanceScore: options.minRelevanceScore,
            maxParallelOperations: options.maxParallelOperations
        });
    
        console.log('[Performance] Created research session:', session.id);
        this.activeSessions.set(session.id, session);
    
        try {
            console.log('[Performance] Starting parallel search...');
            const parallelSearchStart = Date.now();
            
            const queries = [
                topic,
                `${topic} tutorial`,
                `${topic} guide`,
                `${topic} example`,
                `${topic} implementation`,
                `${topic} code`,
                `${topic} design pattern`,
                `${topic} best practice`
            ];
            console.log('[Performance] Search queries:', queries);
    
            const searchResults = await this.parallelSearch.parallelSearch(queries);
            timings.parallelSearch = Date.now() - parallelSearchStart;
            console.log('[Performance] Parallel search complete. Duration:', timings.parallelSearch, 'ms');
    
            const deduplicationStart = Date.now();
            const allResults = searchResults.results.flatMap(result => result.results);
            console.log('[Performance] Total results:', allResults.length);
    
            const uniqueResults = this.deduplicateResults(allResults);
            console.log('[Performance] Unique results:', uniqueResults.length);
    
            const sortedResults = uniqueResults.sort((a, b) => b.relevanceScore - a.relevanceScore);
            timings.deduplication = Date.now() - deduplicationStart;
            console.log('[Performance] Deduplication complete. Duration:', timings.deduplication, 'ms');
    
            // Process top results first
            console.log('[Performance] Processing top 5 results...');
            const topProcessingStart = Date.now();
            const topResults = sortedResults.slice(0, 5);
            await Promise.all(topResults.map(r => {
                console.log('[Performance] Processing URL:', r.url);
                return session.processUrl(r.url);
            }));
            timings.topResultsProcessing = Date.now() - topProcessingStart;
            console.log('[Performance] Top results processing complete. Duration:', timings.topResultsProcessing, 'ms');
    
            // Process remaining results
            console.log('[Performance] Processing remaining results...');
            const remainingProcessingStart = Date.now();
            const remainingResults = sortedResults.slice(5);
            await Promise.all(remainingResults.map(r => {
                console.log('[Performance] Processing URL:', r.url);
                return session.processUrl(r.url);
            }));
            timings.remainingResultsProcessing = Date.now() - remainingProcessingStart;
            console.log('[Performance] Remaining results processing complete. Duration:', timings.remainingResultsProcessing, 'ms');
    
            // Complete the session
            console.log('[Performance] Completing session...');
            await session.complete();
    
            // Format and return results
            console.log('[Performance] Formatting results...');
            const results = this.formatResults(session);
            
            // Add timing information
            timings.total = Date.now() - startTime;
            results.timing.operations = {
                parallelSearch: timings.parallelSearch,
                deduplication: timings.deduplication,
                topResultsProcessing: timings.topResultsProcessing,
                remainingResultsProcessing: timings.remainingResultsProcessing,
                total: timings.total
            };
    
            console.log('[Performance] Research complete. Total duration:', timings.total, 'ms');
            console.log('[Performance] Operation timings:', timings);
    
            return results;
        } catch (error) {
            console.error(`[Performance] Error in research session ${session.id}:`, error);
            throw error;
        } finally {
            // Cleanup
            this.activeSessions.delete(session.id);
            await this.parallelSearch.cleanup();
        }
    }
  • src/index.ts:87-124 (registration)
    Registration of the 'deep_research' tool in the MCP server's listTools handler, defining name, description, and input schema.
    {
        name: 'deep_research',
        description: 'Perform deep research on a topic with content extraction and analysis',
        inputSchema: {
            type: 'object',
            properties: {
                topic: {
                    type: 'string',
                    description: 'Research topic or question'
                },
                maxDepth: {
                    type: 'number',
                    description: 'Maximum depth of related content exploration',
                    minimum: 1,
                    maximum: 2
                },
                maxBranching: {
                    type: 'number',
                    description: 'Maximum number of related paths to explore',
                    minimum: 1,
                    maximum: 3
                },
                timeout: {
                    type: 'number',
                    description: 'Research timeout in milliseconds',
                    minimum: 30000,
                    maximum: 55000
                },
                minRelevanceScore: {
                    type: 'number',
                    description: 'Minimum relevance score for including content',
                    minimum: 0,
                    maximum: 1
                }
            },
            required: ['topic']
        }
    },
  • MCP CallToolRequest handler case for 'deep_research', validates args and delegates to DeepResearch.startResearch instance.
    case 'deep_research': {
        const args = request.params.arguments as unknown as DeepResearchArgs;
        if (!args?.topic) {
            throw new McpError(ErrorCode.InvalidParams, 'Topic is required');
        }
    
        console.log(`Starting deep research on topic: ${args.topic}`);
        const result = await deepResearch.startResearch(args.topic, {
            maxDepth: Math.min(args.maxDepth || 2, 2),
            maxBranching: Math.min(args.maxBranching || 3, 3),
            timeout: Math.min(args.timeout || 55000, 55000),
            minRelevanceScore: args.minRelevanceScore || 0.7
        });
    
        return {
            content: [
                {
                    type: 'text',
                    text: JSON.stringify(result, null, 2)
                }
            ]
        };
    }
  • TypeScript interface defining input arguments for deep_research tool, matching the inputSchema.
    interface DeepResearchArgs {
        topic: string;
        maxDepth?: number;
        maxBranching?: number;
        timeout?: number;
        minRelevanceScore?: number;
    }
  • Interface for options passed to startResearch method.
    export interface DeepResearchOptions {
        maxDepth?: number;
        maxBranching?: number;
        timeout?: number;
        minRelevanceScore?: number;
        maxParallelOperations?: number;
    }
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It mentions 'content extraction and analysis' but fails to detail critical aspects such as execution time, resource usage, error handling, or output format. This leaves significant gaps in understanding how the tool behaves beyond its basic purpose.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that directly states the tool's purpose without unnecessary words. It's front-loaded with the core action and avoids redundancy, making it highly concise and well-structured for quick comprehension.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity of a 'deep research' tool with 5 parameters, no annotations, and no output schema, the description is insufficient. It doesn't explain what 'deep research' entails, how results are returned, or any behavioral constraints, leaving the agent with inadequate information for effective use in a broader context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, meaning all parameters are documented in the schema. The description adds no additional semantic context about parameters beyond implying 'deep research' involves branching and depth. This meets the baseline for high schema coverage but doesn't enhance understanding of parameter roles or interactions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose as 'Perform deep research on a topic with content extraction and analysis,' which specifies the verb (perform deep research) and resource (topic) with additional capabilities (content extraction and analysis). However, it doesn't explicitly differentiate from sibling tools like 'parallel_search' or 'visit_page,' which prevents a perfect score.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives like 'parallel_search' or 'visit_page.' It lacks any context about appropriate scenarios, prerequisites, or exclusions, leaving the agent with minimal direction for tool selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/qpd-v/mcp-DEEPwebresearch'

If you have feedback or need assistance with the MCP directory API, please join our Discord server