Skip to main content
Glama

web_search

Search the web using multiple providers for factual, privacy-focused, or AI-enhanced results with query operators and domain filtering.

Instructions

Search the web. Providers: tavily (factual/citations), brave (privacy/operators), kagi (quality/operators), exa (AI-semantic). Brave/Kagi support query operators like site:, filetype:, lang:, etc.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYesQuery
providerYesSearch provider
limitNoResult limit
include_domainsNoDomains to include
exclude_domainsNoDomains to exclude

Implementation Reference

  • MCP tool registration including schema, description, and handler function for 'web_search'. The handler delegates to the registered web_search_provider's search method, handles large results, and formats the response as JSON text or error.
    if (this.web_search_provider) {
    	server.tool(
    		{
    			name: 'web_search',
    			description: this.web_search_provider.description,
    			schema: v.object({
    				query: v.pipe(v.string(), v.description('Query')),
    				provider: v.pipe(
    					v.union([
    						v.literal('tavily'),
    						v.literal('brave'),
    						v.literal('kagi'),
    						v.literal('exa'),
    					]),
    					v.description('Search provider'),
    				),
    				limit: v.optional(
    					v.pipe(v.number(), v.description('Result limit')),
    				),
    				include_domains: v.optional(
    					v.pipe(
    						v.array(v.string()),
    						v.description('Domains to include'),
    					),
    				),
    				exclude_domains: v.optional(
    					v.pipe(
    						v.array(v.string()),
    						v.description('Domains to exclude'),
    					),
    				),
    			}),
    		},
    		async ({
    			query,
    			provider,
    			limit,
    			include_domains,
    			exclude_domains,
    		}) => {
    			try {
    				const results = await this.web_search_provider!.search({
    					query,
    					provider,
    					limit,
    					include_domains,
    					exclude_domains,
    				} as any);
    				const safe_results = handle_large_result(
    					results,
    					'web_search',
    				);
    				return {
    					content: [
    						{
    							type: 'text' as const,
    							text: JSON.stringify(safe_results, null, 2),
    						},
    					],
    				};
    			} catch (error) {
    				const error_response = create_error_response(
    					error as Error,
    				);
    				return {
    					content: [
    						{
    							type: 'text' as const,
    							text: error_response.error,
    						},
    					],
    					isError: true,
    				};
    			}
    		},
    	);
    }
  • Valibot input schema for the web_search tool defining parameters: query (required), provider (tavily|brave|kagi|exa), optional limit, include_domains, exclude_domains.
    schema: v.object({
    	query: v.pipe(v.string(), v.description('Query')),
    	provider: v.pipe(
    		v.union([
    			v.literal('tavily'),
    			v.literal('brave'),
    			v.literal('kagi'),
    			v.literal('exa'),
    		]),
    		v.description('Search provider'),
    	),
    	limit: v.optional(
    		v.pipe(v.number(), v.description('Result limit')),
    	),
    	include_domains: v.optional(
    		v.pipe(
    			v.array(v.string()),
    			v.description('Domains to include'),
    		),
    	),
    	exclude_domains: v.optional(
    		v.pipe(
    			v.array(v.string()),
    			v.description('Domains to exclude'),
    		),
    	),
    }),
  • Conditional registration of the UnifiedWebSearchProvider instance to the tool registry if any web search API key is valid.
    if (has_web_search) {
    	register_web_search_provider(new UnifiedWebSearchProvider());
    }
  • UnifiedWebSearchProvider class implementing SearchProvider. Instantiates sub-providers (Tavily, Brave, Kagi, Exa) and delegates search calls to the selected provider based on input.
    export class UnifiedWebSearchProvider implements SearchProvider {
    	name = 'web_search';
    	description =
    		'Search the web. Providers: tavily (factual/citations), brave (privacy/operators), kagi (quality/operators), exa (AI-semantic). Brave/Kagi support query operators like site:, filetype:, lang:, etc.';
    
    	private providers: Map<WebSearchProvider, SearchProvider> =
    		new Map();
    
    	constructor() {
    		this.providers.set('tavily', new TavilySearchProvider());
    		this.providers.set('brave', new BraveSearchProvider());
    		this.providers.set('kagi', new KagiSearchProvider());
    		this.providers.set('exa', new ExaSearchProvider());
    	}
    
    	async search(
    		params: UnifiedWebSearchParams,
    	): Promise<SearchResult[]> {
    		const { provider, ...searchParams } = params;
    
    		if (!provider) {
    			throw new ProviderError(
    				ErrorType.INVALID_INPUT,
    				'Provider parameter is required',
    				this.name,
    			);
    		}
    
    		const selectedProvider = this.providers.get(provider);
    
    		if (!selectedProvider) {
    			throw new ProviderError(
    				ErrorType.INVALID_INPUT,
    				`Invalid provider: ${provider}. Valid options: ${Array.from(this.providers.keys()).join(', ')}`,
    				this.name,
    			);
    		}
    
    		return selectedProvider.search(searchParams);
    	}
    }
  • Function to register a SearchProvider instance (e.g., UnifiedWebSearchProvider) with the ToolRegistry for use in the web_search tool.
    export const register_web_search_provider = (
    	provider: SearchProvider,
    ) => {
    	registry.register_web_search_provider(provider);
    };

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-omnisearch'

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