search_image
Search for images online using Google Images to find visual content based on your query, with options to control result count and safe search settings.
Instructions
Search the image(s) online
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| count | No | Number of results to return (1-10, default: 2) | |
| query | Yes | Search query for images | |
| safe | No | Safe search setting (default: off) | |
| startIndex | No | Starting index of next search result page (not needed for initial search request) |
Implementation Reference
- src/tools/search_image/index.ts:17-87 (handler)The main tool handler function for 'search_image' that processes inputs, calls searchImages from utils, handles errors using tryCatch, formats metadata and content for MCP response.export const handler: ToolCallback<typeof schema> = async ({ count = 2, query, safe = 'off', startIndex }) => { logger().info('handler called', { count, query, safe, startIndex }); const [err, res] = await tryCatch<GoogleSearchError, SearchResult>(searchImages({ count, query, safe, startIndex })); if (err != null) { return { _meta: { error: { type: 'GoogleSearchError', message: err.message, status: err.status, statusText: err.statusText, }, }, content: [ { type: 'text' as const, text: `Error: ${err.message}`, }, ], }; } const _meta = { itemsCount: res.items.length, nextPageIdx: res.nextPageIdx, previousPageIdx: res.previousPageIdx, searchTerms: res.searchTerms, }; const result = { summary: { query: res.searchTerms, itemsReturned: res.items.length, pagination: { previousPageStartIndex: res.previousPageIdx, nextPageStartIndex: res.nextPageIdx, }, }, items: res.items.map((item, index) => ({ index: index + (startIndex || 1), title: item.title, link: item.link, displayLink: item.displayLink, mimeType: item.mime, image: { contextLink: item.image.contextLink, dimensions: `${item.image.width}x${item.image.height}`, size: `${Math.round(item.image.byteSize / 1024)}KB`, thumbnail: { link: item.image.thumbnailLink, dimensions: `${item.image.thumbnailWidth}x${item.image.thumbnailHeight}`, }, }, })), }; logger().info('handler success', { _meta, result }); return { _meta, content: [ { type: 'text' as const, text: `Search successfully returned ${count} images. StartIndex of the next search page is: ${result.summary.pagination.nextPageStartIndex}`, }, ...result.items.map((i) => ({ type: 'text' as const, text: `${i.index}: ${i.link}`, })), ], }; };
- src/tools/search_image/index.ts:8-13 (schema)Zod-based input schema defining parameters for the search_image tool: count, query, safe, startIndex.export const schema = { count: z.number().min(1).max(10).optional().describe('Number of results to return (1-10, default: 2)'), query: z.string().describe('Search query for images'), safe: z.enum(['off', 'medium', 'high']).optional().describe('Safe search setting (default: off)'), startIndex: z.number().min(1).optional().describe('Starting index of next search result page (not needed for initial search request)'), } as const;
- src/index.ts:20-20 (registration)Registers the 'search_image' tool on the MCP server, providing name, description, schema, and handler.server.tool('search_image', 'Search the image(s) online', searchImageSchema, searchImageHandler);
- Core helper function implementing Google Custom Search API call for images, including URL construction (via buildSearchUrl), fetch, error handling, Zod validation of response, and pagination extraction.export async function searchImages({ count = 2, query, safe = 'off', startIndex }: SearchOptions): Promise<SearchResult> { const url = buildSearchUrl({ query, count, safe, startIndex }); logger().info('searchImages() called', { count, query, safe, startIndex, url }); const response = await fetch(url); if (!response.ok) { throw new GoogleSearchError(`Google Search API request failed: ${response.statusText}`, response.status, response.statusText); } const data = await response.json(); logger().info('searchImages() response data', { data }); const [validationErr, validatedData] = tryCatch(() => googleSearchResponseSchema.parse(data)); if (validationErr != null) { throw new GoogleSearchError(`Invalid response format from Google Search API: ${validationErr.message}`); } // extract pagination information const requestQuery = validatedData.queries.request[0]; const previousPageIdx = validatedData.queries.previousPage?.[0]?.startIndex; const nextPageIdx = validatedData.queries.nextPage?.[0]?.startIndex; return { items: validatedData.items || [], previousPageIdx, nextPageIdx, searchTerms: requestQuery.searchTerms, }; }