Skip to main content
Glama
jina-ai

Jina AI Remote MCP Server

Official
by jina-ai

search_web

Search the web for up-to-date information, news, articles, and websites. Use this tool to research topics, find resources, or discover relevant content with customizable filters like location, language, and time range.

Instructions

Search the entire web for current information, news, articles, and websites. Use this when you need up-to-date information, want to find specific websites, research topics, or get the latest news. Ideal for answering questions about recent events, finding resources, or discovering relevant content. 💡 Tip: Use parallel_search_web if you need to run multiple searches simultaneously.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
glNoCountry code, e.g., 'dz' for Algeria
hlNoLanguage code, e.g., 'zh-cn' for Simplified Chinese
locationNoLocation for search results, e.g., 'London', 'New York', 'Tokyo'
numNoMaximum number of search results to return, between 1-100
queryYesSearch terms or keywords to find relevant web content (e.g., 'climate change news 2024', 'best pizza recipe')
tbsNoTime-based search parameter, e.g., 'qdr:h' for past hour, can be qdr:h, qdr:d, qdr:w, qdr:m, qdr:y

Implementation Reference

  • The async handler function implementing the search_web tool logic, handling single or array of queries, calling executeWebSearch directly or in parallel.
    async ({ query, num, tbs, location, gl, hl }: { query: string | string[]; num: number; tbs?: string; location?: string; gl?: string; hl?: string }) => { try { const props = getProps(); const tokenError = checkBearerToken(props.bearerToken); if (tokenError) { return tokenError; } // Handle single query or single-element array if (typeof query === 'string' || (Array.isArray(query) && query.length === 1)) { const singleQuery = typeof query === 'string' ? query : query[0]; const searchResult = await executeWebSearch({ query: singleQuery, num, tbs, location, gl, hl }, props.bearerToken); return { content: formatSingleSearchResultToContentItems(searchResult), }; } // Handle multiple queries with parallel search if (Array.isArray(query) && query.length > 1) { const searches = query.map(q => ({ query: q, num, tbs, location, gl, hl })); const uniqueSearches = searches.filter((search, index, self) => index === self.findIndex(s => s.query === search.query) ); const webSearchFunction = async (searchArgs: SearchWebArgs) => { return executeWebSearch(searchArgs, props.bearerToken); }; const results = await executeParallelSearches(uniqueSearches, webSearchFunction, { timeout: 30000 }); return { content: formatParallelSearchResultsToContentItems(results), }; } return createErrorResponse("Invalid query format"); } catch (error) { return createErrorResponse(`Error: ${error instanceof Error ? error.message : String(error)}`); } },
  • Registration of the search_web tool via server.tool call, including description, input schema, and handler reference.
    server.tool( "search_web", "Search the entire web for current information, news, articles, and websites. Use this when you need up-to-date information, want to find specific websites, research topics, or get the latest news. Ideal for answering questions about recent events, finding resources, or discovering relevant content.", { query: z.union([z.string(), z.array(z.string())]).describe("Search terms or keywords to find relevant web content (e.g., 'climate change news 2024', 'best pizza recipe'). Can be a single query string or an array of queries for parallel search."), 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, can be qdr:h, qdr:d, qdr:w, qdr:m, qdr:y"), 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") }, async ({ query, num, tbs, location, gl, hl }: { query: string | string[]; num: number; tbs?: string; location?: string; gl?: string; hl?: string }) => { try { const props = getProps(); const tokenError = checkBearerToken(props.bearerToken); if (tokenError) { return tokenError; } // Handle single query or single-element array if (typeof query === 'string' || (Array.isArray(query) && query.length === 1)) { const singleQuery = typeof query === 'string' ? query : query[0]; const searchResult = await executeWebSearch({ query: singleQuery, num, tbs, location, gl, hl }, props.bearerToken); return { content: formatSingleSearchResultToContentItems(searchResult), }; } // Handle multiple queries with parallel search if (Array.isArray(query) && query.length > 1) { const searches = query.map(q => ({ query: q, num, tbs, location, gl, hl })); const uniqueSearches = searches.filter((search, index, self) => index === self.findIndex(s => s.query === search.query) ); const webSearchFunction = async (searchArgs: SearchWebArgs) => { return executeWebSearch(searchArgs, props.bearerToken); }; const results = await executeParallelSearches(uniqueSearches, webSearchFunction, { timeout: 30000 }); return { content: formatParallelSearchResultsToContentItems(results), }; } return createErrorResponse("Invalid query format"); } catch (error) { return createErrorResponse(`Error: ${error instanceof Error ? error.message : String(error)}`); } }, );
  • Zod input schema defining parameters for search_web: query (string or array), num, tbs, location, gl, hl.
    { query: z.union([z.string(), z.array(z.string())]).describe("Search terms or keywords to find relevant web content (e.g., 'climate change news 2024', 'best pizza recipe'). Can be a single query string or an array of queries for parallel search."), 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, can be qdr:h, qdr:d, qdr:w, qdr:m, qdr:y"), 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") },
  • Helper function executeWebSearch that performs the actual HTTP request to Jina's search API (svip.jina.ai) with the given parameters.
    export async function executeWebSearch( searchArgs: SearchWebArgs, 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, num: searchArgs.num || 30, ...(searchArgs.tbs && { tbs: searchArgs.tbs }), ...(searchArgs.location && { location: searchArgs.location }), ...(searchArgs.gl && { gl: searchArgs.gl }), ...(searchArgs.hl && { hl: searchArgs.hl }) }), }); if (!response.ok) { return { error: `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: `Search failed for query "${searchArgs.query}": ${error instanceof Error ? error.message : String(error)}` }; } }
  • TypeScript interface defining the SearchWebArgs type used in the handler and helpers.
    export interface SearchWebArgs { query: string; num?: number; tbs?: string; location?: string; gl?: string; hl?: string; }

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/jina-ai/MCP'

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