Skip to main content
Glama
spences10

MCP JinaAI Search Server

search

Search the web to retrieve clean, LLM-friendly content using Jina.ai Reader, returning top results with URLs and processed text for efficient information extraction.

Instructions

Search the web and get clean, LLM-friendly content using Jina.ai Reader. Returns top 5 results with URLs and clean content.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYesSearch query
formatNoResponse format (json or text)text
no_cacheNoBypass cache for fresh results
token_budgetNoMaximum number of tokens for this request
browser_localeNoBrowser locale for rendering content
streamNoEnable stream mode for large pages
gather_linksNoGather all links at the end of the response
gather_imagesNoGather all images at the end of the response
image_captionNoCaption images in the content
enable_iframeNoExtract content from iframes
enable_shadow_domNoExtract content from shadow DOM
resolve_redirectsNoFollow redirect chains to final URL

Implementation Reference

  • Handler for CallToolRequestSchema that checks if the tool is 'search' and executes the Jina.ai search API call with parameters, handling response and errors.
    this.server.setRequestHandler(
    	CallToolRequestSchema,
    	async (request) => {
    		if (request.params.name !== 'search') {
    			throw new McpError(
    				ErrorCode.MethodNotFound,
    				`Unknown tool: ${request.params.name}`,
    			);
    		}
    
    		const arguments_record = request.params.arguments as {
    			query: string;
    			format?: 'json' | 'text';
    			no_cache?: boolean;
    			token_budget?: number;
    			browser_locale?: string;
    			stream?: boolean;
    			gather_links?: boolean;
    			gather_images?: boolean;
    			image_caption?: boolean;
    			enable_iframe?: boolean;
    			enable_shadow_dom?: boolean;
    			resolve_redirects?: boolean;
    		};
    		const {
    			query,
    			format = 'text',
    			no_cache = false,
    			token_budget,
    			browser_locale,
    			stream = false,
    			gather_links = false,
    			gather_images = false,
    			image_caption = false,
    			enable_iframe = false,
    			enable_shadow_dom = false,
    			resolve_redirects = true,
    		} = arguments_record;
    		const search_url = `https://s.jina.ai/${encodeURIComponent(
    			query,
    		)}`;
    
    		const headers: Record<string, string> = {
    			Authorization: `Bearer ${API_KEY}`,
    			Accept:
    				format === 'json' ? 'application/json' : 'text/plain',
    		};
    
    		if (no_cache) {
    			headers['X-Bypass-Cache'] = 'true';
    		}
    		if (token_budget) {
    			headers['X-Token-Budget'] = token_budget.toString();
    		}
    		if (browser_locale) {
    			headers['X-Browser-Locale'] = browser_locale;
    		}
    		if (stream) {
    			headers['X-Stream-Mode'] = 'true';
    		}
    		if (gather_links) {
    			headers['X-Gather-Links'] = 'true';
    		}
    		if (gather_images) {
    			headers['X-Gather-Images'] = 'true';
    		}
    		if (image_caption) {
    			headers['X-Image-Caption'] = 'true';
    		}
    		if (enable_iframe) {
    			headers['X-Enable-Iframe'] = 'true';
    		}
    		if (enable_shadow_dom) {
    			headers['X-Enable-Shadow-DOM'] = 'true';
    		}
    		if (!resolve_redirects) {
    			headers['X-No-Redirect'] = 'true';
    		}
    
    		try {
    			const response = await fetch(search_url, {
    				method: 'POST',
    				headers,
    			});
    
    			if (!response.ok) {
    				const error_text = await response.text();
    				throw new Error(error_text);
    			}
    
    			const result =
    				format === 'json'
    					? await response.json()
    					: await response.text();
    
    			return {
    				content: [
    					{
    						type: 'text',
    						text:
    							format === 'json'
    								? JSON.stringify(result, null, 2)
    								: result,
    					},
    				],
    			};
    		} catch (error) {
    			return {
    				content: [
    					{
    						type: 'text',
    						text: `Jina.ai API error: ${
    							error instanceof Error
    								? error.message
    								: String(error)
    						}`,
    					},
    				],
    				isError: true,
    			};
    		}
    	},
    );
  • Schema definition for the 'search' tool, specifying name, description, and detailed input schema with parameters such as query (required), format, token_budget, etc.
    const search_tool_schema = {
    	name: 'search',
    	description:
    		'Search the web and get clean, LLM-friendly content using Jina.ai Reader. Returns top 5 results with URLs and clean content.',
    	inputSchema: {
    		type: 'object',
    		properties: {
    			query: {
    				type: 'string',
    				description: 'Search query',
    			},
    			format: {
    				type: 'string',
    				description: 'Response format (json or text)',
    				enum: ['json', 'text'],
    				default: 'text',
    			},
    			no_cache: {
    				type: 'boolean',
    				description: 'Bypass cache for fresh results',
    				default: false,
    			},
    			token_budget: {
    				type: 'number',
    				description: 'Maximum number of tokens for this request',
    				minimum: 1,
    			},
    			browser_locale: {
    				type: 'string',
    				description: 'Browser locale for rendering content',
    			},
    			stream: {
    				type: 'boolean',
    				description: 'Enable stream mode for large pages',
    				default: false,
    			},
    			gather_links: {
    				type: 'boolean',
    				description: 'Gather all links at the end of the response',
    				default: false,
    			},
    			gather_images: {
    				type: 'boolean',
    				description: 'Gather all images at the end of the response',
    				default: false,
    			},
    			image_caption: {
    				type: 'boolean',
    				description: 'Caption images in the content',
    				default: false,
    			},
    			enable_iframe: {
    				type: 'boolean',
    				description: 'Extract content from iframes',
    				default: false,
    			},
    			enable_shadow_dom: {
    				type: 'boolean',
    				description: 'Extract content from shadow DOM',
    				default: false,
    			},
    			resolve_redirects: {
    				type: 'boolean',
    				description: 'Follow redirect chains to final URL',
    				default: true,
    			},
    		},
    		required: ['query'],
    	},
    };
  • src/index.ts:120-125 (registration)
    Registration of the 'search' tool by returning it in the ListToolsRequest handler.
    this.server.setRequestHandler(
    	ListToolsRequestSchema,
    	async () => ({
    		tools: [search_tool_schema],
    	}),
    );
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/spences10/mcp-jinaai-search'

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