parallel_search_ssrn
Execute multiple SSRN academic searches simultaneously to gather comprehensive social science research from diverse angles and methodologies.
Instructions
Run multiple SSRN searches in parallel for comprehensive social science research coverage and diverse academic angles. For best results, provide multiple search queries that explore different research angles and methodologies. You can use expand_query to help generate diverse queries, or create them yourself.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| searches | Yes | Array of SSRN search configurations to execute in parallel (maximum 5 searches for optimal performance) | |
| timeout | No | Timeout in milliseconds for all searches |
Implementation Reference
- src/tools/jina-tools.ts:727-767 (handler)Primary handler implementation for the 'parallel_search_ssrn' tool. Registers the tool with MCP server, defines input schema, and implements parallel execution logic using executeSsrnSearch and executeParallelSearches.if (isToolEnabled("parallel_search_ssrn")) { server.tool( "parallel_search_ssrn", "Run multiple SSRN searches in parallel for comprehensive social science research coverage and diverse academic angles. For best results, provide multiple search queries that explore different research angles and methodologies. You can use expand_query to help generate diverse queries, or create them yourself.", { searches: z.array(z.object({ query: z.string().describe("Academic search terms, author names, or research topics"), num: z.number().default(30).describe("Maximum number of academic papers to return, between 1-100"), tbs: z.string().optional().describe("Time-based search parameter, e.g., 'qdr:h' for past hour") })).max(5).describe("Array of SSRN 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: SearchSsrnArgs[]; 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 SSRN search function const ssrnSearchFunction = async (searchArgs: SearchSsrnArgs) => { return executeSsrnSearch(searchArgs, props.bearerToken); }; // Execute parallel searches using utility const results = await executeParallelSearches(uniqueSearches, ssrnSearchFunction, { timeout }); return { content: formatParallelSearchResultsToContentItems(results), }; } catch (error) { return createErrorResponse(`Error: ${error instanceof Error ? error.message : String(error)}`); } }, );
- src/utils/search.ts:22-26 (schema)Type definition for SearchSsrnArgs used in the tool's input schema.export interface SearchSsrnArgs { query: string; num?: number; tbs?: string; }
- src/utils/search.ts:137-166 (helper)Core helper function executeSsrnSearch that performs a single SSRN search via Jina API, called by the parallel handler.export async function executeSsrnSearch( searchArgs: SearchSsrnArgs, bearerToken: string ): Promise<SearchResultOrError> { try { const response = await fetch('https://svip.jina.ai/', { method: 'POST', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', 'Authorization': `Bearer ${bearerToken}`, }, body: JSON.stringify({ q: searchArgs.query, domain: 'ssrn', num: searchArgs.num || 30, ...(searchArgs.tbs && { tbs: searchArgs.tbs }) }), }); if (!response.ok) { return { error: `SSRN search failed for query "${searchArgs.query}": ${response.statusText}` }; } const data = await response.json() as any; return { query: searchArgs.query, results: data.results || [] }; } catch (error) { return { error: `SSRN search failed for query "${searchArgs.query}": ${error instanceof Error ? error.message : String(error)}` }; } }
- src/utils/search.ts:309-341 (helper)Generic helper executeParallelSearches for running multiple searches concurrently with timeout handling.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[]; }
- src/index.ts:13-23 (registration)Tool listed in parallel tag and ALL_TOOLS for enabling/disabling via query params.parallel: ["parallel_search_web", "parallel_search_arxiv", "parallel_search_ssrn", "parallel_read_url"], read: ["read_url", "parallel_read_url", "capture_screenshot_url"], utility: ["primer", "show_api_key", "expand_query", "guess_datetime_url", "extract_pdf"], rerank: ["sort_by_relevance", "deduplicate_strings", "deduplicate_images"], }; // All available tools const ALL_TOOLS = [ "primer", "show_api_key", "read_url", "capture_screenshot_url", "guess_datetime_url", "search_web", "search_arxiv", "search_ssrn", "search_images", "search_jina_blog", "expand_query", "parallel_search_web", "parallel_search_arxiv", "parallel_search_ssrn", "parallel_read_url",
- src/index.ts:100-100 (registration)Main entry point calls registerJinaTools which conditionally registers parallel_search_ssrn based on enabledTools.registerJinaTools(server, () => currentProps, enabledTools);