Skip to main content
Glama
wlmwwx

Jina AI Remote MCP Server

by wlmwwx

parallel_search_web

Execute multiple web searches simultaneously to gather comprehensive information and diverse perspectives on a topic. Provide distinct queries covering different aspects for optimal results.

Instructions

Run multiple web searches in parallel for comprehensive topic coverage and diverse perspectives. For best results, provide multiple search queries that explore different aspects of your topic. You can use expand_query to help generate diverse queries, or create them yourself.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
searchesYesArray of search configurations to execute in parallel (maximum 5 searches for optimal performance)
timeoutNoTimeout in milliseconds for all searches

Implementation Reference

  • The main handler function for the parallel_search_web tool. It validates the bearer token, deduplicates search queries, defines a web search wrapper, executes parallel searches using executeParallelSearches, and formats the results.
    async ({ searches, timeout }: { searches: SearchWebArgs[]; timeout: number }) => {
    	try {
    		const props = getProps();
    
    		const tokenError = checkBearerToken(props.bearerToken);
    		if (tokenError) {
    			return tokenError;
    		}
    
    		const uniqueSearches = searches.filter((search, index, self) =>
    			index === self.findIndex(s => s.query === search.query)
    		);
    
    		// Use the common web search function
    		const webSearchFunction = async (searchArgs: SearchWebArgs) => {
    			return executeWebSearch(searchArgs, props.bearerToken);
    		};
    
    		// Execute parallel searches using utility
    		const results = await executeParallelSearches(uniqueSearches, webSearchFunction, { timeout });
    
    		return {
    			content: formatParallelSearchResultsToContentItems(results),
    		};
    	} catch (error) {
    		return createErrorResponse(`Error: ${error instanceof Error ? error.message : String(error)}`);
    	}
    },
  • Zod input schema for parallel_search_web tool defining the array of web search configurations (max 5) and timeout.
    {
    	searches: z.array(z.object({
    		query: z.string().describe("Search terms or keywords to find relevant web content"),
    		num: z.number().default(30).describe("Maximum number of search results to return, between 1-100"),
    		tbs: z.string().optional().describe("Time-based search parameter, e.g., 'qdr:h' for past hour"),
    		location: z.string().optional().describe("Location for search results, e.g., 'London', 'New York', 'Tokyo'"),
    		gl: z.string().optional().describe("Country code, e.g., 'dz' for Algeria"),
    		hl: z.string().optional().describe("Language code, e.g., 'zh-cn' for Simplified Chinese")
    	})).max(5).describe("Array of search configurations to execute in parallel (maximum 5 searches for optimal performance)"),
    	timeout: z.number().default(30000).describe("Timeout in milliseconds for all searches")
    },
  • Registration of the parallel_search_web tool using server.tool() in registerJinaTools function.
    server.tool(
    	"parallel_search_web",
    	"Run multiple web searches in parallel for comprehensive topic coverage and diverse perspectives. For best results, provide multiple search queries that explore different aspects of your topic. You can use expand_query to help generate diverse queries, or create them yourself. 💡 Use this when you need to gather information from multiple search angles at once for efficiency.",
    	{
    		searches: z.array(z.object({
    			query: z.string().describe("Search terms or keywords to find relevant web content"),
    			num: z.number().default(30).describe("Maximum number of search results to return, between 1-100"),
    			tbs: z.string().optional().describe("Time-based search parameter, e.g., 'qdr:h' for past hour"),
    			location: z.string().optional().describe("Location for search results, e.g., 'London', 'New York', 'Tokyo'"),
    			gl: z.string().optional().describe("Country code, e.g., 'dz' for Algeria"),
    			hl: z.string().optional().describe("Language code, e.g., 'zh-cn' for Simplified Chinese")
    		})).max(5).describe("Array of search configurations to execute in parallel (maximum 5 searches for optimal performance)"),
    		timeout: z.number().default(30000).describe("Timeout in milliseconds for all searches")
    	},
    	async ({ searches, timeout }: { searches: SearchWebArgs[]; timeout: number }) => {
    		try {
    			const props = getProps();
    
    			const tokenError = checkBearerToken(props.bearerToken);
    			if (tokenError) {
    				return tokenError;
    			}
    
    			const uniqueSearches = searches.filter((search, index, self) =>
    				index === self.findIndex(s => s.query === search.query)
    			);
    
    			// Use the common web search function
    			const webSearchFunction = async (searchArgs: SearchWebArgs) => {
    				return executeWebSearch(searchArgs, props.bearerToken);
    			};
    
    			// Execute parallel searches using utility
    			const results = await executeParallelSearches(uniqueSearches, webSearchFunction, { timeout });
    
    			return {
    				content: formatParallelSearchResultsToContentItems(results),
    			};
    		} catch (error) {
    			return createErrorResponse(`Error: ${error instanceof Error ? error.message : String(error)}`);
    		}
    	},
    );
  • Core helper function that executes multiple searches in parallel with timeout handling, used by the parallel_search_web handler.
    export async function executeParallelSearches<T>(
        searches: T[],
        searchFunction: (searchArgs: T) => Promise<SearchResultOrError>,
        options: ParallelSearchOptions = {}
    ): Promise<ParallelSearchResult[]> {
        const { timeout = 30000 } = options;
    
        // Execute all searches in parallel
        const searchPromises = searches.map(async (searchArgs) => {
            try {
                return await searchFunction(searchArgs);
            } catch (error) {
                return { error: `Search failed: ${error instanceof Error ? error.message : String(error)}` };
            }
        });
    
        // Wait for all searches with timeout
        const results = await Promise.allSettled(searchPromises);
        const timeoutPromise = new Promise(resolve => setTimeout(() => resolve('timeout'), timeout));
    
        const completedResults = await Promise.race([
            Promise.all(results.map(result =>
                result.status === 'fulfilled' ? result.value : { error: 'Promise rejected' }
            )),
            timeoutPromise
        ]);
    
        if (completedResults === 'timeout') {
            throw new Error(`Parallel search timed out after ${timeout}ms`);
        }
    
        return completedResults as ParallelSearchResult[];
    }
  • Type definition for individual web search arguments used in parallel_search_web searches array.
    export interface SearchWebArgs {
        query: string;
        num?: number;
        tbs?: string;
        location?: string;
        gl?: string;
        hl?: string;
    }
Behavior3/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 'parallel' execution and 'comprehensive topic coverage and diverse perspectives,' which hints at performance characteristics and intent. However, it doesn't disclose critical behavioral traits like rate limits, authentication needs, error handling, or what happens when searches fail. The description adds some context about optimal performance ('maximum 5 searches') but lacks comprehensive behavioral transparency for a tool with potentially complex execution.

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

Conciseness4/5

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

The description is appropriately concise with three sentences that each serve a purpose: stating the tool's purpose, providing usage guidance, and mentioning an alternative tool. It's front-loaded with the core functionality. There's minimal waste, though the second sentence could be slightly more direct. Overall, it's efficiently structured for quick comprehension.

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

Completeness3/5

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

Given the tool's complexity (parallel execution, multiple parameters), lack of annotations, and no output schema, the description is moderately complete. It covers the purpose and basic usage but misses important contextual details: what the output looks like (no output schema), error conditions, performance guarantees, or how results from parallel searches are combined. For a tool with significant operational complexity, the description should provide more complete context about behavior and results.

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%, so the schema already documents all parameters thoroughly. The description doesn't add any parameter-specific information beyond what's in the schema. It generically mentions 'provide multiple search queries' which aligns with the 'searches' parameter but doesn't provide additional semantics, syntax examples, or constraints. Baseline 3 is appropriate when the schema does all the parameter documentation work.

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: 'Run multiple web searches in parallel for comprehensive topic coverage and diverse perspectives.' It specifies the verb ('Run multiple web searches in parallel') and resource ('web searches'), but doesn't explicitly distinguish it from sibling tools like 'search_web' or 'parallel_search_arxiv' beyond mentioning 'web' in the name and description. The purpose is clear but sibling differentiation is implicit rather than explicit.

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

Usage Guidelines4/5

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

The description provides clear usage context: 'For best results, provide multiple search queries that explore different aspects of your topic.' It also mentions an alternative tool: 'You can use expand_query to help generate diverse queries.' However, it doesn't explicitly state when NOT to use this tool versus alternatives like 'search_web' or 'parallel_search_arxiv', nor does it cover prerequisites or exclusions beyond the implicit parallel nature.

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

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/wlmwwx/jina-mcp'

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