mcp-scraper 0.3.17 → 0.3.19

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 (62) hide show
  1. package/README.md +26 -58
  2. package/dist/bin/api-server.cjs +346 -60
  3. package/dist/bin/api-server.cjs.map +1 -1
  4. package/dist/bin/api-server.js +2 -2
  5. package/dist/bin/mcp-scraper-cli.cjs +4 -4
  6. package/dist/bin/mcp-scraper-cli.cjs.map +1 -1
  7. package/dist/bin/mcp-scraper-cli.js +5 -5
  8. package/dist/bin/mcp-scraper-cli.js.map +1 -1
  9. package/dist/bin/mcp-scraper-install.cjs +12 -12
  10. package/dist/bin/mcp-scraper-install.cjs.map +1 -1
  11. package/dist/bin/mcp-scraper-install.js +3 -3
  12. package/dist/bin/mcp-scraper-install.js.map +1 -1
  13. package/dist/bin/mcp-stdio-server.cjs +2441 -785
  14. package/dist/bin/mcp-stdio-server.cjs.map +1 -1
  15. package/dist/bin/mcp-stdio-server.js +1377 -9
  16. package/dist/bin/mcp-stdio-server.js.map +1 -1
  17. package/dist/bin/paa-harvest.js +2 -3
  18. package/dist/bin/paa-harvest.js.map +1 -1
  19. package/dist/{chunk-N33YEY6W.js → chunk-A46NKAAM.js} +210 -10
  20. package/dist/{chunk-N33YEY6W.js.map → chunk-A46NKAAM.js.map} +1 -1
  21. package/dist/chunk-AUKOY2IV.js +7 -0
  22. package/dist/chunk-AUKOY2IV.js.map +1 -0
  23. package/dist/{chunk-ACIUCZ27.js → chunk-DE7WP4UU.js} +11 -11
  24. package/dist/chunk-DE7WP4UU.js.map +1 -0
  25. package/dist/{chunk-4OPKIDON.js → chunk-IGOEAKC7.js} +4 -6
  26. package/dist/{chunk-4OPKIDON.js.map → chunk-IGOEAKC7.js.map} +1 -1
  27. package/dist/{chunk-ZAUMSBV3.js → chunk-T337IGVE.js} +8 -8
  28. package/dist/chunk-T337IGVE.js.map +1 -0
  29. package/dist/{chunk-M2S27J6Z.js → chunk-ZAP7MYVO.js} +26 -1
  30. package/dist/chunk-ZAP7MYVO.js.map +1 -0
  31. package/dist/index.js +2 -3
  32. package/dist/index.js.map +1 -1
  33. package/dist/{server-TKWY47JA.js → server-EYNMXWUJ.js} +379 -167
  34. package/dist/server-EYNMXWUJ.js.map +1 -0
  35. package/dist/{worker-2WVKKCC7.js → worker-YZ2ZJE4F.js} +9 -10
  36. package/dist/{worker-2WVKKCC7.js.map → worker-YZ2ZJE4F.js.map} +1 -1
  37. package/docs/mcp-tool-manifest.generated.json +28 -27
  38. package/package.json +3 -3
  39. package/dist/bin/browser-agent-stdio-server.cjs +0 -1523
  40. package/dist/bin/browser-agent-stdio-server.cjs.map +0 -1
  41. package/dist/bin/browser-agent-stdio-server.d.cts +0 -1
  42. package/dist/bin/browser-agent-stdio-server.d.ts +0 -1
  43. package/dist/bin/browser-agent-stdio-server.js +0 -43
  44. package/dist/bin/browser-agent-stdio-server.js.map +0 -1
  45. package/dist/bin/mcp-scraper-combined-stdio-server.cjs +0 -5718
  46. package/dist/bin/mcp-scraper-combined-stdio-server.cjs.map +0 -1
  47. package/dist/bin/mcp-scraper-combined-stdio-server.d.cts +0 -1
  48. package/dist/bin/mcp-scraper-combined-stdio-server.d.ts +0 -1
  49. package/dist/bin/mcp-scraper-combined-stdio-server.js +0 -70
  50. package/dist/bin/mcp-scraper-combined-stdio-server.js.map +0 -1
  51. package/dist/chunk-3YGKXXUG.js +0 -133
  52. package/dist/chunk-3YGKXXUG.js.map +0 -1
  53. package/dist/chunk-ACIUCZ27.js.map +0 -1
  54. package/dist/chunk-M2S27J6Z.js.map +0 -1
  55. package/dist/chunk-PVWWY5NV.js +0 -7
  56. package/dist/chunk-PVWWY5NV.js.map +0 -1
  57. package/dist/chunk-UFD7N36R.js +0 -1332
  58. package/dist/chunk-UFD7N36R.js.map +0 -1
  59. package/dist/chunk-WN7PBKMV.js +0 -28
  60. package/dist/chunk-WN7PBKMV.js.map +0 -1
  61. package/dist/chunk-ZAUMSBV3.js.map +0 -1
  62. package/dist/server-TKWY47JA.js.map +0 -1
@@ -4,7 +4,14 @@ import {
4
4
  createHarvestAttemptRecorder,
5
5
  harvestProblemResponse,
6
6
  serializeHarvestProblem
7
- } from "./chunk-ZAUMSBV3.js";
7
+ } from "./chunk-T337IGVE.js";
8
+ import {
9
+ harvest
10
+ } from "./chunk-IGOEAKC7.js";
11
+ import {
12
+ browserServiceApiKey
13
+ } from "./chunk-ZAP7MYVO.js";
14
+ import "./chunk-LFATOGDF.js";
8
15
  import {
9
16
  claimPendingJob,
10
17
  completeJob,
@@ -13,14 +20,6 @@ import {
13
20
  failJob,
14
21
  listHarvestAttempts
15
22
  } from "./chunk-5H22TOXQ.js";
16
- import {
17
- harvest
18
- } from "./chunk-4OPKIDON.js";
19
- import "./chunk-M2S27J6Z.js";
20
- import {
21
- browserServiceApiKey
22
- } from "./chunk-WN7PBKMV.js";
23
- import "./chunk-LFATOGDF.js";
24
23
 
25
24
  // src/api/webhook.ts
26
25
  async function deliverWebhook(url, payload, retries = 3) {
@@ -125,4 +124,4 @@ export {
125
124
  startWorker,
126
125
  tickOnce
127
126
  };
128
- //# sourceMappingURL=worker-2WVKKCC7.js.map
127
+ //# sourceMappingURL=worker-YZ2ZJE4F.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/api/webhook.ts","../src/api/worker.ts"],"sourcesContent":["export async function deliverWebhook(url: string, payload: object, retries = 3): Promise<void> {\n for (let attempt = 1; attempt <= retries; attempt++) {\n try {\n const res = await fetch(url, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n signal: AbortSignal.timeout(10_000),\n })\n if (res.ok) return\n console.warn(`[webhook] attempt ${attempt} → ${res.status} from ${url}`)\n } catch (err) {\n console.warn(`[webhook] attempt ${attempt} failed:`, err instanceof Error ? err.message : err)\n }\n if (attempt < retries) await new Promise((r) => setTimeout(r, 1000 * attempt * 2))\n }\n console.error(`[webhook] gave up after ${retries} attempts for ${url}`)\n}\n","import { claimPendingJob, completeJob, failJob, creditMc, debitMc, listHarvestAttempts } from './db.js'\nimport { browserServiceApiKey } from '../lib/browser-service-env.js'\nimport { harvest } from '../harvest.js'\nimport { deliverWebhook } from './webhook.js'\nimport type { HarvestOptions } from '../types.js'\nimport { MC_COSTS } from './rates.js'\nimport { classifyHarvestProblem, harvestProblemResponse, serializeHarvestProblem } from './harvest-problems.js'\nimport { createHarvestAttemptRecorder } from './harvest-attempt-events.js'\n\nexport type TickResult = {\n claimed: boolean\n jobId?: string\n completed?: boolean\n durationMs?: number\n}\nexport type DrainBudget = {\n maxJobs: number\n deadlineMs: number\n}\n\nconst MAX_CONCURRENT = 2\nlet running = 0\n\nfunction countPaaQuestions(result: unknown): number {\n if (!result || typeof result !== 'object') return 0\n const value = result as { totalQuestions?: unknown; flat?: unknown }\n if (typeof value.totalQuestions === 'number') return value.totalQuestions\n return Array.isArray(value.flat) ? value.flat.length : 0\n}\n\nfunction paaCostForQuestionCount(questionCount: number): number {\n return Math.max(1, questionCount) * MC_COSTS.paa\n}\n\nasync function processJob(job: Awaited<ReturnType<typeof claimPendingJob>> & object) {\n running++\n try {\n const opts = typeof job.options === 'string' ? JSON.parse(job.options) as Partial<HarvestOptions> & { billingHoldMc?: number } : job.options as Partial<HarvestOptions> & { billingHoldMc?: number }\n const result = await harvest({\n ...opts,\n kernelApiKey: browserServiceApiKey(),\n headless: true,\n format: 'json',\n outputDir: '/tmp/paa-output-api',\n onAttemptEvent: createHarvestAttemptRecorder(job.id, job.user_id),\n })\n await completeJob(job.id, result)\n const attempts = await listHarvestAttempts(job.id, job.user_id)\n if (!opts.serpOnly && typeof opts.billingHoldMc === 'number') {\n const actualCost = paaCostForQuestionCount(countPaaQuestions(result))\n const diff = opts.billingHoldMc - actualCost\n if (diff > 0) await creditMc(job.user_id, diff, 'paa_refund', 'overestimate refund')\n else if (diff < 0) await debitMc(job.user_id, -diff, 'paa', opts.query ?? job.query)\n }\n if (job.callback_url) {\n await deliverWebhook(job.callback_url, { job_id: job.id, status: 'done', result, attempts })\n }\n } catch (err) {\n const problem = classifyHarvestProblem(err)\n await failJob(job.id, serializeHarvestProblem(problem))\n const attempts = await listHarvestAttempts(job.id, job.user_id)\n try {\n const opts = typeof job.options === 'string' ? JSON.parse(job.options) as { billingHoldMc?: number } : job.options as { billingHoldMc?: number }\n if (typeof opts.billingHoldMc === 'number' && opts.billingHoldMc > 0) {\n await creditMc(job.user_id, opts.billingHoldMc, 'refund', 'failed call')\n }\n } catch {}\n if (job.callback_url) {\n await deliverWebhook(job.callback_url, { job_id: job.id, status: 'failed', ...harvestProblemResponse(problem), attempts })\n }\n } finally {\n running--\n }\n}\n\nexport async function tickOnce(): Promise<TickResult> {\n const job = await claimPendingJob()\n if (!job) return { claimed: false }\n const startedAt = Date.now()\n await processJob(job as NonNullable<typeof job>)\n return { claimed: true, jobId: (job as { id: string }).id, completed: true, durationMs: Date.now() - startedAt }\n}\n\nexport async function drainQueue(budget: DrainBudget): Promise<TickResult[]> {\n const results: TickResult[] = []\n for (let i = 0; i < budget.maxJobs; i++) {\n if (Date.now() >= budget.deadlineMs) break\n const r = await tickOnce()\n results.push(r)\n if (!r.claimed) break\n }\n return results\n}\n\nexport function startWorker(): void {\n setInterval(async () => {\n if (running >= MAX_CONCURRENT) return\n const job = await claimPendingJob()\n if (job) void processJob(job as NonNullable<typeof job>)\n }, 2000)\n console.log(`[worker] started — polling every 2s, max ${MAX_CONCURRENT} concurrent`)\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/api/webhook.ts","../src/api/worker.ts"],"sourcesContent":["export async function deliverWebhook(url: string, payload: object, retries = 3): Promise<void> {\n for (let attempt = 1; attempt <= retries; attempt++) {\n try {\n const res = await fetch(url, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n signal: AbortSignal.timeout(10_000),\n })\n if (res.ok) return\n console.warn(`[webhook] attempt ${attempt} → ${res.status} from ${url}`)\n } catch (err) {\n console.warn(`[webhook] attempt ${attempt} failed:`, err instanceof Error ? err.message : err)\n }\n if (attempt < retries) await new Promise((r) => setTimeout(r, 1000 * attempt * 2))\n }\n console.error(`[webhook] gave up after ${retries} attempts for ${url}`)\n}\n","import { claimPendingJob, completeJob, failJob, creditMc, debitMc, listHarvestAttempts } from './db.js'\nimport { browserServiceApiKey } from '../lib/browser-service-env.js'\nimport { harvest } from '../harvest.js'\nimport { deliverWebhook } from './webhook.js'\nimport type { HarvestOptions } from '../types.js'\nimport { MC_COSTS } from './rates.js'\nimport { classifyHarvestProblem, harvestProblemResponse, serializeHarvestProblem } from './harvest-problems.js'\nimport { createHarvestAttemptRecorder } from './harvest-attempt-events.js'\n\nexport type TickResult = {\n claimed: boolean\n jobId?: string\n completed?: boolean\n durationMs?: number\n}\nexport type DrainBudget = {\n maxJobs: number\n deadlineMs: number\n}\n\nconst MAX_CONCURRENT = 2\nlet running = 0\n\nfunction countPaaQuestions(result: unknown): number {\n if (!result || typeof result !== 'object') return 0\n const value = result as { totalQuestions?: unknown; flat?: unknown }\n if (typeof value.totalQuestions === 'number') return value.totalQuestions\n return Array.isArray(value.flat) ? value.flat.length : 0\n}\n\nfunction paaCostForQuestionCount(questionCount: number): number {\n return Math.max(1, questionCount) * MC_COSTS.paa\n}\n\nasync function processJob(job: Awaited<ReturnType<typeof claimPendingJob>> & object) {\n running++\n try {\n const opts = typeof job.options === 'string' ? JSON.parse(job.options) as Partial<HarvestOptions> & { billingHoldMc?: number } : job.options as Partial<HarvestOptions> & { billingHoldMc?: number }\n const result = await harvest({\n ...opts,\n kernelApiKey: browserServiceApiKey(),\n headless: true,\n format: 'json',\n outputDir: '/tmp/paa-output-api',\n onAttemptEvent: createHarvestAttemptRecorder(job.id, job.user_id),\n })\n await completeJob(job.id, result)\n const attempts = await listHarvestAttempts(job.id, job.user_id)\n if (!opts.serpOnly && typeof opts.billingHoldMc === 'number') {\n const actualCost = paaCostForQuestionCount(countPaaQuestions(result))\n const diff = opts.billingHoldMc - actualCost\n if (diff > 0) await creditMc(job.user_id, diff, 'paa_refund', 'overestimate refund')\n else if (diff < 0) await debitMc(job.user_id, -diff, 'paa', opts.query ?? job.query)\n }\n if (job.callback_url) {\n await deliverWebhook(job.callback_url, { job_id: job.id, status: 'done', result, attempts })\n }\n } catch (err) {\n const problem = classifyHarvestProblem(err)\n await failJob(job.id, serializeHarvestProblem(problem))\n const attempts = await listHarvestAttempts(job.id, job.user_id)\n try {\n const opts = typeof job.options === 'string' ? JSON.parse(job.options) as { billingHoldMc?: number } : job.options as { billingHoldMc?: number }\n if (typeof opts.billingHoldMc === 'number' && opts.billingHoldMc > 0) {\n await creditMc(job.user_id, opts.billingHoldMc, 'refund', 'failed call')\n }\n } catch {}\n if (job.callback_url) {\n await deliverWebhook(job.callback_url, { job_id: job.id, status: 'failed', ...harvestProblemResponse(problem), attempts })\n }\n } finally {\n running--\n }\n}\n\nexport async function tickOnce(): Promise<TickResult> {\n const job = await claimPendingJob()\n if (!job) return { claimed: false }\n const startedAt = Date.now()\n await processJob(job as NonNullable<typeof job>)\n return { claimed: true, jobId: (job as { id: string }).id, completed: true, durationMs: Date.now() - startedAt }\n}\n\nexport async function drainQueue(budget: DrainBudget): Promise<TickResult[]> {\n const results: TickResult[] = []\n for (let i = 0; i < budget.maxJobs; i++) {\n if (Date.now() >= budget.deadlineMs) break\n const r = await tickOnce()\n results.push(r)\n if (!r.claimed) break\n }\n return results\n}\n\nexport function startWorker(): void {\n setInterval(async () => {\n if (running >= MAX_CONCURRENT) return\n const job = await claimPendingJob()\n if (job) void processJob(job as NonNullable<typeof job>)\n }, 2000)\n console.log(`[worker] started — polling every 2s, max ${MAX_CONCURRENT} concurrent`)\n}\n"],"mappings":"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","names":[]}
@@ -1,5 +1,5 @@
1
1
  {
2
- "generatedAt": "2026-06-26T17:52:12.189Z",
2
+ "generatedAt": "2026-06-26T21:41:09.644Z",
3
3
  "counts": {
4
4
  "main_stdio": 25,
5
5
  "browser_agent_stdio": 20,
@@ -38,8 +38,8 @@
38
38
  ],
39
39
  "browser_agent_stdio": [
40
40
  "browser_open",
41
- "browser_profile_onboard",
42
- "browser_profile_status",
41
+ "browser_profile_connect",
42
+ "browser_profile_list",
43
43
  "browser_screenshot",
44
44
  "browser_read",
45
45
  "browser_locate",
@@ -85,8 +85,8 @@
85
85
  "rank_tracker_workflow",
86
86
  "credits_info",
87
87
  "browser_open",
88
- "browser_profile_onboard",
89
- "browser_profile_status",
88
+ "browser_profile_connect",
89
+ "browser_profile_list",
90
90
  "browser_screenshot",
91
91
  "browser_read",
92
92
  "browser_locate",
@@ -165,8 +165,8 @@
165
165
  "rank_tracker_workflow",
166
166
  "credits_info",
167
167
  "browser_open",
168
- "browser_profile_onboard",
169
- "browser_profile_status",
168
+ "browser_profile_connect",
169
+ "browser_profile_list",
170
170
  "browser_screenshot",
171
171
  "browser_read",
172
172
  "browser_locate",
@@ -971,7 +971,7 @@
971
971
  "url=\"https://example.com\"",
972
972
  "timeout_seconds=600"
973
973
  ],
974
- "negativeSpace": "Browser sessions are direct/no-proxy by default. Use browser_profile_onboard for customer login setup or reconnects; use browser_list_sessions to recover an existing session; call browser_close when done.",
974
+ "negativeSpace": "Browser sessions are direct/no-proxy by default. Use browser_profile_connect to save a login first; use browser_list_sessions to recover an existing session; call browser_close when done.",
975
975
  "producesHandlesFor": [
976
976
  "browser_screenshot",
977
977
  "browser_read",
@@ -981,7 +981,7 @@
981
981
  "consumesHandles": []
982
982
  },
983
983
  {
984
- "name": "browser_profile_onboard",
984
+ "name": "browser_profile_connect",
985
985
  "surfaces": [
986
986
  "browser_agent_stdio",
987
987
  "combined_stdio"
@@ -991,27 +991,27 @@
991
991
  "hasStructuredContent": true,
992
992
  "writesLocalFiles": false,
993
993
  "symptomTriggers": [
994
- "the user wants to set up, connect, reconnect, or refresh an authenticated hosted browser profile for future browser-agent sessions"
994
+ "the user wants to save, add, connect, reconnect, or refresh a site login (ChatGPT, Claude, Reddit, any account) so the server can reuse a logged-in browser; one profile can hold multiple logins"
995
995
  ],
996
996
  "samplePrompts": [
997
- "Connect seo@example.com for AI visibility tracking",
998
- "Reconnect this saved ChatGPT profile",
999
- "Create a logged-in hosted browser profile"
997
+ "Save my ChatGPT login",
998
+ "Connect my Reddit account",
999
+ "Add my Claude login to the same profile",
1000
+ "Reconnect this saved profile"
1000
1001
  ],
1001
1002
  "formatExamples": [
1002
- "email=\"seo@example.com\"",
1003
- "domain=\"chatgpt.com\"",
1004
- "login_url=\"https://chatgpt.com/\""
1003
+ "email=\"seo@example.com\", domain=\"chatgpt.com\"",
1004
+ "profile=\"seo-example-com\", domain=\"claude.ai\", note=\"Claude Pro\""
1005
1005
  ],
1006
- "negativeSpace": "This is the customer setup path. Provide the watch_url, let the user complete login, then call browser_profile_status until status is AUTHENTICATED. Do not ask for credentials. Auth setup is direct/no-proxy by default.",
1006
+ "negativeSpace": "This saves logins, it does not drive the browser (use browser_open) or scrape public pages (use extract_url). Provide the watch_url, let the user sign in, then poll browser_profile_list until AUTHENTICATED. Do not ask for credentials. Call again with the same profile + a new domain to stack accounts.",
1007
1007
  "producesHandlesFor": [
1008
- "browser_profile_status",
1008
+ "browser_profile_list",
1009
1009
  "browser_open"
1010
1010
  ],
1011
1011
  "consumesHandles": []
1012
1012
  },
1013
1013
  {
1014
- "name": "browser_profile_status",
1014
+ "name": "browser_profile_list",
1015
1015
  "surfaces": [
1016
1016
  "browser_agent_stdio",
1017
1017
  "combined_stdio"
@@ -1021,18 +1021,19 @@
1021
1021
  "hasStructuredContent": true,
1022
1022
  "writesLocalFiles": false,
1023
1023
  "symptomTriggers": [
1024
- "the user has completed profile login and the model needs to verify whether the hosted profile is authenticated"
1024
+ "the model needs to see which logins a profile holds, or to poll a just-saved login until it is AUTHENTICATED"
1025
1025
  ],
1026
1026
  "samplePrompts": [
1027
- "Check if the ChatGPT profile is connected",
1028
- "Did the user finish browser login?",
1029
- "Verify this saved browser profile auth status"
1027
+ "What's connected in my profile",
1028
+ "Is my ChatGPT login ready yet",
1029
+ "Which accounts are saved in this profile"
1030
1030
  ],
1031
1031
  "formatExamples": [
1032
- "connection_id from browser_profile_onboard",
1033
- "profile=\"seo-example-com-chatgpt-com\", domain=\"chatgpt.com\""
1032
+ "profile=\"seo-example-com\"",
1033
+ "profile=\"seo-example-com\", domain=\"chatgpt.com\"",
1034
+ "connection_id from browser_profile_connect"
1034
1035
  ],
1035
- "negativeSpace": "This only checks auth status; use browser_open after status is AUTHENTICATED.",
1036
+ "negativeSpace": "Read-only listing + auth-status check; use browser_open after a login reads AUTHENTICATED.",
1036
1037
  "producesHandlesFor": [
1037
1038
  "browser_open"
1038
1039
  ],
@@ -1545,7 +1546,7 @@
1545
1546
  "session_id=\"bas_...\", export=true",
1546
1547
  "session_id=\"bas_...\", prompt=\"best running shoes 2024\", first_party_domain=\"acme.com\", reset=true, export=true"
1547
1548
  ],
1548
- "negativeSpace": "Requires a logged-in chatgpt.com/claude.ai hosted session. If login is missing or stale, rerun browser_profile_onboard, wait for browser_profile_status to report AUTHENTICATED, then browser_open the saved direct/no-proxy profile. For Google AI Overview citations use harvest_paa, not this tool.",
1549
+ "negativeSpace": "Requires a logged-in chatgpt.com/claude.ai hosted session. If login is missing or stale, rerun browser_profile_connect, poll browser_profile_list until AUTHENTICATED, then browser_open the saved direct/no-proxy profile. For Google AI Overview citations use harvest_paa, not this tool.",
1549
1550
  "producesHandlesFor": [],
1550
1551
  "consumesHandles": [
1551
1552
  "browser-session-id"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-scraper",
3
- "version": "0.3.17",
3
+ "version": "0.3.19",
4
4
  "description": "MCP server for MCP Scraper web intelligence tools",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -17,8 +17,8 @@
17
17
  "paa-harvest": "dist/bin/paa-harvest.js",
18
18
  "paa-api": "dist/bin/api-server.js",
19
19
  "mcp-scraper": "dist/bin/mcp-stdio-server.js",
20
- "browser-agent": "dist/bin/browser-agent-stdio-server.js",
21
- "mcp-scraper-combined": "dist/bin/mcp-scraper-combined-stdio-server.js",
20
+ "mcp-scraper-combined": "dist/bin/mcp-stdio-server.js",
21
+ "browser-agent": "dist/bin/mcp-stdio-server.js",
22
22
  "mcp-scraper-install": "dist/bin/mcp-scraper-install.js",
23
23
  "mcp-scraper-cli": "dist/bin/mcp-scraper-cli.js"
24
24
  },