@iflow-mcp/jakeliume-webpeel 0.22.0
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.
- package/LICENSE +15 -0
- package/README.md +313 -0
- package/dist/cache.d.ts +30 -0
- package/dist/cache.js +139 -0
- package/dist/cli/commands/auth.d.ts +5 -0
- package/dist/cli/commands/auth.js +411 -0
- package/dist/cli/commands/doctor.d.ts +37 -0
- package/dist/cli/commands/doctor.js +371 -0
- package/dist/cli/commands/fetch.d.ts +6 -0
- package/dist/cli/commands/fetch.js +1345 -0
- package/dist/cli/commands/guide.d.ts +2 -0
- package/dist/cli/commands/guide.js +183 -0
- package/dist/cli/commands/interact.d.ts +5 -0
- package/dist/cli/commands/interact.js +840 -0
- package/dist/cli/commands/jobs.d.ts +5 -0
- package/dist/cli/commands/jobs.js +997 -0
- package/dist/cli/commands/monitor.d.ts +12 -0
- package/dist/cli/commands/monitor.js +197 -0
- package/dist/cli/commands/observe.d.ts +12 -0
- package/dist/cli/commands/observe.js +158 -0
- package/dist/cli/commands/screenshot.d.ts +5 -0
- package/dist/cli/commands/screenshot.js +282 -0
- package/dist/cli/commands/search.d.ts +5 -0
- package/dist/cli/commands/search.js +1021 -0
- package/dist/cli/commands/setup.d.ts +13 -0
- package/dist/cli/commands/setup.js +244 -0
- package/dist/cli/commands/skill.d.ts +15 -0
- package/dist/cli/commands/skill.js +195 -0
- package/dist/cli/utils.d.ts +84 -0
- package/dist/cli/utils.js +806 -0
- package/dist/cli-auth.d.ts +75 -0
- package/dist/cli-auth.js +369 -0
- package/dist/cli.d.ts +17 -0
- package/dist/cli.js +99 -0
- package/dist/core/actions.d.ts +69 -0
- package/dist/core/actions.js +495 -0
- package/dist/core/agent.d.ts +98 -0
- package/dist/core/agent.js +558 -0
- package/dist/core/answer.d.ts +42 -0
- package/dist/core/answer.js +395 -0
- package/dist/core/application-tracker.d.ts +84 -0
- package/dist/core/application-tracker.js +184 -0
- package/dist/core/apply.d.ts +162 -0
- package/dist/core/apply.js +816 -0
- package/dist/core/auth-detection.d.ts +35 -0
- package/dist/core/auth-detection.js +358 -0
- package/dist/core/auto-extract.d.ts +82 -0
- package/dist/core/auto-extract.js +604 -0
- package/dist/core/auto-interact.d.ts +23 -0
- package/dist/core/auto-interact.js +246 -0
- package/dist/core/bm25-filter.d.ts +66 -0
- package/dist/core/bm25-filter.js +288 -0
- package/dist/core/branding.d.ts +54 -0
- package/dist/core/branding.js +234 -0
- package/dist/core/browser-fetch.d.ts +323 -0
- package/dist/core/browser-fetch.js +1600 -0
- package/dist/core/browser-pool.d.ts +91 -0
- package/dist/core/browser-pool.js +550 -0
- package/dist/core/budget.d.ts +42 -0
- package/dist/core/budget.js +324 -0
- package/dist/core/business-intel.d.ts +47 -0
- package/dist/core/business-intel.js +279 -0
- package/dist/core/cache.d.ts +13 -0
- package/dist/core/cache.js +121 -0
- package/dist/core/cf-worker-proxy.d.ts +32 -0
- package/dist/core/cf-worker-proxy.js +87 -0
- package/dist/core/challenge-detection.d.ts +26 -0
- package/dist/core/challenge-detection.js +468 -0
- package/dist/core/change-tracking.d.ts +75 -0
- package/dist/core/change-tracking.js +276 -0
- package/dist/core/chunker.d.ts +46 -0
- package/dist/core/chunker.js +249 -0
- package/dist/core/chunking.d.ts +42 -0
- package/dist/core/chunking.js +181 -0
- package/dist/core/circuit-breaker.d.ts +44 -0
- package/dist/core/circuit-breaker.js +85 -0
- package/dist/core/content-pruner.d.ts +47 -0
- package/dist/core/content-pruner.js +425 -0
- package/dist/core/cookie-cache.d.ts +60 -0
- package/dist/core/cookie-cache.js +163 -0
- package/dist/core/crawl-checkpoint.d.ts +54 -0
- package/dist/core/crawl-checkpoint.js +104 -0
- package/dist/core/crawler.d.ts +84 -0
- package/dist/core/crawler.js +349 -0
- package/dist/core/cross-verify.d.ts +27 -0
- package/dist/core/cross-verify.js +93 -0
- package/dist/core/deep-fetch.d.ts +74 -0
- package/dist/core/deep-fetch.js +405 -0
- package/dist/core/deep-research.d.ts +141 -0
- package/dist/core/deep-research.js +972 -0
- package/dist/core/design-analysis.d.ts +70 -0
- package/dist/core/design-analysis.js +490 -0
- package/dist/core/design-compare.d.ts +38 -0
- package/dist/core/design-compare.js +264 -0
- package/dist/core/diff.d.ts +61 -0
- package/dist/core/diff.js +289 -0
- package/dist/core/dns-cache.d.ts +20 -0
- package/dist/core/dns-cache.js +198 -0
- package/dist/core/documents.d.ts +23 -0
- package/dist/core/documents.js +123 -0
- package/dist/core/domain-memory.d.ts +66 -0
- package/dist/core/domain-memory.js +163 -0
- package/dist/core/domain-verify.d.ts +40 -0
- package/dist/core/domain-verify.js +379 -0
- package/dist/core/engine-ranker.d.ts +112 -0
- package/dist/core/engine-ranker.js +395 -0
- package/dist/core/extract-inline.d.ts +38 -0
- package/dist/core/extract-inline.js +215 -0
- package/dist/core/extract-listings.d.ts +38 -0
- package/dist/core/extract-listings.js +461 -0
- package/dist/core/extract.d.ts +9 -0
- package/dist/core/extract.js +139 -0
- package/dist/core/fetch-cache.d.ts +57 -0
- package/dist/core/fetch-cache.js +95 -0
- package/dist/core/fetcher.d.ts +13 -0
- package/dist/core/fetcher.js +12 -0
- package/dist/core/google-cache.d.ts +29 -0
- package/dist/core/google-cache.js +180 -0
- package/dist/core/google-serp-parser.d.ts +82 -0
- package/dist/core/google-serp-parser.js +287 -0
- package/dist/core/hotel-search.d.ts +122 -0
- package/dist/core/hotel-search.js +382 -0
- package/dist/core/http-fetch.d.ts +72 -0
- package/dist/core/http-fetch.js +820 -0
- package/dist/core/human.d.ts +175 -0
- package/dist/core/human.js +680 -0
- package/dist/core/image-caption.d.ts +44 -0
- package/dist/core/image-caption.js +271 -0
- package/dist/core/jobs.d.ts +75 -0
- package/dist/core/jobs.js +634 -0
- package/dist/core/json-ld.d.ts +15 -0
- package/dist/core/json-ld.js +617 -0
- package/dist/core/language-detect.d.ts +18 -0
- package/dist/core/language-detect.js +135 -0
- package/dist/core/links.d.ts +10 -0
- package/dist/core/links.js +44 -0
- package/dist/core/llm-extract.d.ts +71 -0
- package/dist/core/llm-extract.js +507 -0
- package/dist/core/llm-provider.d.ts +100 -0
- package/dist/core/llm-provider.js +702 -0
- package/dist/core/local-search.d.ts +60 -0
- package/dist/core/local-search.js +308 -0
- package/dist/core/logger.d.ts +28 -0
- package/dist/core/logger.js +104 -0
- package/dist/core/map.d.ts +33 -0
- package/dist/core/map.js +127 -0
- package/dist/core/markdown.d.ts +92 -0
- package/dist/core/markdown.js +809 -0
- package/dist/core/metadata.d.ts +34 -0
- package/dist/core/metadata.js +422 -0
- package/dist/core/observe.d.ts +113 -0
- package/dist/core/observe.js +395 -0
- package/dist/core/ocr.d.ts +12 -0
- package/dist/core/ocr.js +33 -0
- package/dist/core/paginate.d.ts +31 -0
- package/dist/core/paginate.js +106 -0
- package/dist/core/pdf.d.ts +8 -0
- package/dist/core/pdf.js +25 -0
- package/dist/core/peel-tls.d.ts +25 -0
- package/dist/core/peel-tls.js +220 -0
- package/dist/core/pipeline.d.ts +132 -0
- package/dist/core/pipeline.js +1666 -0
- package/dist/core/profiles.d.ts +61 -0
- package/dist/core/profiles.js +350 -0
- package/dist/core/prompt-guard.d.ts +30 -0
- package/dist/core/prompt-guard.js +119 -0
- package/dist/core/proxy-config.d.ts +90 -0
- package/dist/core/proxy-config.js +172 -0
- package/dist/core/quick-answer.d.ts +53 -0
- package/dist/core/quick-answer.js +833 -0
- package/dist/core/rate-governor.d.ts +80 -0
- package/dist/core/rate-governor.js +238 -0
- package/dist/core/readability.d.ts +57 -0
- package/dist/core/readability.js +533 -0
- package/dist/core/research.d.ts +66 -0
- package/dist/core/research.js +270 -0
- package/dist/core/retry.d.ts +60 -0
- package/dist/core/retry.js +119 -0
- package/dist/core/safe-browsing.d.ts +30 -0
- package/dist/core/safe-browsing.js +206 -0
- package/dist/core/schema-extraction.d.ts +66 -0
- package/dist/core/schema-extraction.js +352 -0
- package/dist/core/schema-postprocess.d.ts +32 -0
- package/dist/core/schema-postprocess.js +469 -0
- package/dist/core/schema-templates.d.ts +19 -0
- package/dist/core/schema-templates.js +143 -0
- package/dist/core/screenshot.d.ts +224 -0
- package/dist/core/screenshot.js +207 -0
- package/dist/core/search-engines.d.ts +25 -0
- package/dist/core/search-engines.js +182 -0
- package/dist/core/search-provider.d.ts +243 -0
- package/dist/core/search-provider.js +1629 -0
- package/dist/core/searxng-provider.d.ts +35 -0
- package/dist/core/searxng-provider.js +105 -0
- package/dist/core/selective-evidence.d.ts +151 -0
- package/dist/core/selective-evidence.js +389 -0
- package/dist/core/site-search.d.ts +44 -0
- package/dist/core/site-search.js +252 -0
- package/dist/core/sitemap.d.ts +23 -0
- package/dist/core/sitemap.js +105 -0
- package/dist/core/source-credibility.d.ts +29 -0
- package/dist/core/source-credibility.js +584 -0
- package/dist/core/source-scoring.d.ts +166 -0
- package/dist/core/source-scoring.js +396 -0
- package/dist/core/stemmer.d.ts +38 -0
- package/dist/core/stemmer.js +509 -0
- package/dist/core/strategies.d.ts +104 -0
- package/dist/core/strategies.js +1044 -0
- package/dist/core/strategy-hooks.d.ts +145 -0
- package/dist/core/strategy-hooks.js +74 -0
- package/dist/core/structured-extract.d.ts +43 -0
- package/dist/core/structured-extract.js +550 -0
- package/dist/core/summarize.d.ts +17 -0
- package/dist/core/summarize.js +78 -0
- package/dist/core/synonyms.d.ts +42 -0
- package/dist/core/synonyms.js +184 -0
- package/dist/core/system-monitor.d.ts +61 -0
- package/dist/core/system-monitor.js +133 -0
- package/dist/core/table-format.d.ts +30 -0
- package/dist/core/table-format.js +146 -0
- package/dist/core/threat-feeds.d.ts +23 -0
- package/dist/core/threat-feeds.js +104 -0
- package/dist/core/timing.d.ts +21 -0
- package/dist/core/timing.js +33 -0
- package/dist/core/transcript-export.d.ts +47 -0
- package/dist/core/transcript-export.js +107 -0
- package/dist/core/user-agents.d.ts +82 -0
- package/dist/core/user-agents.js +239 -0
- package/dist/core/vertical-search.d.ts +54 -0
- package/dist/core/vertical-search.js +158 -0
- package/dist/core/watch-manager.d.ts +175 -0
- package/dist/core/watch-manager.js +416 -0
- package/dist/core/watch.d.ts +101 -0
- package/dist/core/watch.js +389 -0
- package/dist/core/youtube.d.ts +130 -0
- package/dist/core/youtube.js +1175 -0
- package/dist/ee/challenge-re-export.d.ts +1 -0
- package/dist/ee/challenge-re-export.js +1 -0
- package/dist/ee/challenge-solver.d.ts +72 -0
- package/dist/ee/challenge-solver.js +720 -0
- package/dist/ee/domain-extractors.d.ts +8 -0
- package/dist/ee/domain-extractors.js +8 -0
- package/dist/ee/domain-intel.d.ts +16 -0
- package/dist/ee/domain-intel.js +133 -0
- package/dist/ee/extractors/allrecipes.d.ts +2 -0
- package/dist/ee/extractors/allrecipes.js +120 -0
- package/dist/ee/extractors/amazon.d.ts +2 -0
- package/dist/ee/extractors/amazon.js +78 -0
- package/dist/ee/extractors/arxiv.d.ts +2 -0
- package/dist/ee/extractors/arxiv.js +137 -0
- package/dist/ee/extractors/bestbuy.d.ts +2 -0
- package/dist/ee/extractors/bestbuy.js +78 -0
- package/dist/ee/extractors/carscom.d.ts +2 -0
- package/dist/ee/extractors/carscom.js +121 -0
- package/dist/ee/extractors/coingecko.d.ts +2 -0
- package/dist/ee/extractors/coingecko.js +134 -0
- package/dist/ee/extractors/craigslist.d.ts +2 -0
- package/dist/ee/extractors/craigslist.js +92 -0
- package/dist/ee/extractors/devto.d.ts +2 -0
- package/dist/ee/extractors/devto.js +135 -0
- package/dist/ee/extractors/ebay.d.ts +2 -0
- package/dist/ee/extractors/ebay.js +90 -0
- package/dist/ee/extractors/espn.d.ts +2 -0
- package/dist/ee/extractors/espn.js +260 -0
- package/dist/ee/extractors/etsy.d.ts +2 -0
- package/dist/ee/extractors/etsy.js +52 -0
- package/dist/ee/extractors/facebook.d.ts +2 -0
- package/dist/ee/extractors/facebook.js +46 -0
- package/dist/ee/extractors/github.d.ts +2 -0
- package/dist/ee/extractors/github.js +196 -0
- package/dist/ee/extractors/google-flights.d.ts +2 -0
- package/dist/ee/extractors/google-flights.js +176 -0
- package/dist/ee/extractors/hackernews.d.ts +2 -0
- package/dist/ee/extractors/hackernews.js +147 -0
- package/dist/ee/extractors/imdb.d.ts +2 -0
- package/dist/ee/extractors/imdb.js +172 -0
- package/dist/ee/extractors/index.d.ts +26 -0
- package/dist/ee/extractors/index.js +247 -0
- package/dist/ee/extractors/instagram.d.ts +2 -0
- package/dist/ee/extractors/instagram.js +102 -0
- package/dist/ee/extractors/kalshi.d.ts +2 -0
- package/dist/ee/extractors/kalshi.js +121 -0
- package/dist/ee/extractors/kayak-cars.d.ts +2 -0
- package/dist/ee/extractors/kayak-cars.js +270 -0
- package/dist/ee/extractors/linkedin.d.ts +2 -0
- package/dist/ee/extractors/linkedin.js +113 -0
- package/dist/ee/extractors/medium.d.ts +2 -0
- package/dist/ee/extractors/medium.js +130 -0
- package/dist/ee/extractors/news.d.ts +4 -0
- package/dist/ee/extractors/news.js +173 -0
- package/dist/ee/extractors/npm.d.ts +2 -0
- package/dist/ee/extractors/npm.js +86 -0
- package/dist/ee/extractors/pdf.d.ts +2 -0
- package/dist/ee/extractors/pdf.js +108 -0
- package/dist/ee/extractors/pinterest.d.ts +2 -0
- package/dist/ee/extractors/pinterest.js +34 -0
- package/dist/ee/extractors/polymarket.d.ts +2 -0
- package/dist/ee/extractors/polymarket.js +358 -0
- package/dist/ee/extractors/producthunt.d.ts +2 -0
- package/dist/ee/extractors/producthunt.js +88 -0
- package/dist/ee/extractors/pubmed.d.ts +2 -0
- package/dist/ee/extractors/pubmed.js +162 -0
- package/dist/ee/extractors/pypi.d.ts +2 -0
- package/dist/ee/extractors/pypi.js +80 -0
- package/dist/ee/extractors/reddit.d.ts +2 -0
- package/dist/ee/extractors/reddit.js +438 -0
- package/dist/ee/extractors/redfin.d.ts +2 -0
- package/dist/ee/extractors/redfin.js +156 -0
- package/dist/ee/extractors/semanticscholar.d.ts +2 -0
- package/dist/ee/extractors/semanticscholar.js +131 -0
- package/dist/ee/extractors/shared.d.ts +12 -0
- package/dist/ee/extractors/shared.js +76 -0
- package/dist/ee/extractors/soundcloud.d.ts +2 -0
- package/dist/ee/extractors/soundcloud.js +34 -0
- package/dist/ee/extractors/sportsbetting.d.ts +2 -0
- package/dist/ee/extractors/sportsbetting.js +37 -0
- package/dist/ee/extractors/spotify.d.ts +2 -0
- package/dist/ee/extractors/spotify.js +34 -0
- package/dist/ee/extractors/stackoverflow.d.ts +2 -0
- package/dist/ee/extractors/stackoverflow.js +61 -0
- package/dist/ee/extractors/substack.d.ts +2 -0
- package/dist/ee/extractors/substack.js +115 -0
- package/dist/ee/extractors/substackroot.d.ts +2 -0
- package/dist/ee/extractors/substackroot.js +46 -0
- package/dist/ee/extractors/tiktok.d.ts +2 -0
- package/dist/ee/extractors/tiktok.js +29 -0
- package/dist/ee/extractors/tradingview.d.ts +2 -0
- package/dist/ee/extractors/tradingview.js +182 -0
- package/dist/ee/extractors/twitch.d.ts +2 -0
- package/dist/ee/extractors/twitch.js +36 -0
- package/dist/ee/extractors/twitter.d.ts +2 -0
- package/dist/ee/extractors/twitter.js +327 -0
- package/dist/ee/extractors/types.d.ts +14 -0
- package/dist/ee/extractors/types.js +1 -0
- package/dist/ee/extractors/walmart.d.ts +2 -0
- package/dist/ee/extractors/walmart.js +50 -0
- package/dist/ee/extractors/weather.d.ts +2 -0
- package/dist/ee/extractors/weather.js +133 -0
- package/dist/ee/extractors/wikipedia.d.ts +4 -0
- package/dist/ee/extractors/wikipedia.js +235 -0
- package/dist/ee/extractors/yelp.d.ts +2 -0
- package/dist/ee/extractors/yelp.js +216 -0
- package/dist/ee/extractors/youtube.d.ts +2 -0
- package/dist/ee/extractors/youtube.js +189 -0
- package/dist/ee/extractors/zillow.d.ts +54 -0
- package/dist/ee/extractors/zillow.js +247 -0
- package/dist/ee/extractors-re-export.d.ts +1 -0
- package/dist/ee/extractors-re-export.js +1 -0
- package/dist/ee/premium-hooks.d.ts +20 -0
- package/dist/ee/premium-hooks.js +50 -0
- package/dist/ee/spa-detection.d.ts +2 -0
- package/dist/ee/spa-detection.js +2 -0
- package/dist/ee/stability.d.ts +4 -0
- package/dist/ee/stability.js +29 -0
- package/dist/ee/swr-cache.d.ts +14 -0
- package/dist/ee/swr-cache.js +34 -0
- package/dist/index.d.ts +143 -0
- package/dist/index.js +291 -0
- package/dist/integrations/index.d.ts +2 -0
- package/dist/integrations/index.js +2 -0
- package/dist/integrations/langchain.d.ts +64 -0
- package/dist/integrations/langchain.js +115 -0
- package/dist/integrations/llamaindex.d.ts +50 -0
- package/dist/integrations/llamaindex.js +91 -0
- package/dist/mcp/handlers/act.d.ts +5 -0
- package/dist/mcp/handlers/act.js +34 -0
- package/dist/mcp/handlers/definitions.d.ts +6 -0
- package/dist/mcp/handlers/definitions.js +395 -0
- package/dist/mcp/handlers/extract.d.ts +7 -0
- package/dist/mcp/handlers/extract.js +135 -0
- package/dist/mcp/handlers/fetch.d.ts +6 -0
- package/dist/mcp/handlers/fetch.js +98 -0
- package/dist/mcp/handlers/find.d.ts +5 -0
- package/dist/mcp/handlers/find.js +137 -0
- package/dist/mcp/handlers/index.d.ts +13 -0
- package/dist/mcp/handlers/index.js +63 -0
- package/dist/mcp/handlers/legacy.d.ts +25 -0
- package/dist/mcp/handlers/legacy.js +450 -0
- package/dist/mcp/handlers/meta.d.ts +6 -0
- package/dist/mcp/handlers/meta.js +40 -0
- package/dist/mcp/handlers/monitor.d.ts +5 -0
- package/dist/mcp/handlers/monitor.js +41 -0
- package/dist/mcp/handlers/observe.d.ts +8 -0
- package/dist/mcp/handlers/observe.js +37 -0
- package/dist/mcp/handlers/read.d.ts +6 -0
- package/dist/mcp/handlers/read.js +78 -0
- package/dist/mcp/handlers/see.d.ts +5 -0
- package/dist/mcp/handlers/see.js +75 -0
- package/dist/mcp/handlers/types.d.ts +29 -0
- package/dist/mcp/handlers/types.js +28 -0
- package/dist/mcp/server.d.ts +7 -0
- package/dist/mcp/server.js +108 -0
- package/dist/mcp/smart-router.d.ts +23 -0
- package/dist/mcp/smart-router.js +178 -0
- package/dist/server/app.d.ts +14 -0
- package/dist/server/app.js +632 -0
- package/dist/server/auth-store.d.ts +28 -0
- package/dist/server/auth-store.js +88 -0
- package/dist/server/bull-queues.d.ts +60 -0
- package/dist/server/bull-queues.js +90 -0
- package/dist/server/email-service.d.ts +55 -0
- package/dist/server/email-service.js +291 -0
- package/dist/server/job-queue.d.ts +100 -0
- package/dist/server/job-queue.js +145 -0
- package/dist/server/logger.d.ts +10 -0
- package/dist/server/logger.js +37 -0
- package/dist/server/middleware/audit-log.d.ts +14 -0
- package/dist/server/middleware/audit-log.js +73 -0
- package/dist/server/middleware/auth.d.ts +35 -0
- package/dist/server/middleware/auth.js +225 -0
- package/dist/server/middleware/rate-limit.d.ts +50 -0
- package/dist/server/middleware/rate-limit.js +270 -0
- package/dist/server/middleware/scope-guard.d.ts +25 -0
- package/dist/server/middleware/scope-guard.js +45 -0
- package/dist/server/middleware/url-validator.d.ts +15 -0
- package/dist/server/middleware/url-validator.js +201 -0
- package/dist/server/openapi.yaml +6418 -0
- package/dist/server/pg-auth-store.d.ts +146 -0
- package/dist/server/pg-auth-store.js +576 -0
- package/dist/server/pg-job-queue.d.ts +59 -0
- package/dist/server/pg-job-queue.js +375 -0
- package/dist/server/routes/activity.d.ts +6 -0
- package/dist/server/routes/activity.js +79 -0
- package/dist/server/routes/admin-active.d.ts +7 -0
- package/dist/server/routes/admin-active.js +120 -0
- package/dist/server/routes/admin-stats.d.ts +7 -0
- package/dist/server/routes/admin-stats.js +176 -0
- package/dist/server/routes/agent.d.ts +24 -0
- package/dist/server/routes/agent.js +480 -0
- package/dist/server/routes/answer.d.ts +5 -0
- package/dist/server/routes/answer.js +125 -0
- package/dist/server/routes/ask.d.ts +28 -0
- package/dist/server/routes/ask.js +295 -0
- package/dist/server/routes/batch.d.ts +6 -0
- package/dist/server/routes/batch.js +493 -0
- package/dist/server/routes/cache-warm.d.ts +25 -0
- package/dist/server/routes/cache-warm.js +212 -0
- package/dist/server/routes/cli-usage.d.ts +6 -0
- package/dist/server/routes/cli-usage.js +127 -0
- package/dist/server/routes/compat.d.ts +23 -0
- package/dist/server/routes/compat.js +652 -0
- package/dist/server/routes/crawl.d.ts +13 -0
- package/dist/server/routes/crawl.js +287 -0
- package/dist/server/routes/deep-fetch.d.ts +8 -0
- package/dist/server/routes/deep-fetch.js +57 -0
- package/dist/server/routes/deep-research.d.ts +11 -0
- package/dist/server/routes/deep-research.js +232 -0
- package/dist/server/routes/demo.d.ts +24 -0
- package/dist/server/routes/demo.js +517 -0
- package/dist/server/routes/do.d.ts +8 -0
- package/dist/server/routes/do.js +72 -0
- package/dist/server/routes/extract.d.ts +14 -0
- package/dist/server/routes/extract.js +325 -0
- package/dist/server/routes/feed.d.ts +15 -0
- package/dist/server/routes/feed.js +311 -0
- package/dist/server/routes/fetch-queue.d.ts +13 -0
- package/dist/server/routes/fetch-queue.js +357 -0
- package/dist/server/routes/fetch.d.ts +7 -0
- package/dist/server/routes/fetch.js +1274 -0
- package/dist/server/routes/go.d.ts +14 -0
- package/dist/server/routes/go.js +81 -0
- package/dist/server/routes/health.d.ts +11 -0
- package/dist/server/routes/health.js +141 -0
- package/dist/server/routes/jobs.d.ts +7 -0
- package/dist/server/routes/jobs.js +574 -0
- package/dist/server/routes/map.d.ts +11 -0
- package/dist/server/routes/map.js +116 -0
- package/dist/server/routes/mcp.d.ts +14 -0
- package/dist/server/routes/mcp.js +197 -0
- package/dist/server/routes/metrics.d.ts +37 -0
- package/dist/server/routes/metrics.js +149 -0
- package/dist/server/routes/oauth.d.ts +9 -0
- package/dist/server/routes/oauth.js +396 -0
- package/dist/server/routes/playground.d.ts +17 -0
- package/dist/server/routes/playground.js +283 -0
- package/dist/server/routes/reader.d.ts +18 -0
- package/dist/server/routes/reader.js +192 -0
- package/dist/server/routes/research.d.ts +14 -0
- package/dist/server/routes/research.js +482 -0
- package/dist/server/routes/screenshot.d.ts +22 -0
- package/dist/server/routes/screenshot.js +820 -0
- package/dist/server/routes/search.d.ts +6 -0
- package/dist/server/routes/search.js +874 -0
- package/dist/server/routes/session.d.ts +17 -0
- package/dist/server/routes/session.js +548 -0
- package/dist/server/routes/share.d.ts +18 -0
- package/dist/server/routes/share.js +462 -0
- package/dist/server/routes/smart-search/handlers/cars.d.ts +2 -0
- package/dist/server/routes/smart-search/handlers/cars.js +102 -0
- package/dist/server/routes/smart-search/handlers/flights.d.ts +2 -0
- package/dist/server/routes/smart-search/handlers/flights.js +72 -0
- package/dist/server/routes/smart-search/handlers/general.d.ts +13 -0
- package/dist/server/routes/smart-search/handlers/general.js +717 -0
- package/dist/server/routes/smart-search/handlers/hotels.d.ts +2 -0
- package/dist/server/routes/smart-search/handlers/hotels.js +88 -0
- package/dist/server/routes/smart-search/handlers/products.d.ts +2 -0
- package/dist/server/routes/smart-search/handlers/products.js +1309 -0
- package/dist/server/routes/smart-search/handlers/rental.d.ts +2 -0
- package/dist/server/routes/smart-search/handlers/rental.js +154 -0
- package/dist/server/routes/smart-search/handlers/restaurants.d.ts +2 -0
- package/dist/server/routes/smart-search/handlers/restaurants.js +225 -0
- package/dist/server/routes/smart-search/handlers/transit-verdict.d.ts +41 -0
- package/dist/server/routes/smart-search/handlers/transit-verdict.js +224 -0
- package/dist/server/routes/smart-search/index.d.ts +19 -0
- package/dist/server/routes/smart-search/index.js +546 -0
- package/dist/server/routes/smart-search/intent.d.ts +3 -0
- package/dist/server/routes/smart-search/intent.js +264 -0
- package/dist/server/routes/smart-search/llm.d.ts +16 -0
- package/dist/server/routes/smart-search/llm.js +70 -0
- package/dist/server/routes/smart-search/sources/reddit.d.ts +18 -0
- package/dist/server/routes/smart-search/sources/reddit.js +34 -0
- package/dist/server/routes/smart-search/sources/yelp.d.ts +25 -0
- package/dist/server/routes/smart-search/sources/yelp.js +171 -0
- package/dist/server/routes/smart-search/sources/youtube.d.ts +8 -0
- package/dist/server/routes/smart-search/sources/youtube.js +9 -0
- package/dist/server/routes/smart-search/types.d.ts +81 -0
- package/dist/server/routes/smart-search/types.js +1 -0
- package/dist/server/routes/smart-search/utils.d.ts +20 -0
- package/dist/server/routes/smart-search/utils.js +146 -0
- package/dist/server/routes/stats.d.ts +6 -0
- package/dist/server/routes/stats.js +71 -0
- package/dist/server/routes/stripe.d.ts +15 -0
- package/dist/server/routes/stripe.js +296 -0
- package/dist/server/routes/transcript-export.d.ts +10 -0
- package/dist/server/routes/transcript-export.js +178 -0
- package/dist/server/routes/usage.d.ts +9 -0
- package/dist/server/routes/usage.js +279 -0
- package/dist/server/routes/users.d.ts +8 -0
- package/dist/server/routes/users.js +1867 -0
- package/dist/server/routes/watch.d.ts +15 -0
- package/dist/server/routes/watch.js +309 -0
- package/dist/server/routes/webhooks.d.ts +26 -0
- package/dist/server/routes/webhooks.js +170 -0
- package/dist/server/routes/youtube.d.ts +6 -0
- package/dist/server/routes/youtube.js +130 -0
- package/dist/server/sentry.d.ts +14 -0
- package/dist/server/sentry.js +104 -0
- package/dist/server/types.d.ts +15 -0
- package/dist/server/types.js +7 -0
- package/dist/server/utils/response.d.ts +44 -0
- package/dist/server/utils/response.js +69 -0
- package/dist/server/utils/sse.d.ts +22 -0
- package/dist/server/utils/sse.js +38 -0
- package/dist/types.d.ts +552 -0
- package/dist/types.js +39 -0
- package/llms.txt +105 -0
- package/package.json +189 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* First-class /v1/map endpoint
|
|
3
|
+
*
|
|
4
|
+
* Native WebPeel URL discovery API — returns our standard {success, links, count} format.
|
|
5
|
+
* Distinct from the Firecrawl-compatible compat.ts /v1/map route.
|
|
6
|
+
*
|
|
7
|
+
* POST /v1/map — Discover all URLs on a domain
|
|
8
|
+
*/
|
|
9
|
+
import { Router } from 'express';
|
|
10
|
+
import '../types.js'; // Augments Express.Request with requestId
|
|
11
|
+
import { mapDomain } from '../../core/map.js';
|
|
12
|
+
import { validateUrlForSSRF, SSRFError } from '../middleware/url-validator.js';
|
|
13
|
+
export function createMapRouter() {
|
|
14
|
+
const router = Router();
|
|
15
|
+
/**
|
|
16
|
+
* POST /v1/map
|
|
17
|
+
*
|
|
18
|
+
* Discover all URLs on a domain by combining sitemap discovery and link crawling.
|
|
19
|
+
*
|
|
20
|
+
* Body:
|
|
21
|
+
* url {string} Required. Starting URL / domain root.
|
|
22
|
+
* search {string} Optional. Filter URLs by relevance to this query.
|
|
23
|
+
* maxUrls {number} Max URLs to return (default: 5000).
|
|
24
|
+
* includePatterns {string[]} Regex patterns — only include matching URLs.
|
|
25
|
+
* excludePatterns {string[]} Regex patterns — exclude matching URLs.
|
|
26
|
+
*
|
|
27
|
+
* Response:
|
|
28
|
+
* { success: true, links: [{url, title?, description?}], count: number }
|
|
29
|
+
*/
|
|
30
|
+
router.post('/', async (req, res) => {
|
|
31
|
+
try {
|
|
32
|
+
const { url, search, maxUrls = 5000, includePatterns, excludePatterns, } = req.body ?? {};
|
|
33
|
+
// Validate URL
|
|
34
|
+
if (!url || typeof url !== 'string') {
|
|
35
|
+
res.status(400).json({
|
|
36
|
+
success: false,
|
|
37
|
+
error: {
|
|
38
|
+
type: 'invalid_request',
|
|
39
|
+
message: 'Missing or invalid "url" parameter.',
|
|
40
|
+
docs: 'https://webpeel.dev/docs/api-reference#map',
|
|
41
|
+
},
|
|
42
|
+
requestId: req.requestId,
|
|
43
|
+
});
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
new URL(url);
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
res.status(400).json({
|
|
51
|
+
success: false,
|
|
52
|
+
error: {
|
|
53
|
+
type: 'invalid_request',
|
|
54
|
+
message: 'Invalid URL format.',
|
|
55
|
+
docs: 'https://webpeel.dev/docs/api-reference#map',
|
|
56
|
+
},
|
|
57
|
+
requestId: req.requestId,
|
|
58
|
+
});
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
// SECURITY: Validate URL to prevent SSRF
|
|
62
|
+
try {
|
|
63
|
+
validateUrlForSSRF(url);
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
if (error instanceof SSRFError) {
|
|
67
|
+
res.status(400).json({
|
|
68
|
+
success: false,
|
|
69
|
+
error: {
|
|
70
|
+
type: 'blocked_url',
|
|
71
|
+
message: 'Cannot map localhost, private networks, or non-HTTP URLs.',
|
|
72
|
+
docs: 'https://webpeel.dev/docs/api-reference#map',
|
|
73
|
+
},
|
|
74
|
+
requestId: req.requestId,
|
|
75
|
+
});
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
const mapOptions = {
|
|
81
|
+
maxUrls,
|
|
82
|
+
search: typeof search === 'string' ? search : undefined,
|
|
83
|
+
};
|
|
84
|
+
if (Array.isArray(includePatterns) && includePatterns.length > 0) {
|
|
85
|
+
mapOptions.includePatterns = includePatterns;
|
|
86
|
+
}
|
|
87
|
+
if (Array.isArray(excludePatterns) && excludePatterns.length > 0) {
|
|
88
|
+
mapOptions.excludePatterns = excludePatterns;
|
|
89
|
+
}
|
|
90
|
+
const result = await mapDomain(url, mapOptions);
|
|
91
|
+
// Return native format: { url, title?, description? }
|
|
92
|
+
// mapDomain returns urls as string[], so wrap each in an object.
|
|
93
|
+
const links = result.urls.map((u) => ({ url: u }));
|
|
94
|
+
res.json({
|
|
95
|
+
success: true,
|
|
96
|
+
links,
|
|
97
|
+
count: links.length,
|
|
98
|
+
elapsed: result.elapsed,
|
|
99
|
+
requestId: req.requestId,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
console.error('POST /v1/map error:', error);
|
|
104
|
+
res.status(500).json({
|
|
105
|
+
success: false,
|
|
106
|
+
error: {
|
|
107
|
+
type: 'internal_error',
|
|
108
|
+
message: 'An unexpected error occurred.',
|
|
109
|
+
docs: 'https://webpeel.dev/docs/api-reference#errors',
|
|
110
|
+
},
|
|
111
|
+
requestId: req.requestId,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
return router;
|
|
116
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hosted MCP endpoint — POST /mcp, POST /v2/mcp, POST /:apiKey/v2/mcp
|
|
3
|
+
*
|
|
4
|
+
* Thin HTTP/SSE transport wrapper. All tool logic lives in the shared handler
|
|
5
|
+
* registry at src/mcp/handlers/. This file handles:
|
|
6
|
+
* - Express routing and auth
|
|
7
|
+
* - MCP Streamable HTTP transport setup
|
|
8
|
+
* - Passing McpContext (accountId, pool) to handlers
|
|
9
|
+
*/
|
|
10
|
+
import { Router } from 'express';
|
|
11
|
+
import type { AuthStore } from '../auth-store.js';
|
|
12
|
+
import '../types.js';
|
|
13
|
+
import type { Pool } from 'pg';
|
|
14
|
+
export declare function createMcpRouter(_authStore?: AuthStore, pool?: Pool | null): Router;
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hosted MCP endpoint — POST /mcp, POST /v2/mcp, POST /:apiKey/v2/mcp
|
|
3
|
+
*
|
|
4
|
+
* Thin HTTP/SSE transport wrapper. All tool logic lives in the shared handler
|
|
5
|
+
* registry at src/mcp/handlers/. This file handles:
|
|
6
|
+
* - Express routing and auth
|
|
7
|
+
* - MCP Streamable HTTP transport setup
|
|
8
|
+
* - Passing McpContext (accountId, pool) to handlers
|
|
9
|
+
*/
|
|
10
|
+
import { Router } from 'express';
|
|
11
|
+
import '../types.js'; // Augments Express.Request with requestId
|
|
12
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
13
|
+
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
14
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
15
|
+
import { readFileSync } from 'fs';
|
|
16
|
+
import { join, dirname } from 'path';
|
|
17
|
+
import { fileURLToPath } from 'url';
|
|
18
|
+
import { getHandler } from '../../mcp/handlers/index.js';
|
|
19
|
+
import { toolDefinitions } from '../../mcp/handlers/definitions.js';
|
|
20
|
+
// Read version from package.json
|
|
21
|
+
let pkgVersion = '0.7.0';
|
|
22
|
+
try {
|
|
23
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
24
|
+
const __dirname = dirname(__filename);
|
|
25
|
+
const pkg = JSON.parse(readFileSync(join(__dirname, '..', '..', '..', 'package.json'), 'utf-8'));
|
|
26
|
+
pkgVersion = pkg.version;
|
|
27
|
+
}
|
|
28
|
+
catch { /* fallback */ }
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// Helper
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
function safeStringify(obj) {
|
|
33
|
+
try {
|
|
34
|
+
return JSON.stringify(obj, null, 2);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return JSON.stringify({ error: 'serialization_error', message: 'Failed to serialize result' });
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
// Create a fresh MCP server instance (stateless — one per request)
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
function createMcpServer(pool, req) {
|
|
44
|
+
const mcpServer = new Server({ name: 'webpeel', version: pkgVersion }, { capabilities: { tools: {}, prompts: {} } });
|
|
45
|
+
mcpServer.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: toolDefinitions }));
|
|
46
|
+
// MCP Prompts — pre-built templates for common web data tasks
|
|
47
|
+
const mcpPrompts = [
|
|
48
|
+
{
|
|
49
|
+
name: 'research',
|
|
50
|
+
description: 'Research a topic by searching the web and synthesizing findings from multiple sources.',
|
|
51
|
+
arguments: [{ name: 'topic', description: 'Topic to research', required: true }],
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: 'extract-product',
|
|
55
|
+
description: 'Extract structured product data (name, price, rating, reviews) from any e-commerce URL.',
|
|
56
|
+
arguments: [{ name: 'url', description: 'Product page URL (Amazon, Best Buy, etc.)', required: true }],
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: 'monitor-price',
|
|
60
|
+
description: 'Set up price monitoring for a product page. Tracks changes and reports diffs.',
|
|
61
|
+
arguments: [{ name: 'url', description: 'Product URL to monitor', required: true }],
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
name: 'summarize',
|
|
65
|
+
description: 'Fetch a web page and provide a concise summary of its content.',
|
|
66
|
+
arguments: [{ name: 'url', description: 'URL to summarize', required: true }],
|
|
67
|
+
},
|
|
68
|
+
];
|
|
69
|
+
mcpServer.setRequestHandler(ListPromptsRequestSchema, async () => ({ prompts: mcpPrompts }));
|
|
70
|
+
mcpServer.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
71
|
+
const { name, arguments: args } = request.params;
|
|
72
|
+
const promptMap = {
|
|
73
|
+
'research': (a) => ({ messages: [{ role: 'user', content: { type: 'text', text: `Research "${a.topic}" using webpeel_find with depth="deep", then summarize the key findings with sources.` } }] }),
|
|
74
|
+
'extract-product': (a) => ({ messages: [{ role: 'user', content: { type: 'text', text: `Use webpeel_extract on ${a.url} with fields=['name','price','rating','reviews','availability'] and return the structured data.` } }] }),
|
|
75
|
+
'monitor-price': (a) => ({ messages: [{ role: 'user', content: { type: 'text', text: `Use webpeel_monitor on ${a.url} with selector=".price" to track price changes. Report the current price and set up monitoring.` } }] }),
|
|
76
|
+
'summarize': (a) => ({ messages: [{ role: 'user', content: { type: 'text', text: `Use webpeel_read on ${a.url} with budget=500 to get a concise version, then summarize the key points in 3-4 sentences.` } }] }),
|
|
77
|
+
};
|
|
78
|
+
const handler = promptMap[name];
|
|
79
|
+
if (!handler)
|
|
80
|
+
throw new Error(`Prompt not found: ${name}`);
|
|
81
|
+
return handler((args || {}));
|
|
82
|
+
});
|
|
83
|
+
mcpServer.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
84
|
+
const { name, arguments: rawArgs } = request.params;
|
|
85
|
+
const args = (rawArgs ?? {});
|
|
86
|
+
// Build context: auth + pool for HTTP-specific features (webpeel_watch)
|
|
87
|
+
const accountId = req?.auth?.keyInfo?.accountId ||
|
|
88
|
+
req?.user?.userId ||
|
|
89
|
+
'anonymous';
|
|
90
|
+
const ctx = { accountId, pool: pool ?? undefined };
|
|
91
|
+
try {
|
|
92
|
+
const handler = getHandler(name);
|
|
93
|
+
if (!handler)
|
|
94
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
95
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
96
|
+
return (await handler(args, ctx));
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
const err = error;
|
|
100
|
+
return {
|
|
101
|
+
content: [
|
|
102
|
+
{
|
|
103
|
+
type: 'text',
|
|
104
|
+
text: safeStringify({ error: err.name || 'Error', message: err.message || 'Unknown error' }),
|
|
105
|
+
},
|
|
106
|
+
],
|
|
107
|
+
isError: true,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
return mcpServer;
|
|
112
|
+
}
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
// Shared MCP request handler
|
|
115
|
+
// ---------------------------------------------------------------------------
|
|
116
|
+
async function handleMcpPost(req, res, pool) {
|
|
117
|
+
// Allow unauthenticated access to discovery methods (initialize, tools/list)
|
|
118
|
+
// so MCP marketplaces (Smithery, Glama) and clients can discover our tools.
|
|
119
|
+
// Actual tool execution (tools/call) still works without auth but uses free-tier limits.
|
|
120
|
+
const mcpAuthId = req.auth?.keyInfo?.accountId || req.user?.userId;
|
|
121
|
+
const body = req.body;
|
|
122
|
+
const method = body?.method || (Array.isArray(body) ? body[0]?.method : undefined);
|
|
123
|
+
const isDiscovery = method === 'initialize' || method === 'tools/list' || method === 'notifications/initialized';
|
|
124
|
+
// Only block if no auth AND it's not a discovery method
|
|
125
|
+
if (!mcpAuthId && !isDiscovery) {
|
|
126
|
+
// Still allow tools/call without auth — it'll use anonymous rate limits
|
|
127
|
+
// This enables free-tier MCP usage without signup
|
|
128
|
+
}
|
|
129
|
+
try {
|
|
130
|
+
const mcpServer = createMcpServer(pool, req);
|
|
131
|
+
const transport = new StreamableHTTPServerTransport({
|
|
132
|
+
sessionIdGenerator: undefined, // stateless
|
|
133
|
+
});
|
|
134
|
+
await mcpServer.connect(transport);
|
|
135
|
+
await transport.handleRequest(
|
|
136
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
137
|
+
req, res, req.body);
|
|
138
|
+
transport.close().catch(() => { });
|
|
139
|
+
mcpServer.close().catch(() => { });
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
console.error('MCP endpoint error:', error);
|
|
143
|
+
if (!res.headersSent) {
|
|
144
|
+
res.status(500).json({
|
|
145
|
+
success: false,
|
|
146
|
+
error: {
|
|
147
|
+
type: 'internal_error',
|
|
148
|
+
message: 'Internal error',
|
|
149
|
+
docs: 'https://webpeel.dev/docs/errors#internal_error',
|
|
150
|
+
},
|
|
151
|
+
requestId: req.requestId,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
function mcpMethodNotAllowed(req, res) {
|
|
157
|
+
res.status(405).json({ success: false, error: { type: 'method_not_allowed', message: 'Method not allowed. Use POST to send MCP JSON-RPC messages.', hint: 'Send a POST request with a JSON-RPC body', docs: 'https://webpeel.dev/docs/errors#method_not_allowed' }, requestId: req.requestId });
|
|
158
|
+
}
|
|
159
|
+
function mcpDeleteOk(_req, res) {
|
|
160
|
+
res.status(200).json({ ok: true });
|
|
161
|
+
}
|
|
162
|
+
// ---------------------------------------------------------------------------
|
|
163
|
+
// Express router
|
|
164
|
+
// ---------------------------------------------------------------------------
|
|
165
|
+
export function createMcpRouter(_authStore, pool) {
|
|
166
|
+
const router = Router();
|
|
167
|
+
const boundHandler = (req, res) => handleMcpPost(req, res, pool);
|
|
168
|
+
// GET /.well-known/mcp/server-card.json — MCP server discovery (Smithery, Glama, etc.)
|
|
169
|
+
router.get('/.well-known/mcp/server-card.json', (_req, res) => {
|
|
170
|
+
res.json({
|
|
171
|
+
name: 'WebPeel',
|
|
172
|
+
description: 'The web data platform for AI agents — fetch, search, crawl, extract, monitor, screenshot. 55+ domain extractors, 65-98% token savings.',
|
|
173
|
+
version: '0.21.87',
|
|
174
|
+
tools_count: 7,
|
|
175
|
+
homepage: 'https://webpeel.dev',
|
|
176
|
+
documentation: 'https://webpeel.dev/docs/mcp',
|
|
177
|
+
mcp_endpoint: 'https://api.webpeel.dev/mcp',
|
|
178
|
+
authentication: { type: 'optional', description: 'Bearer token optional. Works without auth using free-tier limits.' },
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
// POST /mcp — legacy path
|
|
182
|
+
router.post('/mcp', boundHandler);
|
|
183
|
+
router.get('/mcp', mcpMethodNotAllowed);
|
|
184
|
+
router.delete('/mcp', mcpDeleteOk);
|
|
185
|
+
// POST /v2/mcp — canonical v2 path; auth via Authorization: Bearer <key> header
|
|
186
|
+
router.post('/v2/mcp', boundHandler);
|
|
187
|
+
router.get('/v2/mcp', mcpMethodNotAllowed);
|
|
188
|
+
router.delete('/v2/mcp', mcpDeleteOk);
|
|
189
|
+
// SECURITY: /:apiKey/v2/mcp — BLOCKED. API keys in URLs are insecure.
|
|
190
|
+
const mcpInsecureAuthHandler = (req, res) => {
|
|
191
|
+
res.status(400).json({ success: false, error: { type: 'insecure_auth', message: 'API keys in URLs are insecure.', hint: 'Use the Authorization header instead: Authorization: Bearer wp_your_key', docs: 'https://webpeel.dev/docs/api-reference#authentication' }, requestId: req.requestId });
|
|
192
|
+
};
|
|
193
|
+
router.post('/:apiKey/v2/mcp', mcpInsecureAuthHandler);
|
|
194
|
+
router.get('/:apiKey/v2/mcp', mcpInsecureAuthHandler);
|
|
195
|
+
router.delete('/:apiKey/v2/mcp', mcpInsecureAuthHandler);
|
|
196
|
+
return router;
|
|
197
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prometheus metrics endpoint for WebPeel.
|
|
3
|
+
*
|
|
4
|
+
* Exposed at GET /metrics (behind auth — admin only).
|
|
5
|
+
*
|
|
6
|
+
* Metrics:
|
|
7
|
+
* - webpeel_requests_total — counter by method, path, status
|
|
8
|
+
* - webpeel_request_duration_seconds — histogram by method, status
|
|
9
|
+
* - webpeel_active_requests — gauge of in-flight requests
|
|
10
|
+
* - webpeel_fetch_duration_seconds — histogram of peel() execution time
|
|
11
|
+
* - webpeel_fetch_method_total — counter by fetch method (simple/browser/stealth)
|
|
12
|
+
* - webpeel_errors_total — counter by error code
|
|
13
|
+
* - webpeel_queue_jobs — gauge of queued/active/failed jobs
|
|
14
|
+
* - webpeel_memory_usage_bytes — gauge from system monitor
|
|
15
|
+
*/
|
|
16
|
+
import { Router, Request, Response, NextFunction } from 'express';
|
|
17
|
+
import client from 'prom-client';
|
|
18
|
+
export declare const httpRequestsTotal: client.Counter<"path" | "status" | "method">;
|
|
19
|
+
export declare const httpRequestDuration: client.Histogram<"status" | "method">;
|
|
20
|
+
export declare const activeRequests: client.Gauge<string>;
|
|
21
|
+
export declare const fetchDuration: client.Histogram<"method" | "success">;
|
|
22
|
+
export declare const fetchMethodCounter: client.Counter<"method">;
|
|
23
|
+
export declare const errorsTotal: client.Counter<"code">;
|
|
24
|
+
export declare const queueJobs: client.Gauge<"state" | "queue">;
|
|
25
|
+
export declare const memoryUsageBytes: client.Gauge<"type">;
|
|
26
|
+
/**
|
|
27
|
+
* Express middleware that records request metrics.
|
|
28
|
+
* Add EARLY in the middleware chain (after request ID, before routes).
|
|
29
|
+
*/
|
|
30
|
+
export declare function metricsMiddleware(): (req: Request, res: Response, next: NextFunction) => void;
|
|
31
|
+
/** Record a peel() operation result */
|
|
32
|
+
export declare function recordFetch(method: string, durationMs: number, success: boolean): void;
|
|
33
|
+
/** Record an error by code */
|
|
34
|
+
export declare function recordError(code: string): void;
|
|
35
|
+
/** Update memory gauge */
|
|
36
|
+
export declare function updateMemoryMetrics(): void;
|
|
37
|
+
export declare function createMetricsRouter(): Router;
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prometheus metrics endpoint for WebPeel.
|
|
3
|
+
*
|
|
4
|
+
* Exposed at GET /metrics (behind auth — admin only).
|
|
5
|
+
*
|
|
6
|
+
* Metrics:
|
|
7
|
+
* - webpeel_requests_total — counter by method, path, status
|
|
8
|
+
* - webpeel_request_duration_seconds — histogram by method, status
|
|
9
|
+
* - webpeel_active_requests — gauge of in-flight requests
|
|
10
|
+
* - webpeel_fetch_duration_seconds — histogram of peel() execution time
|
|
11
|
+
* - webpeel_fetch_method_total — counter by fetch method (simple/browser/stealth)
|
|
12
|
+
* - webpeel_errors_total — counter by error code
|
|
13
|
+
* - webpeel_queue_jobs — gauge of queued/active/failed jobs
|
|
14
|
+
* - webpeel_memory_usage_bytes — gauge from system monitor
|
|
15
|
+
*/
|
|
16
|
+
import { Router } from 'express';
|
|
17
|
+
import client from 'prom-client';
|
|
18
|
+
// Create a custom registry (don't use default to avoid conflicts)
|
|
19
|
+
const register = new client.Registry();
|
|
20
|
+
// Default metrics (CPU, memory, event loop, etc.)
|
|
21
|
+
client.collectDefaultMetrics({ register, prefix: 'webpeel_' });
|
|
22
|
+
// ─── Custom metrics ──────────────────────────────────────────────────────────
|
|
23
|
+
export const httpRequestsTotal = new client.Counter({
|
|
24
|
+
name: 'webpeel_http_requests_total',
|
|
25
|
+
help: 'Total HTTP requests',
|
|
26
|
+
labelNames: ['method', 'path', 'status'],
|
|
27
|
+
registers: [register],
|
|
28
|
+
});
|
|
29
|
+
export const httpRequestDuration = new client.Histogram({
|
|
30
|
+
name: 'webpeel_http_request_duration_seconds',
|
|
31
|
+
help: 'HTTP request duration in seconds',
|
|
32
|
+
labelNames: ['method', 'status'],
|
|
33
|
+
buckets: [0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10, 30, 60],
|
|
34
|
+
registers: [register],
|
|
35
|
+
});
|
|
36
|
+
export const activeRequests = new client.Gauge({
|
|
37
|
+
name: 'webpeel_active_requests',
|
|
38
|
+
help: 'Number of active (in-flight) requests',
|
|
39
|
+
registers: [register],
|
|
40
|
+
});
|
|
41
|
+
export const fetchDuration = new client.Histogram({
|
|
42
|
+
name: 'webpeel_fetch_duration_seconds',
|
|
43
|
+
help: 'Duration of peel() fetch operations',
|
|
44
|
+
labelNames: ['method', 'success'],
|
|
45
|
+
buckets: [0.1, 0.5, 1, 2, 5, 10, 30, 60, 120],
|
|
46
|
+
registers: [register],
|
|
47
|
+
});
|
|
48
|
+
export const fetchMethodCounter = new client.Counter({
|
|
49
|
+
name: 'webpeel_fetch_method_total',
|
|
50
|
+
help: 'Fetch method used',
|
|
51
|
+
labelNames: ['method'],
|
|
52
|
+
registers: [register],
|
|
53
|
+
});
|
|
54
|
+
export const errorsTotal = new client.Counter({
|
|
55
|
+
name: 'webpeel_errors_total',
|
|
56
|
+
help: 'Total errors by error code',
|
|
57
|
+
labelNames: ['code'],
|
|
58
|
+
registers: [register],
|
|
59
|
+
});
|
|
60
|
+
export const queueJobs = new client.Gauge({
|
|
61
|
+
name: 'webpeel_queue_jobs',
|
|
62
|
+
help: 'Queue job counts',
|
|
63
|
+
labelNames: ['queue', 'state'],
|
|
64
|
+
registers: [register],
|
|
65
|
+
});
|
|
66
|
+
export const memoryUsageBytes = new client.Gauge({
|
|
67
|
+
name: 'webpeel_memory_usage_bytes',
|
|
68
|
+
help: 'Application memory usage in bytes',
|
|
69
|
+
labelNames: ['type'],
|
|
70
|
+
registers: [register],
|
|
71
|
+
});
|
|
72
|
+
// ─── Metrics collection middleware ───────────────────────────────────────────
|
|
73
|
+
/**
|
|
74
|
+
* Express middleware that records request metrics.
|
|
75
|
+
* Add EARLY in the middleware chain (after request ID, before routes).
|
|
76
|
+
*/
|
|
77
|
+
export function metricsMiddleware() {
|
|
78
|
+
return (req, res, next) => {
|
|
79
|
+
const start = process.hrtime.bigint();
|
|
80
|
+
activeRequests.inc();
|
|
81
|
+
res.on('finish', () => {
|
|
82
|
+
activeRequests.dec();
|
|
83
|
+
const durationNs = Number(process.hrtime.bigint() - start);
|
|
84
|
+
const durationS = durationNs / 1e9;
|
|
85
|
+
// Normalize path to avoid high-cardinality labels
|
|
86
|
+
const normalizedPath = normalizePath(req.path);
|
|
87
|
+
httpRequestsTotal.inc({
|
|
88
|
+
method: req.method,
|
|
89
|
+
path: normalizedPath,
|
|
90
|
+
status: res.statusCode.toString(),
|
|
91
|
+
});
|
|
92
|
+
httpRequestDuration.observe({ method: req.method, status: res.statusCode.toString() }, durationS);
|
|
93
|
+
});
|
|
94
|
+
next();
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
/** Normalize request path to reduce cardinality (UUIDs, IDs → :id) */
|
|
98
|
+
function normalizePath(path) {
|
|
99
|
+
return path
|
|
100
|
+
.replace(/\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi, '/:id')
|
|
101
|
+
.replace(/\/wp_[a-z]+_[a-f0-9]+/gi, '/:key')
|
|
102
|
+
.replace(/\/\d+/g, '/:id')
|
|
103
|
+
.replace(/\?.*$/, ''); // strip query params
|
|
104
|
+
}
|
|
105
|
+
// ─── Helper functions for recording metrics from other modules ───────────────
|
|
106
|
+
/** Record a peel() operation result */
|
|
107
|
+
export function recordFetch(method, durationMs, success) {
|
|
108
|
+
fetchDuration.observe({ method, success: success.toString() }, durationMs / 1000);
|
|
109
|
+
fetchMethodCounter.inc({ method });
|
|
110
|
+
}
|
|
111
|
+
/** Record an error by code */
|
|
112
|
+
export function recordError(code) {
|
|
113
|
+
errorsTotal.inc({ code });
|
|
114
|
+
}
|
|
115
|
+
/** Update memory gauge */
|
|
116
|
+
export function updateMemoryMetrics() {
|
|
117
|
+
const mem = process.memoryUsage();
|
|
118
|
+
memoryUsageBytes.set({ type: 'rss' }, mem.rss);
|
|
119
|
+
memoryUsageBytes.set({ type: 'heapUsed' }, mem.heapUsed);
|
|
120
|
+
memoryUsageBytes.set({ type: 'heapTotal' }, mem.heapTotal);
|
|
121
|
+
memoryUsageBytes.set({ type: 'external' }, mem.external);
|
|
122
|
+
}
|
|
123
|
+
// Update memory metrics every 15s
|
|
124
|
+
setInterval(updateMemoryMetrics, 15_000);
|
|
125
|
+
// ─── Router ──────────────────────────────────────────────────────────────────
|
|
126
|
+
export function createMetricsRouter() {
|
|
127
|
+
const router = Router();
|
|
128
|
+
router.get('/metrics', async (req, res) => {
|
|
129
|
+
// Only allow admin tier to access metrics
|
|
130
|
+
if (req.auth?.tier !== 'admin') {
|
|
131
|
+
// Also allow unauthenticated access from localhost/K8s internal (Prometheus scraper)
|
|
132
|
+
const ip = req.ip || '';
|
|
133
|
+
const isInternal = ip === '127.0.0.1' ||
|
|
134
|
+
ip === '::1' ||
|
|
135
|
+
ip.startsWith('10.') ||
|
|
136
|
+
ip.startsWith('172.');
|
|
137
|
+
if (!isInternal) {
|
|
138
|
+
res.status(403).json({
|
|
139
|
+
success: false,
|
|
140
|
+
error: { type: 'forbidden', message: 'Metrics require admin access' },
|
|
141
|
+
});
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
res.set('Content-Type', register.contentType);
|
|
146
|
+
res.end(await register.metrics());
|
|
147
|
+
});
|
|
148
|
+
return router;
|
|
149
|
+
}
|