search-docs
Search PDFDancer SDK documentation to find API references, feature details, and usage examples by keyword.
Instructions
Search the official PDFDancer SDK documentation by keyword. Returns matching documentation routes with titles, content snippets, and relevance scores. Use this to find information about PDFDancer features, APIs, and usage examples.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | ||
| maxResults | No |
Implementation Reference
- src/index.ts:245-262 (handler)The handler function for the 'search-docs' tool. It takes query and optional maxResults, calls the /search API endpoint, summarizes the search response, formats it with JSON block, and returns structured content.async ({query, maxResults}) => { const data = await callApi<SearchResponse>('/search', { searchParams: { q: query, maxResults } }); return { content: [ { type: 'text' as const, text: `${summarizeSearchResponse(data)}\n\n${formatJsonBlock('Raw search response', data)}` } ], structuredContent: data }; }
- src/index.ts:237-244 (schema)Input schema and metadata (title, description) for the 'search-docs' tool, defining required 'query' string and optional 'maxResults' number (1-10).{ title: 'Search PDFDancer documentation', description: 'Search the official PDFDancer SDK documentation by keyword. Returns matching documentation routes with titles, content snippets, and relevance scores. Use this to find information about PDFDancer features, APIs, and usage examples.', inputSchema: { query: z.string().min(1, 'query is required'), maxResults: z.number().int().min(1).max(10).optional() } },
- src/index.ts:235-263 (registration)Registration of the 'search-docs' tool with the McpServer, including schema and inline handler function.server.registerTool( 'search-docs', { title: 'Search PDFDancer documentation', description: 'Search the official PDFDancer SDK documentation by keyword. Returns matching documentation routes with titles, content snippets, and relevance scores. Use this to find information about PDFDancer features, APIs, and usage examples.', inputSchema: { query: z.string().min(1, 'query is required'), maxResults: z.number().int().min(1).max(10).optional() } }, async ({query, maxResults}) => { const data = await callApi<SearchResponse>('/search', { searchParams: { q: query, maxResults } }); return { content: [ { type: 'text' as const, text: `${summarizeSearchResponse(data)}\n\n${formatJsonBlock('Raw search response', data)}` } ], structuredContent: data }; } );
- src/index.ts:67-110 (helper)Helper function 'callApi' used by the handler to make HTTP requests to the documentation search API.async function callApi<T>(path: string, options: ApiRequestOptions = {}): Promise<T> { const url = new URL(path, apiBase); if (options.searchParams) { Object.entries(options.searchParams).forEach(([key, value]) => { if (value !== undefined && value !== null && value !== '') { url.searchParams.set(key, String(value)); } }); } const method = options.method ?? 'GET'; const init: RequestInit = { method, headers: { Accept: 'application/json', ...(options.body ? {'Content-Type': 'application/json'} : {}) } }; if (options.body && method === 'POST') { init.body = JSON.stringify(options.body); } const response = await fetch(url, init); const text = await response.text(); if (!response.ok) { throw new Error( `Request to ${url.toString()} failed with status ${response.status}: ${ text || response.statusText }` ); } if (!text) { return undefined as T; } try { return JSON.parse(text) as T; } catch (error) { throw new Error(`Failed to parse JSON response from ${url.toString()}: ${error}`); } }
- src/index.ts:116-129 (helper)Helper function to summarize search results for user-friendly text output in the tool response.function summarizeSearchResponse(data: SearchResponse): string { if (!data.results?.length) { return `No matches for "${data.query}".`; } const lines = data.results.slice(0, 5).map((result, index) => { const title = result.pageTitle ?? result.sectionTitle ?? result.sectionRoute; const score = typeof result.score === 'number' ? `score=${result.score.toFixed(3)}` : ''; return `${index + 1}. ${title} → ${result.sectionRoute} ${score}`.trim(); }); const summary = `${data.total} result(s) for "${data.query}" (showing ${lines.length}, ${data.took}ms).`; return `${summary}\n${lines.join('\n')}`; }