recker 1.0.20-next.b961eae → 1.0.20-next.e194d90

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (425) hide show
  1. package/README.md +31 -0
  2. package/dist/ai/adaptive-timeout.d.ts +0 -1
  3. package/dist/ai/client.d.ts +0 -1
  4. package/dist/ai/client.js +6 -0
  5. package/dist/ai/index.d.ts +3 -1
  6. package/dist/ai/index.js +3 -0
  7. package/dist/ai/providers/anthropic.d.ts +0 -1
  8. package/dist/ai/providers/base.d.ts +0 -1
  9. package/dist/ai/providers/google.d.ts +59 -0
  10. package/dist/ai/providers/google.js +305 -0
  11. package/dist/ai/providers/index.d.ts +4 -1
  12. package/dist/ai/providers/index.js +2 -0
  13. package/dist/ai/providers/ollama.d.ts +44 -0
  14. package/dist/ai/providers/ollama.js +240 -0
  15. package/dist/ai/providers/openai.d.ts +0 -1
  16. package/dist/ai/rate-limiter.d.ts +0 -1
  17. package/dist/ai/vector/index.d.ts +2 -0
  18. package/dist/ai/vector/index.js +2 -0
  19. package/dist/ai/vector/similarity.d.ts +2 -0
  20. package/dist/ai/vector/similarity.js +27 -0
  21. package/dist/ai/vector/store.d.ts +27 -0
  22. package/dist/ai/vector/store.js +82 -0
  23. package/dist/bench/generator.d.ts +0 -1
  24. package/dist/bench/stats.d.ts +0 -1
  25. package/dist/cache/basic-file-storage.d.ts +12 -0
  26. package/dist/cache/basic-file-storage.js +50 -0
  27. package/dist/cache/file-storage.d.ts +25 -11
  28. package/dist/cache/file-storage.js +175 -30
  29. package/dist/cache/memory-limits.d.ts +0 -1
  30. package/dist/cache/memory-storage.d.ts +0 -1
  31. package/dist/cache/redis-storage.d.ts +0 -1
  32. package/dist/cli/handler.d.ts +2 -1
  33. package/dist/cli/handler.js +36 -5
  34. package/dist/cli/index.d.ts +0 -1
  35. package/dist/cli/index.js +559 -5
  36. package/dist/cli/presets.d.ts +0 -1
  37. package/dist/cli/tui/ai-chat.d.ts +0 -1
  38. package/dist/cli/tui/load-dashboard.d.ts +0 -1
  39. package/dist/cli/tui/scroll-buffer.d.ts +0 -1
  40. package/dist/cli/tui/search-panel.d.ts +0 -1
  41. package/dist/cli/tui/shell-search.d.ts +0 -1
  42. package/dist/cli/tui/shell.d.ts +0 -1
  43. package/dist/cli/tui/websocket.d.ts +0 -1
  44. package/dist/constants/http-status.d.ts +0 -1
  45. package/dist/constants.d.ts +0 -1
  46. package/dist/contract/index.d.ts +0 -1
  47. package/dist/cookies/memory-cookie-jar.d.ts +0 -1
  48. package/dist/core/client.d.ts +0 -1
  49. package/dist/core/client.js +1 -1
  50. package/dist/core/errors.d.ts +0 -1
  51. package/dist/core/index.d.ts +0 -1
  52. package/dist/core/request-promise.d.ts +0 -1
  53. package/dist/core/request.d.ts +0 -1
  54. package/dist/core/response.d.ts +0 -1
  55. package/dist/dns/index.d.ts +0 -1
  56. package/dist/dns/propagation.d.ts +0 -1
  57. package/dist/events/request-events.d.ts +0 -1
  58. package/dist/index.d.ts +1 -1
  59. package/dist/index.js +1 -0
  60. package/dist/mcp/client.d.ts +0 -1
  61. package/dist/mcp/contract.d.ts +0 -1
  62. package/dist/mcp/embeddings-loader.d.ts +0 -1
  63. package/dist/mcp/geoip-loader.d.ts +0 -1
  64. package/dist/mcp/index.d.ts +0 -1
  65. package/dist/mcp/ip-intel.d.ts +0 -1
  66. package/dist/mcp/search/hybrid-search.d.ts +0 -1
  67. package/dist/mcp/search/index.d.ts +0 -1
  68. package/dist/mcp/search/math.d.ts +0 -1
  69. package/dist/mcp/search/types.d.ts +0 -1
  70. package/dist/mcp/server.d.ts +6 -2
  71. package/dist/mcp/server.js +193 -151
  72. package/dist/mcp/tools/loader.d.ts +2 -0
  73. package/dist/mcp/tools/loader.js +41 -0
  74. package/dist/mcp/tools/network.d.ts +3 -0
  75. package/dist/mcp/tools/network.js +267 -0
  76. package/dist/mcp/tools/registry.d.ts +17 -0
  77. package/dist/mcp/tools/registry.js +37 -0
  78. package/dist/mcp/types.d.ts +0 -1
  79. package/dist/plugins/auth/api-key.d.ts +8 -0
  80. package/dist/plugins/auth/api-key.js +27 -0
  81. package/dist/plugins/auth/auth0.d.ts +33 -0
  82. package/dist/plugins/auth/auth0.js +94 -0
  83. package/dist/plugins/auth/aws-sigv4.d.ts +10 -0
  84. package/dist/plugins/auth/aws-sigv4.js +88 -0
  85. package/dist/plugins/auth/azure-ad.d.ts +48 -0
  86. package/dist/plugins/auth/azure-ad.js +152 -0
  87. package/dist/plugins/auth/basic.d.ts +7 -0
  88. package/dist/plugins/auth/basic.js +13 -0
  89. package/dist/plugins/auth/bearer.d.ts +8 -0
  90. package/dist/plugins/auth/bearer.js +17 -0
  91. package/dist/plugins/auth/cognito.d.ts +45 -0
  92. package/dist/plugins/auth/cognito.js +208 -0
  93. package/dist/plugins/auth/digest.d.ts +8 -0
  94. package/dist/plugins/auth/digest.js +100 -0
  95. package/dist/plugins/auth/firebase.d.ts +32 -0
  96. package/dist/plugins/auth/firebase.js +195 -0
  97. package/dist/plugins/auth/github-app.d.ts +36 -0
  98. package/dist/plugins/auth/github-app.js +170 -0
  99. package/dist/plugins/auth/google-service-account.d.ts +49 -0
  100. package/dist/plugins/auth/google-service-account.js +172 -0
  101. package/dist/plugins/auth/index.d.ts +15 -0
  102. package/dist/plugins/auth/index.js +15 -0
  103. package/dist/plugins/auth/mtls.d.ts +37 -0
  104. package/dist/plugins/auth/mtls.js +140 -0
  105. package/dist/plugins/auth/oauth2.d.ts +8 -0
  106. package/dist/plugins/auth/oauth2.js +26 -0
  107. package/dist/plugins/auth/oidc.d.ts +55 -0
  108. package/dist/plugins/auth/oidc.js +222 -0
  109. package/dist/plugins/auth/okta.d.ts +47 -0
  110. package/dist/plugins/auth/okta.js +157 -0
  111. package/dist/plugins/auth.d.ts +1 -45
  112. package/dist/plugins/auth.js +1 -268
  113. package/dist/plugins/cache.d.ts +0 -1
  114. package/dist/plugins/certificate-pinning.d.ts +59 -0
  115. package/dist/plugins/certificate-pinning.js +236 -0
  116. package/dist/plugins/circuit-breaker.d.ts +0 -1
  117. package/dist/plugins/compression.d.ts +0 -1
  118. package/dist/plugins/cookie-jar.d.ts +0 -1
  119. package/dist/plugins/dedup.d.ts +0 -1
  120. package/dist/plugins/graphql.d.ts +0 -1
  121. package/dist/plugins/grpc-web.d.ts +0 -1
  122. package/dist/plugins/har-player.d.ts +0 -1
  123. package/dist/plugins/har-recorder.d.ts +0 -1
  124. package/dist/plugins/hls.d.ts +0 -1
  125. package/dist/plugins/http2-push.d.ts +0 -1
  126. package/dist/plugins/http3.d.ts +0 -1
  127. package/dist/plugins/index.d.ts +27 -0
  128. package/dist/plugins/index.js +27 -0
  129. package/dist/plugins/interface-rotator.d.ts +0 -1
  130. package/dist/plugins/jsonrpc.d.ts +0 -1
  131. package/dist/plugins/logger.d.ts +0 -1
  132. package/dist/plugins/odata.d.ts +0 -1
  133. package/dist/plugins/pagination.d.ts +0 -1
  134. package/dist/plugins/proxy-rotator.d.ts +0 -1
  135. package/dist/plugins/rate-limit.d.ts +15 -0
  136. package/dist/plugins/rate-limit.js +162 -0
  137. package/dist/plugins/retry.d.ts +0 -1
  138. package/dist/plugins/scrape.d.ts +0 -1
  139. package/dist/plugins/server-timing.d.ts +0 -1
  140. package/dist/plugins/soap.d.ts +0 -1
  141. package/dist/plugins/user-agent.d.ts +0 -1
  142. package/dist/plugins/xml.d.ts +0 -1
  143. package/dist/plugins/xsrf.d.ts +0 -1
  144. package/dist/presets/anthropic.d.ts +0 -1
  145. package/dist/presets/aws.d.ts +0 -1
  146. package/dist/presets/azure-openai.d.ts +0 -1
  147. package/dist/presets/azure.d.ts +0 -1
  148. package/dist/presets/cloudflare.d.ts +0 -1
  149. package/dist/presets/cohere.d.ts +0 -1
  150. package/dist/presets/deepseek.d.ts +0 -1
  151. package/dist/presets/digitalocean.d.ts +0 -1
  152. package/dist/presets/discord.d.ts +0 -1
  153. package/dist/presets/fireworks.d.ts +0 -1
  154. package/dist/presets/gcp.d.ts +0 -1
  155. package/dist/presets/gemini.d.ts +0 -1
  156. package/dist/presets/github.d.ts +0 -1
  157. package/dist/presets/gitlab.d.ts +0 -1
  158. package/dist/presets/groq.d.ts +0 -1
  159. package/dist/presets/huggingface.d.ts +0 -1
  160. package/dist/presets/index.d.ts +0 -1
  161. package/dist/presets/linear.d.ts +0 -1
  162. package/dist/presets/mailgun.d.ts +0 -1
  163. package/dist/presets/meta.d.ts +0 -1
  164. package/dist/presets/mistral.d.ts +0 -1
  165. package/dist/presets/notion.d.ts +0 -1
  166. package/dist/presets/openai.d.ts +0 -1
  167. package/dist/presets/oracle.d.ts +0 -1
  168. package/dist/presets/perplexity.d.ts +0 -1
  169. package/dist/presets/registry.d.ts +0 -1
  170. package/dist/presets/replicate.d.ts +0 -1
  171. package/dist/presets/sinch.d.ts +0 -1
  172. package/dist/presets/slack.d.ts +0 -1
  173. package/dist/presets/stripe.d.ts +0 -1
  174. package/dist/presets/supabase.d.ts +0 -1
  175. package/dist/presets/tiktok.d.ts +0 -1
  176. package/dist/presets/together.d.ts +0 -1
  177. package/dist/presets/twilio.d.ts +0 -1
  178. package/dist/presets/vercel.d.ts +0 -1
  179. package/dist/presets/vultr.d.ts +0 -1
  180. package/dist/presets/xai.d.ts +0 -1
  181. package/dist/presets/youtube.d.ts +0 -1
  182. package/dist/protocols/ftp.d.ts +0 -1
  183. package/dist/protocols/index.d.ts +0 -1
  184. package/dist/protocols/sftp.d.ts +0 -1
  185. package/dist/protocols/telnet.d.ts +0 -1
  186. package/dist/recker.d.ts +0 -1
  187. package/dist/runner/request-runner.d.ts +0 -1
  188. package/dist/scrape/document.d.ts +0 -1
  189. package/dist/scrape/element.d.ts +0 -1
  190. package/dist/scrape/extractors.d.ts +0 -1
  191. package/dist/scrape/index.d.ts +0 -1
  192. package/dist/scrape/types.d.ts +0 -1
  193. package/dist/testing/index.d.ts +8 -1
  194. package/dist/testing/index.js +4 -0
  195. package/dist/testing/mock-dns-server.d.ts +69 -0
  196. package/dist/testing/mock-dns-server.js +269 -0
  197. package/dist/testing/mock-ftp-server.d.ts +89 -0
  198. package/dist/testing/mock-ftp-server.js +562 -0
  199. package/dist/testing/mock-hls-server.d.ts +0 -1
  200. package/dist/testing/mock-http-server.d.ts +0 -1
  201. package/dist/testing/mock-sse-server.d.ts +0 -1
  202. package/dist/testing/mock-telnet-server.d.ts +59 -0
  203. package/dist/testing/mock-telnet-server.js +273 -0
  204. package/dist/testing/mock-udp-server.d.ts +0 -1
  205. package/dist/testing/mock-websocket-server.d.ts +0 -1
  206. package/dist/testing/mock-whois-server.d.ts +56 -0
  207. package/dist/testing/mock-whois-server.js +234 -0
  208. package/dist/testing/mock.d.ts +0 -1
  209. package/dist/transport/base-udp.d.ts +0 -1
  210. package/dist/transport/fetch.d.ts +0 -1
  211. package/dist/transport/udp-response.d.ts +0 -1
  212. package/dist/transport/udp.d.ts +0 -1
  213. package/dist/transport/undici.d.ts +0 -1
  214. package/dist/types/ai.d.ts +0 -1
  215. package/dist/types/index.d.ts +0 -1
  216. package/dist/types/logger.d.ts +0 -1
  217. package/dist/types/udp.d.ts +0 -1
  218. package/dist/udp/index.d.ts +0 -1
  219. package/dist/utils/agent-manager.d.ts +0 -1
  220. package/dist/utils/body.d.ts +0 -1
  221. package/dist/utils/cert.d.ts +0 -1
  222. package/dist/utils/charset.d.ts +0 -1
  223. package/dist/utils/chart.d.ts +0 -1
  224. package/dist/utils/client-pool.d.ts +0 -1
  225. package/dist/utils/colors.d.ts +0 -1
  226. package/dist/utils/concurrency.d.ts +0 -1
  227. package/dist/utils/dns-toolkit.d.ts +0 -1
  228. package/dist/utils/dns.d.ts +0 -1
  229. package/dist/utils/doh.d.ts +0 -1
  230. package/dist/utils/download.d.ts +0 -1
  231. package/dist/utils/env-proxy.d.ts +0 -1
  232. package/dist/utils/header-parser.d.ts +0 -1
  233. package/dist/utils/html-cleaner.d.ts +0 -1
  234. package/dist/utils/link-header.d.ts +0 -1
  235. package/dist/utils/optional-require.d.ts +0 -1
  236. package/dist/utils/progress.d.ts +0 -1
  237. package/dist/utils/rdap.d.ts +0 -1
  238. package/dist/utils/request-pool.d.ts +0 -1
  239. package/dist/utils/security-grader.d.ts +0 -1
  240. package/dist/utils/sparkline.d.ts +0 -1
  241. package/dist/utils/sse.d.ts +0 -1
  242. package/dist/utils/streaming.d.ts +0 -1
  243. package/dist/utils/system-metrics.d.ts +0 -1
  244. package/dist/utils/tls-inspector.d.ts +0 -1
  245. package/dist/utils/try-fn.d.ts +0 -1
  246. package/dist/utils/upload.d.ts +0 -1
  247. package/dist/utils/user-agent.d.ts +0 -1
  248. package/dist/utils/whois.d.ts +0 -1
  249. package/dist/webrtc/index.d.ts +0 -1
  250. package/dist/websocket/client.d.ts +0 -1
  251. package/package.json +10 -3
  252. package/dist/ai/adaptive-timeout.d.ts.map +0 -1
  253. package/dist/ai/client.d.ts.map +0 -1
  254. package/dist/ai/index.d.ts.map +0 -1
  255. package/dist/ai/providers/anthropic.d.ts.map +0 -1
  256. package/dist/ai/providers/base.d.ts.map +0 -1
  257. package/dist/ai/providers/index.d.ts.map +0 -1
  258. package/dist/ai/providers/openai.d.ts.map +0 -1
  259. package/dist/ai/rate-limiter.d.ts.map +0 -1
  260. package/dist/bench/generator.d.ts.map +0 -1
  261. package/dist/bench/stats.d.ts.map +0 -1
  262. package/dist/cache/file-storage.d.ts.map +0 -1
  263. package/dist/cache/memory-limits.d.ts.map +0 -1
  264. package/dist/cache/memory-storage.d.ts.map +0 -1
  265. package/dist/cache/redis-storage.d.ts.map +0 -1
  266. package/dist/cli/handler.d.ts.map +0 -1
  267. package/dist/cli/index.d.ts.map +0 -1
  268. package/dist/cli/presets.d.ts.map +0 -1
  269. package/dist/cli/tui/ai-chat.d.ts.map +0 -1
  270. package/dist/cli/tui/load-dashboard.d.ts.map +0 -1
  271. package/dist/cli/tui/scroll-buffer.d.ts.map +0 -1
  272. package/dist/cli/tui/search-panel.d.ts.map +0 -1
  273. package/dist/cli/tui/shell-search.d.ts.map +0 -1
  274. package/dist/cli/tui/shell.d.ts.map +0 -1
  275. package/dist/cli/tui/websocket.d.ts.map +0 -1
  276. package/dist/constants/http-status.d.ts.map +0 -1
  277. package/dist/constants.d.ts.map +0 -1
  278. package/dist/contract/index.d.ts.map +0 -1
  279. package/dist/cookies/memory-cookie-jar.d.ts.map +0 -1
  280. package/dist/core/client.d.ts.map +0 -1
  281. package/dist/core/errors.d.ts.map +0 -1
  282. package/dist/core/index.d.ts.map +0 -1
  283. package/dist/core/request-promise.d.ts.map +0 -1
  284. package/dist/core/request.d.ts.map +0 -1
  285. package/dist/core/response.d.ts.map +0 -1
  286. package/dist/dns/index.d.ts.map +0 -1
  287. package/dist/dns/propagation.d.ts.map +0 -1
  288. package/dist/events/request-events.d.ts.map +0 -1
  289. package/dist/index.d.ts.map +0 -1
  290. package/dist/mcp/client.d.ts.map +0 -1
  291. package/dist/mcp/contract.d.ts.map +0 -1
  292. package/dist/mcp/embeddings-loader.d.ts.map +0 -1
  293. package/dist/mcp/geoip-loader.d.ts.map +0 -1
  294. package/dist/mcp/index.d.ts.map +0 -1
  295. package/dist/mcp/ip-intel.d.ts.map +0 -1
  296. package/dist/mcp/search/hybrid-search.d.ts.map +0 -1
  297. package/dist/mcp/search/index.d.ts.map +0 -1
  298. package/dist/mcp/search/math.d.ts.map +0 -1
  299. package/dist/mcp/search/types.d.ts.map +0 -1
  300. package/dist/mcp/server.d.ts.map +0 -1
  301. package/dist/mcp/types.d.ts.map +0 -1
  302. package/dist/plugins/auth.d.ts.map +0 -1
  303. package/dist/plugins/cache.d.ts.map +0 -1
  304. package/dist/plugins/circuit-breaker.d.ts.map +0 -1
  305. package/dist/plugins/compression.d.ts.map +0 -1
  306. package/dist/plugins/cookie-jar.d.ts.map +0 -1
  307. package/dist/plugins/dedup.d.ts.map +0 -1
  308. package/dist/plugins/graphql.d.ts.map +0 -1
  309. package/dist/plugins/grpc-web.d.ts.map +0 -1
  310. package/dist/plugins/har-player.d.ts.map +0 -1
  311. package/dist/plugins/har-recorder.d.ts.map +0 -1
  312. package/dist/plugins/hls.d.ts.map +0 -1
  313. package/dist/plugins/http2-push.d.ts.map +0 -1
  314. package/dist/plugins/http3.d.ts.map +0 -1
  315. package/dist/plugins/interface-rotator.d.ts.map +0 -1
  316. package/dist/plugins/jsonrpc.d.ts.map +0 -1
  317. package/dist/plugins/logger.d.ts.map +0 -1
  318. package/dist/plugins/odata.d.ts.map +0 -1
  319. package/dist/plugins/pagination.d.ts.map +0 -1
  320. package/dist/plugins/proxy-rotator.d.ts.map +0 -1
  321. package/dist/plugins/retry.d.ts.map +0 -1
  322. package/dist/plugins/scrape.d.ts.map +0 -1
  323. package/dist/plugins/server-timing.d.ts.map +0 -1
  324. package/dist/plugins/soap.d.ts.map +0 -1
  325. package/dist/plugins/user-agent.d.ts.map +0 -1
  326. package/dist/plugins/xml.d.ts.map +0 -1
  327. package/dist/plugins/xsrf.d.ts.map +0 -1
  328. package/dist/presets/anthropic.d.ts.map +0 -1
  329. package/dist/presets/aws.d.ts.map +0 -1
  330. package/dist/presets/azure-openai.d.ts.map +0 -1
  331. package/dist/presets/azure.d.ts.map +0 -1
  332. package/dist/presets/cloudflare.d.ts.map +0 -1
  333. package/dist/presets/cohere.d.ts.map +0 -1
  334. package/dist/presets/deepseek.d.ts.map +0 -1
  335. package/dist/presets/digitalocean.d.ts.map +0 -1
  336. package/dist/presets/discord.d.ts.map +0 -1
  337. package/dist/presets/fireworks.d.ts.map +0 -1
  338. package/dist/presets/gcp.d.ts.map +0 -1
  339. package/dist/presets/gemini.d.ts.map +0 -1
  340. package/dist/presets/github.d.ts.map +0 -1
  341. package/dist/presets/gitlab.d.ts.map +0 -1
  342. package/dist/presets/groq.d.ts.map +0 -1
  343. package/dist/presets/huggingface.d.ts.map +0 -1
  344. package/dist/presets/index.d.ts.map +0 -1
  345. package/dist/presets/linear.d.ts.map +0 -1
  346. package/dist/presets/mailgun.d.ts.map +0 -1
  347. package/dist/presets/meta.d.ts.map +0 -1
  348. package/dist/presets/mistral.d.ts.map +0 -1
  349. package/dist/presets/notion.d.ts.map +0 -1
  350. package/dist/presets/openai.d.ts.map +0 -1
  351. package/dist/presets/oracle.d.ts.map +0 -1
  352. package/dist/presets/perplexity.d.ts.map +0 -1
  353. package/dist/presets/registry.d.ts.map +0 -1
  354. package/dist/presets/replicate.d.ts.map +0 -1
  355. package/dist/presets/sinch.d.ts.map +0 -1
  356. package/dist/presets/slack.d.ts.map +0 -1
  357. package/dist/presets/stripe.d.ts.map +0 -1
  358. package/dist/presets/supabase.d.ts.map +0 -1
  359. package/dist/presets/tiktok.d.ts.map +0 -1
  360. package/dist/presets/together.d.ts.map +0 -1
  361. package/dist/presets/twilio.d.ts.map +0 -1
  362. package/dist/presets/vercel.d.ts.map +0 -1
  363. package/dist/presets/vultr.d.ts.map +0 -1
  364. package/dist/presets/xai.d.ts.map +0 -1
  365. package/dist/presets/youtube.d.ts.map +0 -1
  366. package/dist/protocols/ftp.d.ts.map +0 -1
  367. package/dist/protocols/index.d.ts.map +0 -1
  368. package/dist/protocols/sftp.d.ts.map +0 -1
  369. package/dist/protocols/telnet.d.ts.map +0 -1
  370. package/dist/recker.d.ts.map +0 -1
  371. package/dist/runner/request-runner.d.ts.map +0 -1
  372. package/dist/scrape/document.d.ts.map +0 -1
  373. package/dist/scrape/element.d.ts.map +0 -1
  374. package/dist/scrape/extractors.d.ts.map +0 -1
  375. package/dist/scrape/index.d.ts.map +0 -1
  376. package/dist/scrape/types.d.ts.map +0 -1
  377. package/dist/testing/index.d.ts.map +0 -1
  378. package/dist/testing/mock-hls-server.d.ts.map +0 -1
  379. package/dist/testing/mock-http-server.d.ts.map +0 -1
  380. package/dist/testing/mock-sse-server.d.ts.map +0 -1
  381. package/dist/testing/mock-udp-server.d.ts.map +0 -1
  382. package/dist/testing/mock-websocket-server.d.ts.map +0 -1
  383. package/dist/testing/mock.d.ts.map +0 -1
  384. package/dist/transport/base-udp.d.ts.map +0 -1
  385. package/dist/transport/fetch.d.ts.map +0 -1
  386. package/dist/transport/udp-response.d.ts.map +0 -1
  387. package/dist/transport/udp.d.ts.map +0 -1
  388. package/dist/transport/undici.d.ts.map +0 -1
  389. package/dist/types/ai.d.ts.map +0 -1
  390. package/dist/types/index.d.ts.map +0 -1
  391. package/dist/types/logger.d.ts.map +0 -1
  392. package/dist/types/udp.d.ts.map +0 -1
  393. package/dist/udp/index.d.ts.map +0 -1
  394. package/dist/utils/agent-manager.d.ts.map +0 -1
  395. package/dist/utils/body.d.ts.map +0 -1
  396. package/dist/utils/cert.d.ts.map +0 -1
  397. package/dist/utils/charset.d.ts.map +0 -1
  398. package/dist/utils/chart.d.ts.map +0 -1
  399. package/dist/utils/client-pool.d.ts.map +0 -1
  400. package/dist/utils/colors.d.ts.map +0 -1
  401. package/dist/utils/concurrency.d.ts.map +0 -1
  402. package/dist/utils/dns-toolkit.d.ts.map +0 -1
  403. package/dist/utils/dns.d.ts.map +0 -1
  404. package/dist/utils/doh.d.ts.map +0 -1
  405. package/dist/utils/download.d.ts.map +0 -1
  406. package/dist/utils/env-proxy.d.ts.map +0 -1
  407. package/dist/utils/header-parser.d.ts.map +0 -1
  408. package/dist/utils/html-cleaner.d.ts.map +0 -1
  409. package/dist/utils/link-header.d.ts.map +0 -1
  410. package/dist/utils/optional-require.d.ts.map +0 -1
  411. package/dist/utils/progress.d.ts.map +0 -1
  412. package/dist/utils/rdap.d.ts.map +0 -1
  413. package/dist/utils/request-pool.d.ts.map +0 -1
  414. package/dist/utils/security-grader.d.ts.map +0 -1
  415. package/dist/utils/sparkline.d.ts.map +0 -1
  416. package/dist/utils/sse.d.ts.map +0 -1
  417. package/dist/utils/streaming.d.ts.map +0 -1
  418. package/dist/utils/system-metrics.d.ts.map +0 -1
  419. package/dist/utils/tls-inspector.d.ts.map +0 -1
  420. package/dist/utils/try-fn.d.ts.map +0 -1
  421. package/dist/utils/upload.d.ts.map +0 -1
  422. package/dist/utils/user-agent.d.ts.map +0 -1
  423. package/dist/utils/whois.d.ts.map +0 -1
  424. package/dist/webrtc/index.d.ts.map +0 -1
  425. package/dist/websocket/client.d.ts.map +0 -1
@@ -6,6 +6,9 @@ import { fileURLToPath } from 'url';
6
6
  import { createHybridSearch } from './search/index.js';
7
7
  import { UnsupportedError } from '../core/errors.js';
8
8
  import { getIpInfo, isValidIP, isGeoIPAvailable, isBogon, isIPv6 } from './ip-intel.js';
9
+ import { networkTools, networkToolHandlers } from './tools/network.js';
10
+ import { ToolRegistry } from './tools/registry.js';
11
+ import { loadToolModules } from './tools/loader.js';
9
12
  export class MCPServer {
10
13
  options;
11
14
  server;
@@ -15,6 +18,7 @@ export class MCPServer {
15
18
  typeDefinitions = [];
16
19
  sseClients = new Set();
17
20
  initialized = false;
21
+ toolRegistry;
18
22
  constructor(options = {}) {
19
23
  this.options = {
20
24
  name: options.name || 'recker-docs',
@@ -26,8 +30,15 @@ export class MCPServer {
26
30
  transport: options.transport || 'stdio',
27
31
  debug: options.debug || false,
28
32
  toolsFilter: options.toolsFilter || [],
33
+ toolPaths: options.toolPaths || [],
29
34
  };
30
35
  this.hybridSearch = createHybridSearch({ debug: this.options.debug });
36
+ this.toolRegistry = new ToolRegistry();
37
+ this.registerInternalTools();
38
+ this.toolRegistry.registerModule({
39
+ tools: networkTools,
40
+ handlers: networkToolHandlers
41
+ });
31
42
  }
32
43
  indexReady = null;
33
44
  async ensureIndexReady() {
@@ -403,125 +414,132 @@ export class MCPServer {
403
414
  }
404
415
  return Array.from(keywords).slice(0, 50);
405
416
  }
406
- getTools() {
407
- const allTools = [
408
- {
409
- name: 'search_docs',
410
- description: 'Search Recker documentation using hybrid search (fuzzy + semantic). Returns matching docs with relevance scores and snippets. Use this first to find relevant documentation.',
411
- inputSchema: {
412
- type: 'object',
413
- properties: {
414
- query: {
415
- type: 'string',
416
- description: 'Search query (e.g., "retry with exponential backoff", "streaming SSE responses", "cache strategies")',
417
- },
418
- category: {
419
- type: 'string',
420
- description: 'Optional: filter by category (http, cli, ai, protocols, reference, guides)',
421
- },
422
- limit: {
423
- type: 'number',
424
- description: 'Max results to return (default: 5, max: 10)',
425
- },
426
- mode: {
427
- type: 'string',
428
- enum: ['hybrid', 'fuzzy', 'semantic'],
429
- description: 'Search mode: hybrid (default), fuzzy (text matching), or semantic (meaning-based)',
430
- },
431
- },
432
- required: ['query'],
417
+ getResources() {
418
+ const resources = [];
419
+ for (const doc of this.docsIndex) {
420
+ resources.push({
421
+ uri: `docs://${doc.path}`,
422
+ name: doc.title,
423
+ description: `Documentation: ${doc.category} - ${doc.title}`,
424
+ mimeType: 'text/markdown',
425
+ });
426
+ }
427
+ for (const example of this.codeExamples) {
428
+ resources.push({
429
+ uri: `example://${example.id}`,
430
+ name: example.title,
431
+ description: `Example: ${example.feature} (${example.complexity})`,
432
+ mimeType: 'text/x-typescript',
433
+ });
434
+ }
435
+ return resources;
436
+ }
437
+ readResource(uri) {
438
+ if (uri.startsWith('docs://')) {
439
+ const path = uri.slice(7);
440
+ const doc = this.docsIndex.find(d => d.path === path);
441
+ if (!doc) {
442
+ throw new Error(`Documentation not found: ${path}`);
443
+ }
444
+ return [{
445
+ uri,
446
+ mimeType: 'text/markdown',
447
+ text: doc.content,
448
+ type: 'resource',
449
+ }];
450
+ }
451
+ if (uri.startsWith('example://')) {
452
+ const id = uri.slice(10);
453
+ const example = this.codeExamples.find(e => e.id === id);
454
+ if (!example) {
455
+ throw new Error(`Example not found: ${id}`);
456
+ }
457
+ return [{
458
+ uri,
459
+ mimeType: 'text/x-typescript',
460
+ text: example.code,
461
+ type: 'resource',
462
+ }];
463
+ }
464
+ throw new Error(`Unknown resource scheme: ${uri}`);
465
+ }
466
+ registerInternalTools() {
467
+ this.toolRegistry.registerTool({
468
+ name: 'rek_search_docs',
469
+ description: 'Search Recker documentation using hybrid search (fuzzy + semantic). Returns matching docs with relevance scores and snippets. Use this first to find relevant documentation.',
470
+ inputSchema: {
471
+ type: 'object',
472
+ properties: {
473
+ query: { type: 'string', description: 'Search query' },
474
+ category: { type: 'string', description: 'Optional: filter by category' },
475
+ limit: { type: 'number', description: 'Max results (default: 5)' },
476
+ mode: { type: 'string', enum: ['hybrid', 'fuzzy', 'semantic'], description: 'Search mode' },
433
477
  },
478
+ required: ['query'],
434
479
  },
435
- {
436
- name: 'get_doc',
437
- description: 'Get the full content of a specific documentation file. Use the path from search_docs results.',
438
- inputSchema: {
439
- type: 'object',
440
- properties: {
441
- path: {
442
- type: 'string',
443
- description: 'Documentation file path (e.g., "http/07-resilience.md", "cli/01-overview.md")',
444
- },
445
- },
446
- required: ['path'],
480
+ }, (args) => Promise.resolve(this.searchDocs(args)));
481
+ this.toolRegistry.registerTool({
482
+ name: 'rek_get_doc',
483
+ description: 'Get the full content of a specific documentation file. Use the path from search_docs results.',
484
+ inputSchema: {
485
+ type: 'object',
486
+ properties: {
487
+ path: { type: 'string', description: 'Documentation file path' },
447
488
  },
489
+ required: ['path'],
448
490
  },
449
- {
450
- name: 'code_examples',
451
- description: 'Get runnable code examples for Recker features. Returns complete, working examples with explanations.',
452
- inputSchema: {
453
- type: 'object',
454
- properties: {
455
- feature: {
456
- type: 'string',
457
- description: 'Feature to get examples for (e.g., "retry", "cache", "streaming", "websocket", "mcp", "batch", "pagination", "middleware")',
458
- },
459
- complexity: {
460
- type: 'string',
461
- enum: ['basic', 'intermediate', 'advanced'],
462
- description: 'Complexity level of the example (default: all levels)',
463
- },
464
- limit: {
465
- type: 'number',
466
- description: 'Max examples to return (default: 3)',
467
- },
468
- },
469
- required: ['feature'],
491
+ }, (args) => Promise.resolve(this.getDoc(args)));
492
+ this.toolRegistry.registerTool({
493
+ name: 'rek_code_examples',
494
+ description: 'Get runnable code examples for Recker features.',
495
+ inputSchema: {
496
+ type: 'object',
497
+ properties: {
498
+ feature: { type: 'string', description: 'Feature to get examples for' },
499
+ complexity: { type: 'string', enum: ['basic', 'intermediate', 'advanced'], description: 'Complexity level' },
500
+ limit: { type: 'number', description: 'Max examples' },
470
501
  },
502
+ required: ['feature'],
471
503
  },
472
- {
473
- name: 'api_schema',
474
- description: 'Get TypeScript types, interfaces, and API schemas for Recker. Useful for generating type-safe code.',
475
- inputSchema: {
476
- type: 'object',
477
- properties: {
478
- type: {
479
- type: 'string',
480
- description: 'Type/interface to look up (e.g., "Client", "RequestOptions", "RetryOptions", "CacheOptions", "MCPServer")',
481
- },
482
- include: {
483
- type: 'string',
484
- enum: ['definition', 'properties', 'both'],
485
- description: 'What to include: just definition, properties breakdown, or both (default: both)',
486
- },
487
- },
488
- required: ['type'],
504
+ }, (args) => Promise.resolve(this.getCodeExamples(args)));
505
+ this.toolRegistry.registerTool({
506
+ name: 'rek_api_schema',
507
+ description: 'Get TypeScript types, interfaces, and API schemas for Recker.',
508
+ inputSchema: {
509
+ type: 'object',
510
+ properties: {
511
+ type: { type: 'string', description: 'Type/interface to look up' },
512
+ include: { type: 'string', enum: ['definition', 'properties', 'both'], description: 'What to include' },
489
513
  },
514
+ required: ['type'],
490
515
  },
491
- {
492
- name: 'suggest',
493
- description: 'Get implementation suggestions based on use case description. Analyzes requirements and suggests the best Recker patterns.',
494
- inputSchema: {
495
- type: 'object',
496
- properties: {
497
- useCase: {
498
- type: 'string',
499
- description: 'Describe what you want to achieve (e.g., "call an API with retry and cache", "stream AI responses", "scrape multiple sites in parallel")',
500
- },
501
- constraints: {
502
- type: 'array',
503
- items: { type: 'string' },
504
- description: 'Any constraints or requirements (e.g., ["must handle rate limits", "need progress tracking"])',
505
- },
506
- },
507
- required: ['useCase'],
516
+ }, (args) => Promise.resolve(this.getApiSchema(args)));
517
+ this.toolRegistry.registerTool({
518
+ name: 'rek_suggest',
519
+ description: 'Get implementation suggestions based on use case description.',
520
+ inputSchema: {
521
+ type: 'object',
522
+ properties: {
523
+ useCase: { type: 'string', description: 'Describe what you want to achieve' },
524
+ constraints: { type: 'array', items: { type: 'string' }, description: 'Any constraints' },
508
525
  },
526
+ required: ['useCase'],
509
527
  },
510
- {
511
- name: 'ip_lookup',
512
- description: 'Get geolocation and network information for an IP address using the local MaxMind GeoLite2 database. Returns city, country, coordinates, timezone, and more. Works offline after first download.',
513
- inputSchema: {
514
- type: 'object',
515
- properties: {
516
- ip: {
517
- type: 'string',
518
- description: 'IPv4 or IPv6 address to lookup (e.g., "8.8.8.8", "2001:4860:4860::8888")',
519
- },
520
- },
521
- required: ['ip'],
528
+ }, (args) => Promise.resolve(this.getSuggestions(args)));
529
+ this.toolRegistry.registerTool({
530
+ name: 'rek_ip_lookup',
531
+ description: 'Get geolocation and network information for an IP address.',
532
+ inputSchema: {
533
+ type: 'object',
534
+ properties: {
535
+ ip: { type: 'string', description: 'IPv4 or IPv6 address' },
522
536
  },
537
+ required: ['ip'],
523
538
  },
524
- ];
539
+ }, (args) => Promise.resolve(this.ipLookup(args)));
540
+ }
541
+ getTools() {
542
+ const allTools = this.toolRegistry.listTools();
525
543
  if (this.options.toolsFilter.length > 0) {
526
544
  return allTools.filter(tool => this.isToolEnabled(tool.name));
527
545
  }
@@ -550,26 +568,8 @@ export class MCPServer {
550
568
  }
551
569
  return name === pattern;
552
570
  }
553
- handleToolCall(name, args) {
554
- switch (name) {
555
- case 'search_docs':
556
- return this.searchDocs(args);
557
- case 'get_doc':
558
- return this.getDoc(args);
559
- case 'code_examples':
560
- return this.getCodeExamples(args);
561
- case 'api_schema':
562
- return this.getApiSchema(args);
563
- case 'suggest':
564
- return this.getSuggestions(args);
565
- case 'ip_lookup':
566
- return this.ipLookup(args);
567
- default:
568
- return {
569
- content: [{ type: 'text', text: `Unknown tool: ${name}` }],
570
- isError: true,
571
- };
572
- }
571
+ async handleToolCall(name, args) {
572
+ return this.toolRegistry.callTool(name, args);
573
573
  }
574
574
  searchDocs(args) {
575
575
  const query = String(args.query || '');
@@ -624,7 +624,7 @@ export class MCPServer {
624
624
  }
625
625
  const stats = this.hybridSearch.getStats();
626
626
  const searchMode = stats.embeddings > 0 ? mode : 'fuzzy';
627
- const output = results.map((r, i) => `${i + 1}. **${r.title}** (${(r.score * 100).toFixed(0)}% match)\n Path: \`${r.path}\`\n ${r.snippet}`).join('\n\n');
627
+ const output = results.map((r, i) => `${i + 1}. **${r.title}** (${(r.score * 100).toFixed(0)}% match)\n Path: \`${r.path}\`\n ${r.snippet}`).join('\\n\\n');
628
628
  return {
629
629
  content: [{
630
630
  type: 'text',
@@ -713,7 +713,7 @@ export class MCPServer {
713
713
  }
714
714
  const output = examples.map((ex, i) => {
715
715
  return `## ${i + 1}. ${ex.title}\n\n**Complexity:** ${ex.complexity}\n**Path:** \`${ex.path}\`\n\n${ex.description ? `${ex.description}\n\n` : ''}\`\`\`typescript\n${ex.code}\n\`\`\``;
716
- }).join('\n\n---\n\n');
716
+ }).join('\\n\\n---\\n\\n');
717
717
  return {
718
718
  content: [{
719
719
  type: 'text',
@@ -750,7 +750,7 @@ export class MCPServer {
750
750
  }
751
751
  result += `**Path:** \`${td.path}\`\n\n`;
752
752
  if (include === 'definition' || include === 'both') {
753
- result += `### Definition\n\n\`\`\`typescript\n${td.definition}\n\`\`\`\n\n`;
753
+ result += `### Definition\n\n\u0060\u0060\u0060typescript\n${td.definition}\n\u0060\u0060\u0060\n\n`;
754
754
  }
755
755
  if ((include === 'properties' || include === 'both') && td.properties && td.properties.length > 0) {
756
756
  result += `### Properties\n\n`;
@@ -828,13 +828,13 @@ export class MCPServer {
828
828
  };
829
829
  }
830
830
  const output = suggestions.map((s, i) => {
831
- return `### ${i + 1}. ${s.feature.charAt(0).toUpperCase() + s.feature.slice(1)}\n\n**Why:** ${s.reason}\n\n**Configuration:**\n\`\`\`typescript\n${s.config}\n\`\`\``;
831
+ return `### ${i + 1}. ${s.feature.charAt(0).toUpperCase() + s.feature.slice(1)}\n\n**Why:** ${s.reason}\n\n**Configuration:**\n\u0060\u0060\u0060typescript\n${s.config}\n\u0060\u0060\u0060`;
832
832
  }).join('\n\n');
833
833
  const combinedConfig = this.getCombinedConfig(suggestions.map(s => s.feature));
834
834
  return {
835
835
  content: [{
836
836
  type: 'text',
837
- text: `# Suggested Implementation for: "${useCase}"\n\n${output}\n\n---\n\n## Combined Configuration\n\n\`\`\`typescript\n${combinedConfig}\n\`\`\``,
837
+ text: `# Suggested Implementation for: "${useCase}"\n\n${output}\n\n---\n\n## Combined Configuration\n\n\u0060\u0060\u0060typescript\n${combinedConfig}\n\u0060\u0060\u0060`,
838
838
  }],
839
839
  };
840
840
  }
@@ -875,7 +875,7 @@ export class MCPServer {
875
875
  return {
876
876
  content: [{
877
877
  type: 'text',
878
- text: `# GeoIP Database Required\n\nThe MaxMind GeoLite2 database is being downloaded (~70MB).\n\nPlease try again in a few seconds, or use the CLI:\n\n\`\`\`bash\nrek ip ${ip}\n\`\`\``,
878
+ text: `# GeoIP Database Required\n\nThe MaxMind GeoLite2 database is being downloaded (~70MB).\n\nPlease try again in a few seconds, or use the CLI:\n\n\u0060\u0060\u0060bash\nrek ip ${ip}\n\u0060\u0060\u0060`,
879
879
  }],
880
880
  };
881
881
  }
@@ -885,7 +885,7 @@ export class MCPServer {
885
885
  return {
886
886
  content: [{
887
887
  type: 'text',
888
- text: `# IP Intelligence: ${ip}\n\n**Status:** Public ${ipv6 ? 'IPv6' : 'IPv4'} Address\n\nFor detailed geolocation data (city, country, coordinates, timezone), use the CLI:\n\n\`\`\`bash\nrek ip ${ip}\n\`\`\`\n\n_Note: The MCP server uses a synchronous protocol. Full GeoIP lookups are available via CLI._`,
888
+ text: `# IP Intelligence: ${ip}\n\n**Status:** Public ${ipv6 ? 'IPv6' : 'IPv4'} Address\n\nFor detailed geolocation data (city, country, coordinates, timezone), use the CLI:\n\n\u0060\u0060\u0060bash\nrek ip ${ip}\n\u0060\u0060\u0060\n\n_Note: The MCP server uses a synchronous protocol. Full GeoIP lookups are available via CLI._`,
889
889
  }],
890
890
  };
891
891
  }
@@ -978,8 +978,7 @@ client.beforeRequest((req) => {
978
978
  })`,
979
979
  progress: `const response = await client.get('/large-file', {
980
980
  onDownloadProgress: ({ percent, rate }) => {
981
- console.log(\`\${percent}% at \${rate} bytes/sec\`);
982
- }
981
+ console.log(\`\${percent}% at \${rate} bytes/sec\`); }
983
982
  });`,
984
983
  timeout: `timeout: 30000, // 30 seconds`,
985
984
  scraping: `const $ = await client.get('/page').scrape();
@@ -997,34 +996,39 @@ for await (const chunk of client.get('/chat/completions').sse()) {
997
996
  `import { createClient } from 'recker';
998
997
 
999
998
  const client = createClient({
1000
- baseUrl: 'https://api.example.com',`,
999
+ baseUrl: 'https://api.example.com',
1000
+ `,
1001
1001
  ];
1002
1002
  if (features.includes('retry')) {
1003
1003
  parts.push(` retry: {
1004
1004
  attempts: 3,
1005
1005
  backoff: 'exponential',
1006
1006
  delay: 1000
1007
- },`);
1007
+ },
1008
+ `);
1008
1009
  }
1009
1010
  if (features.includes('cache')) {
1010
1011
  parts.push(` cache: {
1011
1012
  ttl: 60000,
1012
1013
  strategy: 'stale-while-revalidate'
1013
- },`);
1014
+ },
1015
+ `);
1014
1016
  }
1015
1017
  if (features.includes('rate-limiting')) {
1016
1018
  parts.push(` concurrency: {
1017
1019
  requestsPerInterval: 100,
1018
1020
  interval: 1000
1019
- },`);
1021
+ },
1022
+ `);
1020
1023
  }
1021
1024
  if (features.includes('timeout')) {
1022
- parts.push(` timeout: 30000,`);
1025
+ parts.push(` timeout: 30000,
1026
+ `);
1023
1027
  }
1024
1028
  parts.push(`});`);
1025
1029
  return parts.join('\n');
1026
1030
  }
1027
- handleRequest(req) {
1031
+ async handleRequest(req) {
1028
1032
  const { method, params, id } = req;
1029
1033
  this.log(`Request: ${method}`, params);
1030
1034
  try {
@@ -1054,11 +1058,27 @@ const client = createClient({
1054
1058
  }
1055
1059
  case 'tools/call': {
1056
1060
  const { name, arguments: args } = params;
1057
- const result = this.handleToolCall(name, args || {});
1061
+ const result = await this.handleToolCall(name, args || {});
1058
1062
  return { jsonrpc: '2.0', id: id, result };
1059
1063
  }
1060
- case 'resources/list':
1061
- return { jsonrpc: '2.0', id: id, result: { resources: [] } };
1064
+ case 'resources/list': {
1065
+ const resources = this.getResources();
1066
+ return { jsonrpc: '2.0', id: id, result: { resources } };
1067
+ }
1068
+ case 'resources/read': {
1069
+ const { uri } = params;
1070
+ try {
1071
+ const contents = this.readResource(uri);
1072
+ return { jsonrpc: '2.0', id: id, result: { contents } };
1073
+ }
1074
+ catch (error) {
1075
+ return {
1076
+ jsonrpc: '2.0',
1077
+ id: id,
1078
+ error: { code: -32602, message: error.message },
1079
+ };
1080
+ }
1081
+ }
1062
1082
  case 'prompts/list':
1063
1083
  return { jsonrpc: '2.0', id: id, result: { prompts: [] } };
1064
1084
  default:
@@ -1090,12 +1110,12 @@ const client = createClient({
1090
1110
  terminal: false,
1091
1111
  });
1092
1112
  this.log('Starting in stdio mode');
1093
- rl.on('line', (line) => {
1113
+ rl.on('line', async (line) => {
1094
1114
  if (!line.trim())
1095
1115
  return;
1096
1116
  try {
1097
1117
  const request = JSON.parse(line);
1098
- const response = this.handleRequest(request);
1118
+ const response = await this.handleRequest(request);
1099
1119
  process.stdout.write(JSON.stringify(response) + '\n');
1100
1120
  }
1101
1121
  catch (err) {
@@ -1123,6 +1143,21 @@ const client = createClient({
1123
1143
  res.end();
1124
1144
  return;
1125
1145
  }
1146
+ if (req.method === 'GET' && req.url === '/health') {
1147
+ const stats = this.hybridSearch.getStats();
1148
+ res.writeHead(200, { 'Content-Type': 'application/json' });
1149
+ res.end(JSON.stringify({
1150
+ status: 'ok',
1151
+ name: this.options.name,
1152
+ version: this.options.version,
1153
+ docsCount: stats.documents,
1154
+ examplesCount: this.codeExamples.length,
1155
+ typesCount: this.typeDefinitions.length,
1156
+ embeddingsLoaded: stats.embeddings > 0,
1157
+ sseClients: this.sseClients.size,
1158
+ }));
1159
+ return;
1160
+ }
1126
1161
  if (req.method !== 'POST') {
1127
1162
  res.writeHead(405);
1128
1163
  res.end('Method not allowed');
@@ -1130,10 +1165,10 @@ const client = createClient({
1130
1165
  }
1131
1166
  let body = '';
1132
1167
  req.on('data', chunk => body += chunk);
1133
- req.on('end', () => {
1168
+ req.on('end', async () => {
1134
1169
  try {
1135
1170
  const request = JSON.parse(body);
1136
- const response = this.handleRequest(request);
1171
+ const response = await this.handleRequest(request);
1137
1172
  res.writeHead(200, { 'Content-Type': 'application/json' });
1138
1173
  res.end(JSON.stringify(response));
1139
1174
  }
@@ -1183,10 +1218,10 @@ const client = createClient({
1183
1218
  if (req.method === 'POST') {
1184
1219
  let body = '';
1185
1220
  req.on('data', chunk => body += chunk);
1186
- req.on('end', () => {
1221
+ req.on('end', async () => {
1187
1222
  try {
1188
1223
  const request = JSON.parse(body);
1189
- const response = this.handleRequest(request);
1224
+ const response = await this.handleRequest(request);
1190
1225
  res.writeHead(200, { 'Content-Type': 'application/json' });
1191
1226
  res.end(JSON.stringify(response));
1192
1227
  }
@@ -1230,6 +1265,13 @@ const client = createClient({
1230
1265
  }
1231
1266
  async start() {
1232
1267
  await this.ensureIndexReady();
1268
+ if (this.options.toolPaths.length > 0) {
1269
+ const modules = await loadToolModules(this.options.toolPaths);
1270
+ for (const mod of modules) {
1271
+ this.toolRegistry.registerModule(mod);
1272
+ this.log(`Loaded external tools from module: ${mod.tools.map(t => t.name).join(', ')}`);
1273
+ }
1274
+ }
1233
1275
  switch (this.options.transport) {
1234
1276
  case 'stdio':
1235
1277
  return this.startStdio();
@@ -0,0 +1,2 @@
1
+ import type { ToolModule } from './registry.js';
2
+ export declare function loadToolModules(paths: string[]): Promise<ToolModule[]>;
@@ -0,0 +1,41 @@
1
+ import { resolve } from 'path';
2
+ import { existsSync, statSync } from 'fs';
3
+ import { pathToFileURL } from 'url';
4
+ export async function loadToolModules(paths) {
5
+ const modules = [];
6
+ for (const path of paths) {
7
+ try {
8
+ const fullPath = resolve(process.cwd(), path);
9
+ if (!existsSync(fullPath)) {
10
+ console.error(`Warning: Tool file not found: ${fullPath}`);
11
+ continue;
12
+ }
13
+ const stat = statSync(fullPath);
14
+ if (stat.isDirectory()) {
15
+ console.error(`Warning: Tool path must be a file, not a directory: ${fullPath}`);
16
+ continue;
17
+ }
18
+ const fileUrl = pathToFileURL(fullPath).href;
19
+ const mod = await import(fileUrl);
20
+ if (isValidToolModule(mod)) {
21
+ modules.push(mod);
22
+ }
23
+ else if (mod.default && isValidToolModule(mod.default)) {
24
+ modules.push(mod.default);
25
+ }
26
+ else {
27
+ console.error(`Warning: Invalid tool module at ${path}. Must export 'tools' array and 'handlers' object.`);
28
+ }
29
+ }
30
+ catch (error) {
31
+ console.error(`Error loading tool module from ${path}:`, error);
32
+ }
33
+ }
34
+ return modules;
35
+ }
36
+ function isValidToolModule(mod) {
37
+ return (mod &&
38
+ Array.isArray(mod.tools) &&
39
+ typeof mod.handlers === 'object' &&
40
+ mod.handlers !== null);
41
+ }
@@ -0,0 +1,3 @@
1
+ import type { MCPTool, MCPToolResult } from '../types.js';
2
+ export declare const networkTools: MCPTool[];
3
+ export declare const networkToolHandlers: Record<string, (args: Record<string, unknown>) => Promise<MCPToolResult>>;