Skip to main content
Glama

Web Search MCP Server

by williamvd4

search

Perform web searches via Google without needing an API key, retrieving structured results including titles, URLs, and descriptions. Specify queries and set result limits up to 10.

Instructions

Search the web using Google (no API key required)

Input Schema

NameRequiredDescriptionDefault
limitNoMaximum number of results to return (default: 5)
queryYesSearch query

Input Schema (JSON Schema)

{ "properties": { "limit": { "description": "Maximum number of results to return (default: 5)", "maximum": 10, "minimum": 1, "type": "number" }, "query": { "description": "Search query", "type": "string" } }, "required": [ "query" ], "type": "object" }

Implementation Reference

  • Core execution logic of the 'search' tool: performs web scraping of Google search results using axios for HTTP request and cheerio for HTML parsing to extract titles, URLs, and descriptions.
    private async performSearch(query: string, limit: number): Promise<SearchResult[]> { const response = await axios.get('https://www.google.com/search', { params: { q: query }, headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' } }); const $ = cheerio.load(response.data); const results: SearchResult[] = []; $('div.g').each((i, element) => { if (i >= limit) return false; const titleElement = $(element).find('h3'); const linkElement = $(element).find('a'); const snippetElement = $(element).find('.VwiC3b'); if (titleElement.length && linkElement.length) { const url = linkElement.attr('href'); if (url && url.startsWith('http')) { results.push({ title: titleElement.text(), url: url, description: snippetElement.text() || '', }); } } }); return results; }
  • src/index.ts:51-74 (registration)
    Registers the 'search' tool with the MCP server via the listTools handler, including name, description, and input schema.
    this.server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [ { name: 'search', description: 'Search the web using Google (no API key required)', inputSchema: { type: 'object', properties: { query: { type: 'string', description: 'Search query', }, limit: { type: 'number', description: 'Maximum number of results to return (default: 5)', minimum: 1, maximum: 10, }, }, required: ['query'], }, }, ], }));
  • MCP callTool request handler specifically for the 'search' tool: validates tool name and arguments, invokes performSearch, and formats the response as MCP content or error.
    this.server.setRequestHandler(CallToolRequestSchema, async (request) => { if (request.params.name !== 'search') { throw new McpError( ErrorCode.MethodNotFound, `Unknown tool: ${request.params.name}` ); } if (!isValidSearchArgs(request.params.arguments)) { throw new McpError( ErrorCode.InvalidParams, 'Invalid search arguments' ); } const query = request.params.arguments.query; const limit = Math.min(request.params.arguments.limit || 5, 10); try { const results = await this.performSearch(query, limit); return { content: [ { type: 'text', text: JSON.stringify(results, null, 2), }, ], }; } catch (error) { if (axios.isAxiosError(error)) { return { content: [ { type: 'text', text: `Search error: ${error.message}`, }, ], isError: true, }; } throw error; } });
  • Type guard for validating the input arguments of the 'search' tool against the expected schema.
    const isValidSearchArgs = (args: any): args is { query: string; limit?: number } => typeof args === 'object' && args !== null && typeof args.query === 'string' && (args.limit === undefined || typeof args.limit === 'number');
  • TypeScript interface defining the output format of search results from the tool.
    interface SearchResult { title: string; url: string; description: string; }

Other Tools

Related 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/williamvd4/web-search'

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