| 19 | } |
| 20 | |
| 21 | export function createCodeSearchTool() { |
| 22 | return tool({ |
| 23 | description: |
| 24 | 'Search the web for code examples, API documentation, and SDK references. ' + |
| 25 | 'Use this when you need to look up how to use a library, find code patterns, ' + |
| 26 | 'or check API usage. Returns code-focused results from documentation and repositories.', |
| 27 | inputSchema: z.object({ |
| 28 | query: z.string().describe('Search query for code examples or documentation (e.g. "Next.js App Router middleware example", "zod union type validation")'), |
| 29 | tokensNum: z.number().optional().default(5000) |
| 30 | .describe('Response length control: 1000-50000 tokens (default: 5000). Use higher values for detailed API docs.'), |
| 31 | }), |
| 32 | execute: async ({ query, tokensNum }) => { |
| 33 | const controller = new AbortController(); |
| 34 | const timeoutId = setTimeout(() => controller.abort(), API_CONFIG.TIMEOUT_MS); |
| 35 | |
| 36 | try { |
| 37 | const response = await fetch(`${API_CONFIG.BASE_URL}${API_CONFIG.ENDPOINT}`, { |
| 38 | method: 'POST', |
| 39 | headers: { |
| 40 | 'accept': 'application/json, text/event-stream', |
| 41 | 'content-type': 'application/json', |
| 42 | }, |
| 43 | body: JSON.stringify({ |
| 44 | jsonrpc: '2.0', |
| 45 | id: 1, |
| 46 | method: 'tools/call', |
| 47 | params: { |
| 48 | name: 'codedocs', |
| 49 | arguments: { |
| 50 | query, |
| 51 | tokensNum: Math.min(Math.max(tokensNum || API_CONFIG.DEFAULT_TOKENS, 1000), 50000), |
| 52 | }, |
| 53 | }, |
| 54 | }), |
| 55 | signal: controller.signal, |
| 56 | }); |
| 57 | |
| 58 | clearTimeout(timeoutId); |
| 59 | |
| 60 | if (!response.ok) { |
| 61 | const errorText = await response.text(); |
| 62 | return `Search error (${response.status}): ${errorText}`; |
| 63 | } |
| 64 | |
| 65 | const responseText = await response.text(); |
| 66 | |
| 67 | // Parse SSE response |
| 68 | const lines = responseText.split('\n'); |
| 69 | for (const line of lines) { |
| 70 | if (line.startsWith('data: ')) { |
| 71 | const data: McpResponse = JSON.parse(line.substring(6)); |
| 72 | if (data.result?.content?.length > 0) { |
| 73 | return data.result.content[0].text; |
| 74 | } |
| 75 | } |
| 76 | } |
| 77 | |
| 78 | return 'No code examples found. Try a more specific query.'; |