mcp-scraper 0.97.1 → 0.99.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.
Files changed (104) hide show
  1. package/CHANGELOG.md +11 -2434
  2. package/README.md +16 -412
  3. package/dist/bin/api-server.js +3 -2
  4. package/dist/bin/mcp-scraper-cli.js +33 -27
  5. package/dist/bin/mcp-scraper-core.js +9 -1
  6. package/dist/bin/mcp-scraper-install.js +17 -2
  7. package/dist/bin/mcp-stdio-server.js +9 -1
  8. package/dist/bin/paa-harvest.js +8 -1
  9. package/dist/index.cjs +5 -21830
  10. package/dist/index.d.ts +14 -607
  11. package/dist/index.js +5 -39
  12. package/dist/transport.d.ts +35 -0
  13. package/package.json +11 -51
  14. package/THIRD_PARTY_NOTICES.html +0 -203
  15. package/dist/actions-5X5CQAKO.js +0 -1
  16. package/dist/artifacts-4ZDNP2JW.js +0 -1
  17. package/dist/artifacts-N62OPIT5.js +0 -1
  18. package/dist/artifacts-PSADD5OC.js +0 -1
  19. package/dist/artifacts-RUR3OHAK.js +0 -1
  20. package/dist/blob-store-GIH26EDO.js +0 -1
  21. package/dist/bundle-GS657HXG.js +0 -1
  22. package/dist/chunk-24YDQ3EO.js +0 -5
  23. package/dist/chunk-2L7CHN5N.js +0 -4
  24. package/dist/chunk-3F7AFM53.js +0 -1
  25. package/dist/chunk-4AEW53RU.js +0 -954
  26. package/dist/chunk-4HZXATHB.js +0 -27
  27. package/dist/chunk-4YZ74SJ6.js +0 -1
  28. package/dist/chunk-4ZVO6GX4.js +0 -1
  29. package/dist/chunk-55ZANTHL.js +0 -3
  30. package/dist/chunk-5RQWFYXY.js +0 -930
  31. package/dist/chunk-5TQINRZN.js +0 -12
  32. package/dist/chunk-5UQAL7HV.js +0 -41
  33. package/dist/chunk-6D25Q5BR.js +0 -21728
  34. package/dist/chunk-6N5EC7ZO.js +0 -1
  35. package/dist/chunk-7POHNTVW.js +0 -1
  36. package/dist/chunk-7SR7MEU5.js +0 -62
  37. package/dist/chunk-ANQ4JJVI.js +0 -71
  38. package/dist/chunk-B3JRL45T.js +0 -1
  39. package/dist/chunk-B4ZKPLSP.js +0 -1
  40. package/dist/chunk-B5Y26E3A.js +0 -1
  41. package/dist/chunk-C3JWX6KM.js +0 -10
  42. package/dist/chunk-C7MGJUTU.js +0 -1
  43. package/dist/chunk-CNSVZTTT.js +0 -13
  44. package/dist/chunk-EYGA6LOU.js +0 -1
  45. package/dist/chunk-F3M7INSN.js +0 -41
  46. package/dist/chunk-FLAWC5PF.js +0 -5
  47. package/dist/chunk-FM7BX2LU.js +0 -159
  48. package/dist/chunk-HCK6PLM3.js +0 -3
  49. package/dist/chunk-HNNYXMSI.js +0 -1
  50. package/dist/chunk-IFPION5D.js +0 -121
  51. package/dist/chunk-IPQOBOFY.js +0 -1
  52. package/dist/chunk-J7XDXIB6.js +0 -163
  53. package/dist/chunk-JHDD6R3O.js +0 -8
  54. package/dist/chunk-JMZIDHYQ.js +0 -2
  55. package/dist/chunk-K3VDGJNK.js +0 -1
  56. package/dist/chunk-KBZY2OGP.js +0 -11
  57. package/dist/chunk-KJQXUZ4Y.js +0 -4
  58. package/dist/chunk-KXJCGV3H.js +0 -1
  59. package/dist/chunk-NALXKTUU.js +0 -1
  60. package/dist/chunk-NNOX3FYG.js +0 -198
  61. package/dist/chunk-NQFTETVC.js +0 -189
  62. package/dist/chunk-OILOHQNL.js +0 -2
  63. package/dist/chunk-OLYPLX5C.js +0 -1
  64. package/dist/chunk-P6CDR3RM.js +0 -1
  65. package/dist/chunk-PKQHHCO4.js +0 -20
  66. package/dist/chunk-QCBCOEH5.js +0 -1
  67. package/dist/chunk-QER2ELZP.js +0 -1
  68. package/dist/chunk-RDHGQ2WZ.js +0 -1
  69. package/dist/chunk-SDQW7IJN.js +0 -1
  70. package/dist/chunk-SEZETSB3.js +0 -1
  71. package/dist/chunk-SJNSTO3C.js +0 -42
  72. package/dist/chunk-TZYITYL4.js +0 -2
  73. package/dist/chunk-UIOSADPB.js +0 -1718
  74. package/dist/chunk-UNEJYZ4T.js +0 -102
  75. package/dist/chunk-UUJYICAJ.js +0 -1
  76. package/dist/chunk-VVSHZV5S.js +0 -73
  77. package/dist/chunk-WNUXMPVX.js +0 -1
  78. package/dist/chunk-XNTAHMPA.js +0 -218
  79. package/dist/chunk-ZDECILF6.js +0 -16
  80. package/dist/chunk-ZNPGM3XE.js +0 -4
  81. package/dist/compatibility-UPPKZ4KY.js +0 -1
  82. package/dist/contracts-GUXGFCVV.js +0 -1
  83. package/dist/core-schema-Y47YFKH2.js +0 -899
  84. package/dist/direct-completion-ZVPPEBDU.js +0 -1
  85. package/dist/dispatch-GRMMPKQD.js +0 -1
  86. package/dist/editorial-reading-room/assets/app.js +0 -433
  87. package/dist/editorial-reading-room/assets/index.html +0 -139
  88. package/dist/editorial-reading-room/assets/styles.css +0 -1091
  89. package/dist/index.d.cts +0 -607
  90. package/dist/jobs-NRZHGQ7I.js +0 -1
  91. package/dist/media-artifacts-67CJWI7O.js +0 -1
  92. package/dist/metering-YHZ46GV4.js +0 -1
  93. package/dist/migrations-3AKEC5QE.js +0 -1
  94. package/dist/queue-2VKW7SGH.js +0 -1
  95. package/dist/reconciliation-QC6SILLR.js +0 -1
  96. package/dist/report-artifact-offload-PQNFDNPL.js +0 -1
  97. package/dist/repository-CYXVMYAI.js +0 -1
  98. package/dist/repository-UKDA4IWP.js +0 -1
  99. package/dist/server-EYMJROPX.js +0 -5544
  100. package/dist/settlement-47EUTSGX.js +0 -1
  101. package/dist/vendor-errors-647LSH6H.js +0 -1
  102. package/dist/worker-AWJF7UYR.js +0 -1
  103. package/public/.well-known/xray-install.json +0 -183
  104. package/public/agent-install.md +0 -200
@@ -1,102 +0,0 @@
1
- import{a as N}from"./chunk-WNUXMPVX.js";import{b as O}from"./chunk-KJQXUZ4Y.js";import{createHash as M,randomUUID as z}from"crypto";var D="us_zip_groups",K="us_census_places",P=25e3,k=["AL","AK","AZ","AR","CA","CO","CT","DE","DC","FL","GA","HI","ID","IL","IN","IA","KS","KY","LA","ME","MD","MA","MI","MN","MS","MO","MT","NE","NV","NH","NJ","NM","NY","NC","ND","OH","OK","OR","PA","RI","SC","SD","TN","TX","UT","VT","VA","WA","WV","WI","WY"],$={AL:"01",AK:"02",AZ:"04",AR:"05",CA:"06",CO:"08",CT:"09",DE:"10",DC:"11",FL:"12",GA:"13",HI:"15",ID:"16",IL:"17",IN:"18",IA:"19",KS:"20",KY:"21",LA:"22",ME:"23",MD:"24",MA:"25",MI:"26",MN:"27",MS:"28",MO:"29",MT:"30",NE:"31",NV:"32",NH:"33",NJ:"34",NM:"35",NY:"36",NC:"37",ND:"38",OH:"39",OK:"40",OR:"41",PA:"42",RI:"44",SC:"45",SD:"46",TN:"47",TX:"48",UT:"49",VT:"50",VA:"51",WA:"53",WV:"54",WI:"55",WY:"56"},x=new Set(k),A=200,H=2e3,v=null,w=null;function b(t){return t.toLowerCase().replace(/[^a-z0-9]+/g," ").trim()}function Y(t){if(t==null)return[];try{let o=JSON.parse(String(t));return Array.isArray(o)?o.map(String):[]}catch{return[]}}function C(t){return{id:String(t.id),kind:String(t.dataset_kind),sourceUrl:t.source_url==null?null:String(t.source_url),sha256:String(t.sha256),rowCount:Number(t.row_count??0),groupCount:Number(t.group_count??0),stateCount:Number(t.state_count??0),sourceRowCount:Number(t.source_row_count??t.row_count??0),rejectedRowCount:Number(t.rejected_row_count??0),zipCount:Number(t.zip_count??0),coveredStates:Y(t.covered_states_json),coverageComplete:Number(t.coverage_complete??0)===1,status:String(t.status),createdAt:String(t.created_at),completedAt:t.completed_at==null?null:String(t.completed_at),error:t.error==null?null:String(t.error)}}function F(t){return`${K}:${t}`}function X(t){let o=t?.trim();if(!o)return null;if(o.length>H)throw new Error(`sourceUrl must be ${H} characters or fewer`);let a;try{a=new URL(o)}catch{throw new Error("sourceUrl must be a valid URL")}return a.username="",a.password="",a.search="",a.hash="",a.toString()}function q(t){let o=t.trim();return/^\d{1,5}$/.test(o)?o.padStart(5,"0"):null}function f(t){let o=t.trim().toUpperCase();return x.has(o)?o:null}function y(t,o){for(let a of o){let r=t[a];if(r!==void 0)return r}return""}function g(t){if(t===void 0||t.trim()==="")return null;let o=Number(t);return Number.isFinite(o)&&o>=0?Math.trunc(o):null}function V(t){return/^Nashville-Davidson metropolitan government/i.test(t)?"Nashville":t.replace(/\s+(city|town|village|municipality|borough)$/i,"").trim()}function B(t,o){let a=O(t.replace(/^\uFEFF/,""));if(a.length===0)throw new Error("Census place CSV contains no data rows.");let r=new Set(Object.keys(a[0]??{}).map(e=>e.trim())),u=["SUMLEV","STATE","NAME","POPESTIMATE2020","POPESTIMATE2021","POPESTIMATE2022","POPESTIMATE2023","POPESTIMATE2024","POPESTIMATE2025"].filter(e=>!r.has(e));if(u.length>0)throw new Error(`Census place CSV is missing required columns: ${u.join(", ")}.`);let d=a.filter(e=>e.SUMLEV?.trim()==="162");if(o){let e=o.padStart(2,"0"),s=d.filter(l=>l.STATE?.trim().padStart(2,"0")!==e);if(s.length>0){let l=[...new Set(s.map(c=>c.STATE?.trim()||"(blank)"))].slice(0,5);throw new Error(`Census place CSV STATE does not match requested FIPS ${e}; received ${l.join(", ")}.`)}}let E=d.map(e=>{let s=e.NAME?.trim()??"";if(!s)return null;let l=V(s),c=b(l);if(!c)return null;let T={2020:g(e.POPESTIMATE2020),2021:g(e.POPESTIMATE2021),2022:g(e.POPESTIMATE2022),2023:g(e.POPESTIMATE2023),2024:g(e.POPESTIMATE2024),2025:g(e.POPESTIMATE2025)};return Object.values(T).every(m=>m===null)?null:{city:l,cityKey:c,censusName:s,estimatesBase2020:g(e.ESTIMATESBASE2020),populations:T}}).filter(e=>e!==null),p=new Map,i=e=>e.populations[2025]??e.populations[2024]??e.populations[2023]??e.populations[2022]??e.populations[2021]??e.populations[2020]??e.estimatesBase2020??-1;for(let e of E){let s=p.get(e.cityKey);(!s||i(e)>i(s)||i(e)===i(s)&&e.censusName.localeCompare(s.censusName)<0)&&p.set(e.cityKey,e)}let _=[...p.values()].sort((e,s)=>e.city.localeCompare(s.city));if(_.length===0)throw new Error("Census place CSV did not contain any valid place population rows.");return{sourceRowCount:a.length,places:_}}function W(t){let o=O(t.replace(/^\uFEFF/,""));if(o.length===0)throw new Error("Location ZIP CSV contains no data rows.");let a=o[0]??{},r=new Set(Object.keys(a).map(s=>s.trim().toLowerCase())),n=["state_abbr","state","state_id"].some(s=>r.has(s)),u=["city","primary_city"].some(s=>r.has(s)),d=["zipcode","zip","zip_code"].some(s=>r.has(s));if(!n||!u||!d)throw new Error("Location ZIP CSV must include state_abbr/state, city, and zipcode/zip columns.");let E=new Map,p=0,i=0,_=new Set,e=new Set;for(let s of o){let l=Object.fromEntries(Object.entries(s).map(([G,j])=>[G.trim().toLowerCase(),j])),c=f(y(l,["state_abbr","state","state_id"])),T=y(l,["city","primary_city"]).trim(),m=q(y(l,["zipcode","zip","zip_code"])),S=y(l,["county","county_name"]).trim();if(!c||!x.has(c)||!T||!m){i+=1;continue}let I=b(T);if(!I){i+=1;continue}let U=`${c}\0${I}`,L=E.get(U);L||(L={city:T,cityKey:I,state:c,zips:new Set,counties:new Set},E.set(U,L)),L.zips.add(m),S&&L.counties.add(S),_.add(c),e.add(m),p+=1}if(E.size===0)throw new Error("Location ZIP CSV did not contain any valid US city/ZIP rows.");return{sourceRowCount:o.length,rowCount:p,rejectedRowCount:i,zipCount:e.size,stateCount:_.size,coveredStates:[..._].sort(),groups:[...E.values()].map(s=>({city:s.city,cityKey:s.cityKey,state:s.state,zips:[...s.zips].sort(),counties:[...s.counties].sort()})).sort((s,l)=>s.state.localeCompare(l.state)||s.city.localeCompare(l.city))}}function J(t){let o=new Set(t.coveredStates),a=k.filter(n=>!o.has(n)),r=[];if(a.length>0&&r.push(`missing required states: ${a.join(", ")}`),t.zipCount<P&&r.push(`only ${t.zipCount} unique ZIPs; at least ${P} are required`),r.length>0)throw new Error(`Location ZIP snapshot is not nationwide and was not activated (${r.join("; ")}; ${t.rejectedRowCount} rejected rows).`)}async function R(){let t=N();v!==t&&(v=t,w=null),w||(w=(async()=>{await t.execute(`
2
- CREATE TABLE IF NOT EXISTS location_data_imports (
3
- id TEXT PRIMARY KEY,
4
- dataset_kind TEXT NOT NULL,
5
- source_url TEXT,
6
- sha256 TEXT NOT NULL,
7
- row_count INTEGER NOT NULL DEFAULT 0,
8
- group_count INTEGER NOT NULL DEFAULT 0,
9
- state_count INTEGER NOT NULL DEFAULT 0,
10
- source_row_count INTEGER NOT NULL DEFAULT 0,
11
- rejected_row_count INTEGER NOT NULL DEFAULT 0,
12
- zip_count INTEGER NOT NULL DEFAULT 0,
13
- covered_states_json TEXT NOT NULL DEFAULT '[]',
14
- coverage_complete INTEGER NOT NULL DEFAULT 0,
15
- status TEXT NOT NULL,
16
- error TEXT,
17
- created_at TEXT NOT NULL DEFAULT (datetime('now')),
18
- completed_at TEXT
19
- )
20
- `);let o=new Set((await t.execute("PRAGMA table_info(location_data_imports)")).rows.map(r=>String(r.name))),a=[["source_row_count","INTEGER NOT NULL DEFAULT 0"],["rejected_row_count","INTEGER NOT NULL DEFAULT 0"],["zip_count","INTEGER NOT NULL DEFAULT 0"],["covered_states_json","TEXT NOT NULL DEFAULT '[]'"],["coverage_complete","INTEGER NOT NULL DEFAULT 0"]];for(let[r,n]of a)o.has(r)||await t.execute(`ALTER TABLE location_data_imports ADD COLUMN ${r} ${n}`);await t.execute("CREATE INDEX IF NOT EXISTS location_data_imports_kind_created ON location_data_imports(dataset_kind, created_at DESC)"),await t.execute(`
21
- CREATE TABLE IF NOT EXISTS location_zip_groups (
22
- import_id TEXT NOT NULL REFERENCES location_data_imports(id) ON DELETE CASCADE,
23
- state_abbr TEXT NOT NULL,
24
- city_key TEXT NOT NULL,
25
- city TEXT NOT NULL,
26
- zips_json TEXT NOT NULL,
27
- counties_json TEXT NOT NULL,
28
- PRIMARY KEY(import_id, state_abbr, city_key)
29
- )
30
- `),await t.execute("CREATE INDEX IF NOT EXISTS location_zip_groups_state ON location_zip_groups(import_id, state_abbr, city_key)"),await t.execute(`
31
- CREATE TABLE IF NOT EXISTS location_census_places (
32
- import_id TEXT NOT NULL REFERENCES location_data_imports(id) ON DELETE CASCADE,
33
- state_abbr TEXT NOT NULL,
34
- city_key TEXT NOT NULL,
35
- city TEXT NOT NULL,
36
- census_name TEXT NOT NULL,
37
- estimates_base_2020 INTEGER,
38
- population_2020 INTEGER,
39
- population_2021 INTEGER,
40
- population_2022 INTEGER,
41
- population_2023 INTEGER,
42
- population_2024 INTEGER,
43
- population_2025 INTEGER,
44
- PRIMARY KEY(import_id, state_abbr, city_key)
45
- )
46
- `),await t.execute("CREATE INDEX IF NOT EXISTS location_census_places_state ON location_census_places(import_id, state_abbr, city_key)"),await t.execute(`
47
- CREATE TABLE IF NOT EXISTS location_data_active (
48
- dataset_kind TEXT PRIMARY KEY,
49
- import_id TEXT NOT NULL REFERENCES location_data_imports(id),
50
- activated_at TEXT NOT NULL DEFAULT (datetime('now'))
51
- )
52
- `)})().catch(o=>{throw w=null,o})),await w}async function h(t){await R();let a=(await N().execute({sql:`
53
- SELECT i.*
54
- FROM location_data_active a
55
- JOIN location_data_imports i ON i.id = a.import_id
56
- WHERE a.dataset_kind = ? AND i.status = 'ready'
57
- LIMIT 1
58
- `,args:[t]})).rows[0];return a?C(a):null}async function Z(){return h(D)}async function st(){return await R(),(await N().execute(`
59
- SELECT i.*
60
- FROM location_data_active a
61
- JOIN location_data_imports i ON i.id = a.import_id
62
- WHERE i.status = 'ready'
63
- ORDER BY i.dataset_kind ASC
64
- `)).rows.map(o=>C(o))}async function Q(t){let o=f(t);if(!o)throw new Error("state must be a two-letter US state abbreviation");let a=await Z();if(!a)return{dataset:null,groups:new Map};let r=await N().execute({sql:`
65
- SELECT city, city_key, state_abbr, zips_json, counties_json
66
- FROM location_zip_groups
67
- WHERE import_id = ? AND state_abbr = ?
68
- ORDER BY city COLLATE NOCASE ASC
69
- `,args:[a.id,o]}),n=new Map;for(let u of r.rows){let d=String(u.city_key);n.set(d,{city:String(u.city),cityKey:d,state:String(u.state_abbr),zips:JSON.parse(String(u.zips_json)),counties:JSON.parse(String(u.counties_json))})}return{dataset:a,groups:n}}async function at(t){await R();let o=X(t.sourceUrl),a=M("sha256").update(t.csv).digest("hex"),r=await Z();if(r?.sha256===a)return{dataset:r,duplicate:!0};let n=W(t.csv);J(n);let u=`loc_${z().replaceAll("-","")}`,d=N();await d.execute({sql:`
70
- INSERT INTO location_data_imports (
71
- id, dataset_kind, source_url, sha256, row_count, group_count, state_count,
72
- source_row_count, rejected_row_count, zip_count, covered_states_json, coverage_complete, status
73
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, 'loading')
74
- `,args:[u,D,o,a,n.rowCount,n.groups.length,n.stateCount,n.sourceRowCount,n.rejectedRowCount,n.zipCount,JSON.stringify(n.coveredStates)]});try{for(let i=0;i<n.groups.length;i+=A){let _=n.groups.slice(i,i+A).map(e=>({sql:`
75
- INSERT INTO location_zip_groups (
76
- import_id, state_abbr, city_key, city, zips_json, counties_json
77
- ) VALUES (?, ?, ?, ?, ?, ?)
78
- `,args:[u,e.state,e.cityKey,e.city,JSON.stringify(e.zips),JSON.stringify(e.counties)]}));await d.batch(_,"write")}await d.batch([{sql:"UPDATE location_data_imports SET status = 'ready', completed_at = datetime('now'), error = NULL WHERE id = ? AND status = 'loading'",args:[u]},{sql:`
79
- INSERT INTO location_data_active (dataset_kind, import_id, activated_at)
80
- VALUES (?, ?, datetime('now'))
81
- ON CONFLICT(dataset_kind) DO UPDATE SET import_id = excluded.import_id, activated_at = excluded.activated_at
82
- `,args:[D,u]}],"write")}catch(i){let _=i instanceof Error?i.message:String(i);throw await d.execute({sql:"UPDATE location_data_imports SET status = 'failed', error = ?, completed_at = datetime('now') WHERE id = ?",args:[_.slice(0,1e3),u]}).catch(()=>{}),i}let p=(await d.execute({sql:"SELECT * FROM location_data_imports WHERE id = ? LIMIT 1",args:[u]})).rows[0];if(!p)throw new Error("Hosted location import completed without a durable metadata row.");return{dataset:C(p),duplicate:!1}}async function nt(t){await R();let o=f(t.state);if(!o)throw new Error("state must be a two-letter US state abbreviation");let a=F(o),r=X(t.sourceUrl),n=M("sha256").update(t.csv).digest("hex"),u=await h(a);if(u?.sha256===n)return{dataset:u,duplicate:!0};let d=$[o],E=B(t.csv,d),p=`loc_${z().replaceAll("-","")}`,i=N();await i.execute({sql:`
83
- INSERT INTO location_data_imports (
84
- id, dataset_kind, source_url, sha256, row_count, group_count, state_count,
85
- source_row_count, rejected_row_count, zip_count, covered_states_json, coverage_complete, status
86
- ) VALUES (?, ?, ?, ?, ?, ?, 1, ?, 0, 0, ?, 1, 'loading')
87
- `,args:[p,a,r,n,E.places.length,E.places.length,E.sourceRowCount,JSON.stringify([o])]});try{for(let s=0;s<E.places.length;s+=A){let l=E.places.slice(s,s+A).map(c=>({sql:`
88
- INSERT INTO location_census_places (
89
- import_id, state_abbr, city_key, city, census_name, estimates_base_2020,
90
- population_2020, population_2021, population_2022, population_2023,
91
- population_2024, population_2025
92
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
93
- `,args:[p,o,c.cityKey,c.city,c.censusName,c.estimatesBase2020,c.populations[2020],c.populations[2021],c.populations[2022],c.populations[2023],c.populations[2024],c.populations[2025]]}));await i.batch(l,"write")}await i.batch([{sql:"UPDATE location_data_imports SET status = 'ready', completed_at = datetime('now'), error = NULL WHERE id = ? AND status = 'loading'",args:[p]},{sql:`
94
- INSERT INTO location_data_active (dataset_kind, import_id, activated_at)
95
- VALUES (?, ?, datetime('now'))
96
- ON CONFLICT(dataset_kind) DO UPDATE SET import_id = excluded.import_id, activated_at = excluded.activated_at
97
- `,args:[a,p]}],"write")}catch(s){let l=s instanceof Error?s.message:String(s);throw await i.execute({sql:"UPDATE location_data_imports SET status = 'failed', error = ?, completed_at = datetime('now') WHERE id = ?",args:[l.slice(0,1e3),p]}).catch(()=>{}),s}let e=(await i.execute({sql:"SELECT * FROM location_data_imports WHERE id = ? LIMIT 1",args:[p]})).rows[0];if(!e)throw new Error("Hosted Census import completed without a durable metadata row.");return{dataset:C(e),duplicate:!1}}async function it(t){let o=f(t.state);if(!o)throw new Error("state must be a two-letter US state abbreviation");if(!Number.isSafeInteger(t.minPopulation)||t.minPopulation<0)throw new Error("minPopulation must be a non-negative integer");if(!Number.isSafeInteger(t.maxResults)||t.maxResults<1||t.maxResults>100)throw new Error("maxResults must be between 1 and 100");let a=await h(F(o)),n=t.includeZipGroups||!!t.zip?await Q(o):{dataset:null,groups:new Map};if(!a)return{markets:[],populationDataset:null,zipDataset:n.dataset,warnings:[]};let u=await N().execute({sql:`
98
- SELECT *
99
- FROM location_census_places
100
- WHERE import_id = ? AND state_abbr = ?
101
- ORDER BY city COLLATE NOCASE ASC
102
- `,args:[a.id,o]}),d=b(t.cityQuery??""),E=t.zip?.trim(),p=`population_${t.populationYear}`,i=u.rows.map(e=>{let s=e[p];if(s==null)return null;let l=Number(s);if(!Number.isSafeInteger(l)||l<t.minPopulation)return null;let c=String(e.city),T=String(e.city_key);if(d&&!T.includes(d))return null;let m=n.groups.get(T),S=m?.zips??[];return E&&!S.includes(E)?null:{city:c,state:o,location:`${c}, ${o}`,cityKey:`${c}|${o}`,censusName:String(e.census_name),population:l,populationYear:t.populationYear,estimatesBase2020:e.estimates_base_2020==null?null:Number(e.estimates_base_2020),zips:t.includeZipGroups?S:[],counties:t.includeZipGroups?m?.counties??[]:[]}}).filter(e=>e!==null).sort((e,s)=>s.population-e.population||e.city.localeCompare(s.city)).slice(0,t.maxResults),_=[];return t.includeZipGroups&&n.dataset&&i.some(e=>e.zips.length===0)&&_.push("Some hosted Census places did not match the hosted ZIP city groups."),{markets:i,populationDataset:a,zipDataset:n.dataset,warnings:_}}export{D as a,K as b,P as c,k as d,B as e,W as f,R as g,h,Z as i,st as j,Q as k,at as l,nt as m,it as n};
@@ -1 +0,0 @@
1
- import{g as u,j as f,k as d,l as h,m as b,n as x}from"./chunk-NQFTETVC.js";import{h as w}from"./chunk-ANQ4JJVI.js";import{i as p}from"./chunk-C7MGJUTU.js";import{randomUUID as R}from"crypto";import{waitUntil as y}from"@vercel/functions";var c=class extends Error{constructor(){super("runtime_workflow_yield"),this.name="RuntimeWorkflowYield"}};function D(r){let t=Promise.resolve().then(r).catch(e=>{console.error("[runtime-job] execution failed",e instanceof Error?e.name:"UnknownError")});y(t)}async function J(r){let t=`runtime:${R()}`,e=Date.now()+(r.budgetMs??75e4),n={run:(o,i)=>i(),async checkpoint(o,i=33e4){if(!(e-Date.now()>=i))throw await w(o)?new c:Error("runtime_workflow_pause_not_admitted")}};try{return await r.execute({jobId:r.jobId,runId:t,step:n}),"completed"}catch(o){return o instanceof c?"deferred":(await r.onFailure({jobId:r.jobId,runId:t,error:o}),"failed")}}async function l(r,t){let e=process.env.CRON_SECRET?.trim();if(!e)throw Error("runtime_job_dispatch_not_configured");let n=(process.env.APP_URL??process.env.APP_ORIGIN??"https://mcpscraper.dev").replace(/\/$/,""),o=await fetch(`${n}/internal/jobs/run`,{method:"POST",headers:{authorization:`Bearer ${e}`,"content-type":"application/json"},body:JSON.stringify({kind:r,jobId:t}),signal:AbortSignal.timeout(1e4)});if(o.status!==202)throw Error(`runtime_job_dispatch_failed:${o.status}`)}function E(r){return Math.min(3600,Math.max(15,15*2**Math.min(8,Math.max(0,r-1))))}async function k(r){let t={claimed:r.rows.length,dispatched:0,failed:0},e=()=>{t.unknown=(t.unknown??0)+1},n=async o=>{let i=await r.read(o).catch(()=>null);return i?.id===o.id?i:null};for(let o of r.rows){let i=o.claimToken;if(!i||!await r.isCurrent(o,i).catch(()=>!1)){e();continue}try{await r.send(o)}catch(a){let m=(a instanceof Error?a.message:String(a)).slice(0,2e3);if(await r.retainRetry(o,i,m,E(o.attempts)).catch(async()=>{let s=await n(o);return s?.status==="failed"&&s.lastError===m}))t.failed+=1;else{let s=await n(o);s?.status==="dispatched"&&s.dispatchedAt?t.dispatched+=1:e()}continue}if(await r.acknowledge(o,i).catch(()=>!1))t.dispatched+=1;else{let a=await n(o);a?.status==="dispatched"&&a.dispatchedAt?t.dispatched+=1:e()}}return t}async function g(r){return k({rows:r,isCurrent:(t,e)=>h(t.id,e),send:async t=>{try{return await l("site_extract",t.id)}catch(e){throw Error(p(e instanceof Error?e.message:String(e)).slice(0,2e3))}},acknowledge:(t,e)=>b(t.id,e),retainRetry:(t,e,n,o)=>x(t.id,e,n,o),read:async t=>{let e=await u(t.id);return e?{id:e.id,status:e.dispatchedAt?"dispatched":e.dispatchClaimToken?"dispatching":e.dispatchError?"failed":"pending",dispatchedAt:e.dispatchedAt??null,lastError:e.dispatchError??null}:null}})}async function M(r){if((await u(r))?.dispatchedAt)return{claimed:0,dispatched:1,failed:0};let e=await d({jobId:r});return e.length?g(e):{claimed:0,dispatched:0,failed:0,unknown:1}}async function F(r=25){let t=await g(await d({limit:r})),e=await f(r);for(let n of e){t.claimed+=1;try{await l("site_extract",n.id),t.dispatched+=1}catch(o){t.failed+=1,console.warn("[site-extract/resume]",n.id,o instanceof Error?o.message:String(o))}}return{checked:t.claimed,dispatched:t.dispatched,failed:t.failed,...t.unknown?{unknown:t.unknown}:{}}}export{c as a,D as b,J as c,l as d,k as e,M as f,F as g};
@@ -1,73 +0,0 @@
1
- import{c as l}from"./chunk-4ZVO6GX4.js";import{a as _}from"./chunk-WNUXMPVX.js";var c=166667e-10,S="owner_confirmed_2026-10-12";var N=.00111,L=4,p=4e-4;function o(e,t){let r=process.env[e]?.trim();if(!r)return t;let s=Number(r);return Number.isFinite(s)&&s>=0?s:t}var R=o("NANGO_USD_PER_CONNECTION_MONTH",1),A=o("NANGO_USD_PER_FUNCTION_RUN",1e-4),U=o("NANGO_USD_PER_PROXY_REQUEST",1e-4),m=o("NANGO_USD_PER_COMPUTE_SEC",2e-4),g=o("\u0042\u0052\u0049\u0047\u0048\u0054\u0044\u0041\u0054\u0041_BROWSER_USD_PER_GB",8),D=o("\u0042\u0052\u0049\u0047\u0048\u0054\u0044\u0041\u0054\u0041_SERP_USD_PER_REQUEST",.002836168);function u(e,t){return Math.max(0,e)/1e3*c}function d(e,t){return e==="fal_wizper"?Math.max(0,t)/L*N:e==="deepinfra_qwen"?Math.max(0,t)/1e3*p:e==="openrouter"||e==="mcp_memory_video"||e==="mcp_memory_ai"?Math.max(0,t):e==="nango_connection"?Math.max(0,t)*R:e==="nango_function_run"?Math.max(0,t)*A:e==="nango_proxy_request"?Math.max(0,t)*U:e==="nango_compute"?Math.max(0,t)*m:e==="\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061_browser_api"?Math.max(0,t)/1e9*g:0}import{randomUUID as i}from"crypto";var E=!1,n=null;async function T(){if(!E)return n||(n=O().finally(()=>{n=null}),n)}async function O(){let e=_(),t=await e.execute(`
2
- SELECT
3
- (SELECT COUNT(*) FROM sqlite_master WHERE type = 'table' AND name IN ('\u006b\u0065\u0072\u006e\u0065\u006c_session_log', 'vendor_usage_log', 'cost_probe_runs')) = 3
4
- AND (SELECT COUNT(*) FROM pragma_table_info('\u006b\u0065\u0072\u006e\u0065\u006c_session_log') WHERE name IN ('proxy_source', 'proxy_type', 'method')) = 3
5
- AND (SELECT COUNT(*) FROM pragma_table_info('vendor_usage_log') WHERE name IN ('method', 'source_key', 'provider_duration_ms', 'provider_captcha', 'provider_status')) = 5
6
- AND (SELECT COUNT(*) FROM sqlite_master WHERE type = 'index' AND name = 'vendor_usage_log_vendor_source_key') = 1
7
- AND (SELECT COUNT(*) FROM pragma_table_info('cost_probe_runs') WHERE name IN ('units', 'unit_type', 'mode')) = 3
8
- AS ready
9
- `);if(Number(t.rows[0]?.ready??0)===1){E=!0;return}await e.execute(`
10
- CREATE TABLE IF NOT EXISTS \u006b\u0065\u0072\u006e\u0065\u006c_session_log (
11
- id TEXT PRIMARY KEY,
12
- \u006b\u0065\u0072\u006e\u0065\u006c_session_id TEXT,
13
- op TEXT,
14
- source TEXT NOT NULL,
15
- probe_run_id TEXT,
16
- user_id INTEGER,
17
- stealth INTEGER,
18
- headless_sent INTEGER,
19
- proxy_used INTEGER,
20
- fallback INTEGER NOT NULL DEFAULT 0,
21
- opened_at TEXT,
22
- closed_at TEXT,
23
- duration_ms INTEGER NOT NULL DEFAULT 0,
24
- est_cost_usd_headless REAL NOT NULL DEFAULT 0,
25
- est_cost_usd_headful REAL NOT NULL DEFAULT 0,
26
- error TEXT,
27
- created_at TEXT NOT NULL DEFAULT (datetime('now'))
28
- )
29
- `),await e.execute("CREATE INDEX IF NOT EXISTS \u006b\u0065\u0072\u006e\u0065\u006c_session_log_op ON \u006b\u0065\u0072\u006e\u0065\u006c_session_log(op)"),await e.execute("CREATE INDEX IF NOT EXISTS \u006b\u0065\u0072\u006e\u0065\u006c_session_log_probe ON \u006b\u0065\u0072\u006e\u0065\u006c_session_log(probe_run_id)"),await e.execute("CREATE INDEX IF NOT EXISTS \u006b\u0065\u0072\u006e\u0065\u006c_session_log_created ON \u006b\u0065\u0072\u006e\u0065\u006c_session_log(created_at)");try{await e.execute("ALTER TABLE \u006b\u0065\u0072\u006e\u0065\u006c_session_log ADD COLUMN proxy_source TEXT")}catch{}try{await e.execute("ALTER TABLE \u006b\u0065\u0072\u006e\u0065\u006c_session_log ADD COLUMN proxy_type TEXT")}catch{}try{await e.execute("ALTER TABLE \u006b\u0065\u0072\u006e\u0065\u006c_session_log ADD COLUMN method TEXT")}catch{}await e.execute(`
30
- CREATE TABLE IF NOT EXISTS vendor_usage_log (
31
- id TEXT PRIMARY KEY,
32
- op TEXT,
33
- probe_run_id TEXT,
34
- user_id INTEGER,
35
- vendor TEXT NOT NULL,
36
- model TEXT,
37
- units REAL NOT NULL DEFAULT 0,
38
- unit_type TEXT,
39
- est_cost_usd REAL NOT NULL DEFAULT 0,
40
- error TEXT,
41
- source_key TEXT,
42
- provider_duration_ms INTEGER,
43
- provider_captcha INTEGER,
44
- provider_status TEXT,
45
- created_at TEXT NOT NULL DEFAULT (datetime('now'))
46
- )
47
- `),await e.execute("CREATE INDEX IF NOT EXISTS vendor_usage_log_op ON vendor_usage_log(op)"),await e.execute("CREATE INDEX IF NOT EXISTS vendor_usage_log_probe ON vendor_usage_log(probe_run_id)"),await e.execute("CREATE INDEX IF NOT EXISTS vendor_usage_log_created ON vendor_usage_log(created_at)");try{await e.execute("ALTER TABLE vendor_usage_log ADD COLUMN method TEXT")}catch{}try{await e.execute("ALTER TABLE vendor_usage_log ADD COLUMN source_key TEXT")}catch{}try{await e.execute("ALTER TABLE vendor_usage_log ADD COLUMN provider_duration_ms INTEGER")}catch{}try{await e.execute("ALTER TABLE vendor_usage_log ADD COLUMN provider_captcha INTEGER")}catch{}try{await e.execute("ALTER TABLE vendor_usage_log ADD COLUMN provider_status TEXT")}catch{}await e.execute("CREATE UNIQUE INDEX IF NOT EXISTS vendor_usage_log_vendor_source_key ON vendor_usage_log(vendor, source_key) WHERE source_key IS NOT NULL"),await e.execute(`
48
- CREATE TABLE IF NOT EXISTS cost_probe_runs (
49
- id TEXT PRIMARY KEY,
50
- tool TEXT NOT NULL,
51
- target TEXT,
52
- started_at TEXT NOT NULL DEFAULT (datetime('now')),
53
- wall_ms INTEGER NOT NULL DEFAULT 0,
54
- success INTEGER NOT NULL DEFAULT 0,
55
- error TEXT,
56
- http_only INTEGER NOT NULL DEFAULT 0,
57
- \u006b\u0065\u0072\u006e\u0065\u006c_used INTEGER NOT NULL DEFAULT 0,
58
- \u006b\u0065\u0072\u006e\u0065\u006c_sessions INTEGER NOT NULL DEFAULT 0,
59
- \u006b\u0065\u0072\u006e\u0065\u006c_seconds_total REAL NOT NULL DEFAULT 0,
60
- \u006b\u0065\u0072\u006e\u0065\u006c_tier_observed TEXT,
61
- est_\u006b\u0065\u0072\u006e\u0065\u006c_cost_usd_headless REAL NOT NULL DEFAULT 0,
62
- est_\u006b\u0065\u0072\u006e\u0065\u006c_cost_usd_headful REAL NOT NULL DEFAULT 0,
63
- vendor_cost_usd REAL NOT NULL DEFAULT 0,
64
- charged_credits REAL NOT NULL DEFAULT 0,
65
- margin_usd_headless_starter REAL NOT NULL DEFAULT 0,
66
- margin_usd_headful_starter REAL NOT NULL DEFAULT 0,
67
- notes TEXT
68
- )
69
- `),await e.execute("CREATE INDEX IF NOT EXISTS cost_probe_runs_tool ON cost_probe_runs(tool)");try{await e.execute("ALTER TABLE cost_probe_runs ADD COLUMN units REAL")}catch{}try{await e.execute("ALTER TABLE cost_probe_runs ADD COLUMN unit_type TEXT")}catch{}try{await e.execute("ALTER TABLE cost_probe_runs ADD COLUMN mode TEXT")}catch{}E=!0}async function h(e){try{await T();let t=l(),r=Math.max(0,e.closedAtMs-e.openedAtMs);await _().execute({sql:`INSERT INTO \u006b\u0065\u0072\u006e\u0065\u006c_session_log
70
- (id, \u006b\u0065\u0072\u006e\u0065\u006c_session_id, op, source, probe_run_id, user_id, stealth, headless_sent, proxy_used, proxy_source, proxy_type, fallback, opened_at, closed_at, duration_ms, est_cost_usd_headless, est_cost_usd_headful, error, method)
71
- VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`,args:[i(),e.\u006b\u0065\u0072\u006e\u0065\u006cSessionId??null,t?.op??null,e.source,t?.probeRunId??null,t?.userId??null,a(e.stealth),a(e.headlessSent),a(e.proxyUsed),e.proxySource??null,e.proxyType??null,e.fallback?1:0,new Date(e.openedAtMs).toISOString(),new Date(e.closedAtMs).toISOString(),r,u(r,!1),u(r,!0),e.error??null,t?.subOp??null]})}catch(t){console.warn("[cost-telemetry] record\u004b\u0065\u0072\u006e\u0065\u006cSession failed:",t instanceof Error?t.message:String(t))}}async function f(e){try{await T();let t=l();return(await _().execute({sql:`INSERT OR IGNORE INTO vendor_usage_log
72
- (id, op, probe_run_id, user_id, vendor, model, units, unit_type, est_cost_usd, error, method, source_key, provider_duration_ms, provider_captcha, provider_status)
73
- VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`,args:[i(),e.op??t?.op??null,e.probeRunId??t?.probeRunId??null,e.userId??t?.userId??null,e.vendor,e.model??null,e.units,e.unitType,d(e.vendor,e.units),e.error??null,e.method??t?.subOp??null,e.sourceKey??null,e.providerDurationMs??null,a(e.providerCaptcha),e.providerStatus??null]})).rowsAffected===1}catch(t){return console.warn("[cost-telemetry] recordVendorUsage failed:",t instanceof Error?t.message:String(t)),!1}}function a(e){return e==null?null:e?1:0}export{c as a,S as b,u as c,d,T as e,h as f,f as g};
@@ -1 +0,0 @@
1
- import{createClient as t}from"@libsql/client/http";var n=process.env.TURSO_DATABASE_URL??"file:./paa-api.db",l=process.env.TURSO_AUTH_TOKEN,e=null;function o(){return e||(e=t({url:n,authToken:l})),e}export{o as a};
@@ -1,218 +0,0 @@
1
- import{a as _,b as N,c as I}from"./chunk-JHDD6R3O.js";import{a as u}from"./chunk-WNUXMPVX.js";var y="2026-06-26 21:58:03";var k="+3 months";function D(t){return{sql:`INSERT INTO credit_lots (user_id, amount_mc, remaining_mc, source, expires_at)
2
- SELECT ?, legacy.balance_mc, legacy.balance_mc, 'migration', datetime('now', ?)
3
- FROM (
4
- SELECT COALESCE(SUM(amount_mc), 0) AS balance_mc
5
- FROM ledger
6
- WHERE user_id = ?
7
- ) AS legacy
8
- WHERE legacy.balance_mc > 0
9
- AND EXISTS (
10
- SELECT 1 FROM ledger
11
- WHERE user_id = ? AND created_at < ?
12
- )
13
- AND NOT EXISTS (
14
- SELECT 1 FROM credit_lots WHERE user_id = ?
15
- )`,args:[t,k,t,t,y,t]}}async function O(t){return(await u().execute(D(t))).rowsAffected}import{createHash as T,randomUUID as A}from"crypto";var R="(CAST(strftime('%s', 'now') AS INTEGER) * 1000)",f="operation-debit:",w=t=>t==="execute"?"e.phase = 'effects_started' AND r.status = 'running'":"e.phase = 'unknown' AND r.status = 'unknown'";function C(t,e,r){if(!r){if(e.startsWith(f))throw new _;return}if(r.userId!==t||!r.runId||!r.token||!["execute","compensate"].includes(r.mode))throw new _}var W=t=>String(t).includes("operation_wallet_claim_current");function h(t,e,r,i){if(C(t,e,r),!r){let a=A(),d="NOT EXISTS (SELECT 1 FROM operation_debit_plans WHERE debit_key = ?)";return{before:[{sql:`INSERT INTO operation_wallet_fences (id, allowed)
16
- SELECT ?, CASE WHEN ${d} THEN 1 ELSE 0 END`,args:[a,e]}],after:[{sql:"DELETE FROM operation_wallet_fences WHERE id = ?",args:[a]}],current:async p=>!!(await p.execute({sql:`SELECT ${d} AS allowed`,args:[e]})).rows[0]?.allowed}}if(i.kind==="debit"&&r.mode!=="execute"||r.mode==="compensate"&&i.amountMc!==0&&!r.settlementPlanId)throw new _;let n=r.settlementPlanId?" AND EXISTS (SELECT 1 FROM operation_final_settlements s WHERE s.id=? AND s.run_id=p.run_id AND s.user_id=r.user_id AND s.debit_key=p.debit_key AND s.final_amount_mc=? AND s.refund_operation=? AND s.source_surface=?)":"",l=`SELECT 1 FROM operation_debit_plans p
17
- JOIN operation_runs r ON r.id = p.run_id JOIN operation_executions e ON e.run_id = r.id
18
- WHERE p.debit_key = ? AND r.id = ? AND r.user_id = ? AND e.claim_token = ?
19
- AND e.expires_at_ms > ${R} AND ${w(r.mode)}
20
- AND ${i.kind==="debit"?"p.amount_mc = ? AND p.operation = ? AND p.description = ?":"p.refund_operation = ? AND p.source_surface = ?"}${n}`,c=[e,r.runId,t,r.token,...i.kind==="debit"?[i.amountMc,i.operation,i.description]:[i.operation,i.sourceSurface],...r.settlementPlanId?[r.settlementPlanId,i.amountMc,i.operation,i.sourceSurface]:[]],o=A(),s=i.kind==="debit"?{sql:`INSERT OR IGNORE INTO operation_billing_links (run_id, billing_table, billing_key, relation, amount_mc)
21
- SELECT p.run_id, 'billing_debits', d.idempotency_key, 'debit', d.amount_mc FROM operation_debit_plans p
22
- JOIN billing_debits d ON d.idempotency_key = p.debit_key
23
- WHERE p.debit_key = ? AND d.user_id = ? AND d.status = 'applied'`,args:[e,t]}:{sql:`INSERT OR IGNORE INTO operation_billing_links (run_id, billing_table, billing_key, relation, amount_mc)
24
- SELECT p.run_id, 'billing_events', b.id, 'settlement', b.amount_mc FROM operation_debit_plans p
25
- JOIN billing_events b ON b.idempotency_key = ?
26
- WHERE p.debit_key = ? AND b.user_id = ? AND b.status = 'settled'`,args:[`debit-settlement:${T("sha256").update(e).digest("hex")}`,e,t]};return{before:[{sql:`INSERT INTO operation_wallet_fences (id, allowed)
27
- SELECT ?, CASE WHEN EXISTS (${l}) THEN 1 ELSE 0 END`,args:[o,...c]},D(t)],after:[s,{sql:"DELETE FROM operation_wallet_fences WHERE id = ?",args:[o]}],current:async a=>(await a.execute({sql:l,args:c})).rows.length===1}}function M(t){return{label:String(t.label),key:String(t.debit_key),amountMc:Number(t.amount_mc),operation:String(t.operation),description:String(t.description),refundOperation:String(t.refund_operation),sourceSurface:String(t.source_surface)}}async function X(t,e){if(t.mode!=="execute"||!Number.isSafeInteger(e.amountMc)||e.amountMc<=0||!e.label||e.label.length>200||!e.operation||!e.refundOperation||!e.sourceSurface)throw new N;let r=u(),i=f+A();C(t.userId,i,t);let n=`EXISTS (SELECT 1 FROM operation_runs r JOIN operation_executions e ON e.run_id = r.id
28
- WHERE r.id = ? AND r.user_id = ? AND e.claim_token = ? AND e.expires_at_ms > ${R}
29
- AND ${w("execute")})`,l=[t.runId,t.userId,t.token],c;try{await r.batch([{sql:`INSERT OR IGNORE INTO operation_debit_plans
30
- (run_id, label, debit_key, amount_mc, operation, description, refund_operation, source_surface)
31
- SELECT ?, ?, ?, ?, ?, ?, ?, ? WHERE ${n}`,args:[t.runId,e.label,i,e.amountMc,e.operation,e.description,e.refundOperation,e.sourceSurface,...l]},{sql:`UPDATE operation_debit_plans SET amount_mc = ? WHERE run_id = ? AND label = ?
32
- AND operation = ? AND description = ? AND refund_operation = ? AND source_surface = ? AND ${n}
33
- AND EXISTS (SELECT 1 FROM billing_debits d WHERE d.idempotency_key = operation_debit_plans.debit_key
34
- AND d.user_id = ? AND d.status = 'claimed' AND d.amount_mc = operation_debit_plans.amount_mc
35
- AND d.operation = operation_debit_plans.operation AND d.description = operation_debit_plans.description)`,args:[e.amountMc,t.runId,e.label,e.operation,e.description,e.refundOperation,e.sourceSurface,...l,t.userId]}],"write")}catch(a){c=a}let o;try{o=(await r.execute({sql:`SELECT p.* FROM operation_debit_plans p WHERE p.run_id = ? AND p.label = ? AND ${n}`,args:[t.runId,e.label,...l]})).rows[0]}catch(a){throw c??a}if(!o)throw c||new _;let s=M(o);if(s.amountMc!==e.amountMc||s.operation!==e.operation||s.description!==e.description||s.refundOperation!==e.refundOperation||s.sourceSurface!==e.sourceSurface)throw new N;return s}async function B(t){C(t.userId,f,t);let e=u();if(!(await e.execute({sql:`SELECT 1 FROM operation_executions e JOIN operation_runs r ON r.id = e.run_id
36
- WHERE r.id = ? AND r.user_id = ? AND e.claim_token = ? AND e.expires_at_ms > ${R}
37
- AND ${w(t.mode)}`,args:[t.runId,t.userId,t.token]})).rows.length)throw new _;return(await e.execute({sql:"SELECT * FROM operation_debit_plans WHERE run_id = ? ORDER BY label",args:[t.runId]})).rows.map(M)}async function j(t,e){let i=(await u().execute({sql:"SELECT user_id, amount_mc, operation, description, status FROM billing_debits WHERE idempotency_key = ? AND user_id = ? LIMIT 1",args:[e,t]})).rows[0];return i?{amountMc:Number(i.amount_mc),operation:String(i.operation),description:String(i.description),status:String(i.status)}:null}async function J(t,e,r,i,n,l){if(!Number.isSafeInteger(e)||e<=0)throw new Error("idempotent debit amount must be a positive integer");if(!n||n.length>500)throw new Error("idempotent debit key is required and must be bounded");let c=u(),o=h(t,n,l,{kind:"debit",amountMc:e,operation:r,description:i});l||await O(t);let s;try{s=await c.batch([...o.before,{sql:"UPDATE billing_debits SET amount_mc = ? WHERE idempotency_key = ? AND user_id = ? AND operation = ? AND description = ? AND status = 'claimed'",args:[e,n,t,r,i]},{sql:"INSERT OR IGNORE INTO billing_debits (idempotency_key, user_id, amount_mc, operation, description, status) VALUES (?, ?, ?, ?, ?, 'claimed')",args:[n,t,e,r,i]},{sql:`UPDATE users
38
- SET balance_mc = balance_mc - ?
39
- WHERE id = ?
40
- AND balance_mc >= ?
41
- AND (SELECT COALESCE(SUM(remaining_mc), 0)
42
- FROM credit_lots
43
- WHERE user_id = ?
44
- AND remaining_mc > 0
45
- AND (never_expires = 1 OR expires_at > datetime('now'))) >= ?
46
- AND EXISTS (SELECT 1 FROM billing_debits WHERE idempotency_key = ? AND user_id = ? AND amount_mc = ? AND operation = ? AND description = ? AND status = 'claimed')`,args:[e,t,e,t,e,n,t,e,r,i]},{sql:"UPDATE billing_debits SET status = 'applying' WHERE idempotency_key = ? AND user_id = ? AND amount_mc = ? AND operation = ? AND description = ? AND status = 'claimed' AND changes() = 1",args:[n,t,e,r,i]},{sql:`INSERT OR IGNORE INTO billing_debit_allocations
47
- (debit_idempotency_key, lot_id, user_id, amount_mc, expires_at)
48
- WITH ordered AS MATERIALIZED (
49
- SELECT id,
50
- remaining_mc,
51
- expires_at,
52
- COALESCE(SUM(remaining_mc) OVER (
53
- ORDER BY never_expires ASC, expires_at ASC, granted_at ASC, id ASC
54
- ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING
55
- ), 0) AS prior_mc
56
- FROM credit_lots
57
- WHERE user_id = ? AND remaining_mc > 0 AND (never_expires = 1 OR expires_at > datetime('now'))
58
- ), allocation AS (
59
- SELECT id, expires_at, MIN(remaining_mc, MAX(0, ? - prior_mc)) AS take_mc
60
- FROM ordered
61
- )
62
- SELECT ?, id, ?, take_mc, expires_at
63
- FROM allocation
64
- WHERE take_mc > 0
65
- AND EXISTS (SELECT 1 FROM billing_debits WHERE idempotency_key = ? AND status = 'applying')`,args:[t,e,n,t,n]},{sql:`UPDATE credit_lots
66
- SET remaining_mc = remaining_mc - COALESCE((
67
- SELECT amount_mc FROM billing_debit_allocations
68
- WHERE debit_idempotency_key = ? AND lot_id = credit_lots.id
69
- ), 0)
70
- WHERE id IN (
71
- SELECT lot_id FROM billing_debit_allocations WHERE debit_idempotency_key = ?
72
- )
73
- AND EXISTS (SELECT 1 FROM billing_debits WHERE idempotency_key = ? AND status = 'applying')`,args:[n,n,n]},{sql:"INSERT INTO ledger (user_id, amount_mc, operation, description) SELECT user_id, -amount_mc, operation, description FROM billing_debits WHERE idempotency_key = ? AND status = 'applying'",args:[n]},{sql:"UPDATE billing_debits SET status = 'applied', applied_at = datetime('now') WHERE idempotency_key = ? AND status = 'applying'",args:[n]},...o.after],"write")}catch(b){if(W(b))throw new _;try{if(!await o.current(c))throw new _;let E=(await c.execute({sql:"SELECT user_id, amount_mc, operation, description, status FROM billing_debits WHERE idempotency_key = ? AND status = 'applied' LIMIT 1",args:[n]})).rows[0];if(E&&Number(E.user_id)===t&&Number(E.amount_mc)===e&&String(E.operation)===r&&String(E.description)===i){let S=await c.execute({sql:"SELECT balance_mc FROM users WHERE id = ?",args:[t]});return{ok:!0,balance_mc:Number(S.rows[0]?.balance_mc??0),duplicate:!0}}}catch(m){if(m instanceof _)throw m}throw b}let d=(await c.execute({sql:"SELECT user_id, amount_mc, operation, description, status FROM billing_debits WHERE idempotency_key = ? LIMIT 1",args:[n]})).rows[0];if(!d||Number(d.user_id)!==t||Number(d.amount_mc)!==e||String(d.operation)!==r||String(d.description)!==i)throw new Error("idempotent debit key conflicts with another debit");let p=await c.execute({sql:"SELECT balance_mc FROM users WHERE id = ?",args:[t]});return{ok:String(d.status)==="applied",balance_mc:Number(p.rows[0]?.balance_mc??0),duplicate:s[2+o.before.length]?.rowsAffected===0&&String(d.status)==="applied"}}async function V(t,e,r,i,n,l,c){if(!Number.isSafeInteger(r)||r<0)throw new Error("idempotent debit settlement amount must be a non-negative integer");if(!e||e.length>500)throw new Error("idempotent debit settlement key is required and must be bounded");if(!i||!l)throw new Error("idempotent debit settlement operation and source are required");let o=u(),s=h(t,e,c,{kind:"settlement",amountMc:r,operation:i,description:n,sourceSurface:l});c||await O(t);let a=`debit-settlement:${T("sha256").update(e).digest("hex")}`,d="wallet_hold_settlement",p=A(),b=JSON.stringify({debitIdempotencyKey:e,refundOperation:i,description:n}),m=()=>x(t,e,l),E;try{E=await o.batch([...s.before,{sql:`INSERT OR IGNORE INTO billing_events
74
- (id, user_id, idempotency_key, billing_class, source_surface, status, amount_mc, metadata)
75
- VALUES (?, ?, ?, ?, ?, 'settling', ?, ?)`,args:[p,t,a,d,l,r,b]},{sql:`WITH ordered AS (
76
- SELECT a.lot_id,
77
- a.amount_mc,
78
- a.expires_at,
79
- COALESCE(SUM(a.amount_mc) OVER (
80
- ORDER BY a.expires_at ASC, a.lot_id ASC
81
- ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING
82
- ), 0) AS prior_mc
83
- FROM billing_debit_allocations a
84
- WHERE a.debit_idempotency_key = ?
85
- ), refunds AS (
86
- SELECT lot_id,
87
- expires_at,
88
- amount_mc - MIN(amount_mc, MAX(0, ? - prior_mc)) AS refund_mc
89
- FROM ordered
90
- )
91
- UPDATE users
92
- SET balance_mc = balance_mc + CASE
93
- WHEN EXISTS (SELECT 1 FROM ordered) THEN COALESCE(
94
- (SELECT SUM(refund_mc) FROM refunds WHERE expires_at > datetime('now')),
95
- 0
96
- )
97
- -- Holds created before allocation provenance cannot be safely
98
- -- tied back to a source lot. Treat their unused portion as
99
- -- expired instead of minting spendable credits with a guessed
100
- -- expiry.
101
- ELSE 0
102
- END
103
- WHERE id = ?
104
- AND EXISTS (
105
- SELECT 1
106
- FROM billing_events e
107
- JOIN billing_debits d ON d.idempotency_key = ?
108
- WHERE e.idempotency_key = ?
109
- AND e.user_id = ?
110
- AND e.billing_class = ?
111
- AND e.source_surface = ?
112
- AND e.status = 'settling'
113
- AND d.user_id = e.user_id
114
- AND d.status = 'applied'
115
- AND e.amount_mc BETWEEN 0 AND d.amount_mc
116
- )`,args:[e,r,t,e,a,t,d,l]},{sql:`UPDATE billing_events
117
- SET status = 'applying'
118
- WHERE idempotency_key = ?
119
- AND user_id = ?
120
- AND billing_class = ?
121
- AND source_surface = ?
122
- AND status = 'settling'
123
- AND changes() = 1`,args:[a,t,d,l]},{sql:`WITH ordered AS (
124
- SELECT a.lot_id,
125
- a.amount_mc,
126
- a.expires_at,
127
- COALESCE(SUM(a.amount_mc) OVER (
128
- ORDER BY a.expires_at ASC, a.lot_id ASC
129
- ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING
130
- ), 0) AS prior_mc
131
- FROM billing_debit_allocations a
132
- WHERE a.debit_idempotency_key = ?
133
- ), refunds AS (
134
- SELECT lot_id,
135
- expires_at,
136
- amount_mc - MIN(amount_mc, MAX(0, ? - prior_mc)) AS refund_mc
137
- FROM ordered
138
- )
139
- UPDATE credit_lots
140
- SET remaining_mc = remaining_mc + COALESCE((SELECT refund_mc FROM refunds WHERE refunds.lot_id = credit_lots.id), 0)
141
- WHERE id IN (
142
- SELECT lot_id FROM refunds
143
- WHERE refund_mc > 0 AND expires_at > datetime('now')
144
- )
145
- AND EXISTS (SELECT 1 FROM billing_events WHERE idempotency_key = ? AND status = 'applying')`,args:[e,r,a]},{sql:`WITH ordered AS (
146
- SELECT a.amount_mc,
147
- a.expires_at,
148
- COALESCE(SUM(a.amount_mc) OVER (
149
- ORDER BY a.expires_at ASC, a.lot_id ASC
150
- ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING
151
- ), 0) AS prior_mc
152
- FROM billing_debit_allocations a
153
- WHERE a.debit_idempotency_key = ?
154
- ), refunds AS (
155
- SELECT expires_at,
156
- amount_mc - MIN(amount_mc, MAX(0, ? - prior_mc)) AS refund_mc
157
- FROM ordered
158
- ), credited AS (
159
- SELECT e.user_id,
160
- CASE
161
- WHEN EXISTS (SELECT 1 FROM ordered) THEN COALESCE(
162
- (SELECT SUM(refund_mc) FROM refunds WHERE expires_at > datetime('now')),
163
- 0
164
- )
165
- ELSE 0
166
- END AS refund_mc
167
- FROM billing_events e
168
- JOIN billing_debits d ON d.idempotency_key = ?
169
- WHERE e.idempotency_key = ?
170
- AND e.status = 'applying'
171
- )
172
- INSERT INTO ledger (user_id, amount_mc, operation, description)
173
- SELECT user_id,
174
- refund_mc,
175
- ?,
176
- ?
177
- FROM credited
178
- WHERE refund_mc > 0`,args:[e,r,e,a,i,n]},{sql:`UPDATE billing_events
179
- SET status = 'settled', settled_at = datetime('now')
180
- WHERE idempotency_key = ?
181
- AND status = 'applying'`,args:[a]},...s.after],"write")}catch(L){if(W(L))throw new _;try{if(!await s.current(o))throw new _;let g=await m();if(g)return g}catch(g){if(g instanceof _)throw g}throw L}let S=await m();if(!S)throw new Error("idempotent debit settlement did not reach a durable settled state");return{...S,duplicate:E[s.before.length]?.rowsAffected===0}}async function Y(t,e){let{hold:r}=e,i=I(r);if(r.userId!==t.userId||!t.runId||!t.token||!e.label||e.label.length>200||!e.refundOperation||!e.sourceSurface||!e.tool||!e.jobId)throw new N;let n=`EXISTS (SELECT 1 FROM operation_runs r JOIN operation_executions e ON e.run_id=r.id
182
- WHERE r.id=? AND r.user_id=? AND r.tool=? AND r.job_id=? AND r.status='running'
183
- AND json_extract(r.normalized_flags_json,'$._storeGateRequired') IS 1
184
- AND e.claim_token=? AND e.phase='claimed' AND e.expires_at_ms > ${R})`,l=[t.runId,t.userId,e.tool,e.jobId,t.token],c=u(),o;try{await c.batch([{sql:`INSERT OR IGNORE INTO operation_debit_plans
185
- (run_id,label,debit_key,amount_mc,operation,description,refund_operation,source_surface)
186
- SELECT ?,?,?,?,?,?,?,? WHERE ${n} AND (${i.sql})`,args:[t.runId,e.label,r.key,r.amountMc,r.operation,r.description,e.refundOperation,e.sourceSurface,...l,...i.args]},{sql:`INSERT OR IGNORE INTO operation_billing_links (run_id,billing_table,billing_key,relation,amount_mc)
187
- SELECT p.run_id,'billing_debits',p.debit_key,'hold',p.amount_mc FROM operation_debit_plans p
188
- WHERE p.run_id=? AND p.label=? AND p.debit_key=? AND p.amount_mc=? AND p.operation=? AND p.description=?
189
- AND p.refund_operation=? AND p.source_surface=? AND ${n} AND (${i.sql})`,args:[t.runId,e.label,r.key,r.amountMc,r.operation,r.description,e.refundOperation,e.sourceSurface,...l,...i.args]}],"write")}catch(d){o=d}let s;try{s=(await c.execute({sql:`SELECT p.* FROM operation_debit_plans p
190
- WHERE p.run_id=? AND p.label=? AND ${n} AND (${i.sql})`,args:[t.runId,e.label,...l,...i.args]})).rows[0]}catch(d){throw o??d}if(!s)throw o||new _;let a=M(s);if(a.key!==r.key||a.amountMc!==r.amountMc||a.operation!==r.operation||a.description!==r.description||a.refundOperation!==e.refundOperation||a.sourceSurface!==e.sourceSurface)throw new N;return a}async function x(t,e,r){if(!Number.isSafeInteger(t)||t<=0||!e||!r)throw new _;let i=u(),n=`debit-settlement:${T("sha256").update(e).digest("hex")}`,l="wallet_hold_settlement",o=(await i.execute({sql:`SELECT e.user_id,
191
- e.status,
192
- e.amount_mc AS final_amount_mc,
193
- e.billing_class,
194
- e.source_surface,
195
- e.settled_at,
196
- d.amount_mc AS held_amount_mc
197
- FROM billing_events e
198
- JOIN billing_debits d ON d.idempotency_key = ?
199
- WHERE e.idempotency_key = ?
200
- AND d.user_id = e.user_id
201
- AND d.status = 'applied'
202
- LIMIT 1`,args:[e,n]})).rows[0];if(!o)return null;if(Number(o.user_id)!==t||String(o.billing_class)!==l||String(o.source_surface)!==r)throw new Error("idempotent debit settlement key conflicts with another settlement");if(String(o.status)!=="settled")return null;let s=Number(o.held_amount_mc),a=Number(o.final_amount_mc);if(!Number.isSafeInteger(s)||!Number.isSafeInteger(a)||a<0||a>s)throw new Error("idempotent debit settlement receipt is invalid");let d=s-a,p=await i.execute({sql:`WITH ordered AS (
203
- SELECT a.amount_mc,
204
- a.expires_at,
205
- COALESCE(SUM(a.amount_mc) OVER (
206
- ORDER BY a.expires_at ASC, a.lot_id ASC
207
- ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING
208
- ), 0) AS prior_mc
209
- FROM billing_debit_allocations a
210
- WHERE a.debit_idempotency_key = ?
211
- ), refunds AS (
212
- SELECT expires_at,
213
- amount_mc - MIN(amount_mc, MAX(0, ? - prior_mc)) AS refund_mc
214
- FROM ordered
215
- )
216
- SELECT (SELECT COUNT(*) FROM ordered) AS allocation_count,
217
- COALESCE(SUM(CASE WHEN expires_at > ? THEN refund_mc ELSE 0 END), 0) AS credited_refund_mc
218
- FROM refunds`,args:[e,a,String(o.settled_at)]}),m=Number(p.rows[0]?.allocation_count??0)>0?Number(p.rows[0]?.credited_refund_mc??0):0,E=await i.execute({sql:"SELECT balance_mc FROM users WHERE id = ?",args:[t]});return{balance_mc:Number(E.rows[0]?.balance_mc??0),final_amount_mc:a,refund_mc:m,expired_refund_mc:d-m,duplicate:!0}}export{k as a,O as b,X as c,B as d,j as e,J as f,V as g,Y as h,x as i};
@@ -1,16 +0,0 @@
1
- import{a as s}from"./chunk-EYGA6LOU.js";var _={message:"Failed browser requests now settle safely after explicit connection rejection. Job and Maps responses keep service diagnostics private. Incomplete Maps collection reports partial results; existing job identifiers and billing holds remain recoverable."};var i={reset:"\x1B[0m",cyan:"\x1B[36m",lime:"\x1B[32m",amber:"\x1B[33m",red:"\x1B[31m",muted:"\x1B[90m",bold:"\x1B[1m"};function r(t,e,n){return n?`${i[e]}${t}${i.reset}`:t}function o(t,e,n){let a=t.padEnd(9," ");return` ${r(a,"muted",n)} ${e.join(r(" . ","muted",n))}`}function b(t){let e=t.color??!0,n=t.apiKeyConfigured?"$MCP_SCRAPER_API_KEY":"sk_live_your_key",a=String.raw`
2
- __ __ ____ ____
3
- | \/ |/ ___| _ \
4
- | |\/| | | | |_) |
5
- | | | | |___| __/
6
- |_| |_|\____|_|
7
-
8
- ____ ____ ____ _ ____ _____ ____
9
- / ___| / ___| _ \ / \ | _ \| ____| _ \
10
- \___ \| | | |_) | / _ \ | |_) | _| | |_) |
11
- ___) | |___| _ < / ___ \| __/| |___| _ <
12
- |____/ \____|_| \_\/_/ \_\_| |_____|_| \_\
13
- `,c=[`MCP_SCRAPER_API_KEY=${n} npx -y -p mcp-scraper@latest \\`," mcp-scraper-cli agent install claude --apply"].join(`
14
- `),l=["[mcp_servers.mcp-scraper]",'command = "npx"','args = ["-y", "-p", "mcp-scraper@latest", "mcp-scraper"]',`env = { MCP_SCRAPER_API_KEY = "${n}" }`].join(`
15
- `);return[r(`mcp-scraper v${t.version}`,"bold",e),r("> mcp-scraper-install","muted",e),r(a,"amber",e),`${r("MCP Scraper Agent","cyan",e)} . v${t.version} . mcpscraper.dev`,"1/1 install surfaces ready",r(`Newest in v${t.version}: ${_.message}`,"lime",e),"",`${r("Tools","cyan",e)} ${r(`(${s.inventory.totalTools} MCP tools)`,"muted",e)}`,o("search",["harvest_paa","search_serp","maps_search","maps_place_intel"],e),o("extract",["extract_url","map_site_urls","extract_site","audit_site","directory_workflow"],e),o("build",["create_editorial_reading_room","rank_tracker_workflow","portable HTML"],e),o("media",["youtube_harvest","youtube_transcribe","facebook_reels_inventory","facebook_ad_search","facebook_page_intel","facebook_ad_transcribe","facebook_video_transcribe","tiktok_video_transcribe","instagram_profile_content","instagram_media_download","reddit_thread"],e),o("browser",["serp_identity_create","serp_identity_list","browser_open","browser_profile_connect","browser_profile_list","browser_close","browser_screenshot","browser_read","browser_locate","browser_replay_mark","browser_replay_annotate"],e),o("connect",["list_service_connections","describe_service_connection_tool","import_service_connection_to_memory","export_connected_service_data","renew_connected_data_download","read_service_connection","call_service_connection_action"],e),o("commons",["commons_search_entities","commons_get_entity_linkset","commons_prepare_entity","commons_submit_entity","commons_prepare_publication","commons_claim_publication","commons_publish_editorial","commons_get_publication"],e),o("account",["credits_info","reports","MCP resources"],e),o("memory",["memory-put","memory-get","memory-search","list-vaults","record-fact","list_artifact_templates"],e),`${r("Workflows","cyan",e)} ${r("(MCP + CLI + API)","muted",e)}`,o("route",["workflow_list","workflow_suggest","workflow_run","workflow_step","workflow_status","workflow_artifact_read"],e),o("seo",["directory","agent-packet","competitive audit","map/serp comparison","PAA/AIO briefs"],e),"",r("Usage tips:","amber",e),"Run mcp-scraper-install for this visible card. Run mcp-scraper-cli for setup utilities and subcommands.","Run mcp-scraper in a human terminal to print this card; MCP clients get the same command as a silent stdio server.","Explicit card command: npx -y -p mcp-scraper@latest mcp-scraper-install","Hosted browser sessions use direct/no-proxy egress by default.","Customer auth setup: run browser_profile_connect, send the watch_url, let the user sign in, then call browser_profile_list until AUTHENTICATED.","Connected account ranges: call export_connected_service_data once. It handles Gmail, Calendar, Zoom, and Resend pagination; do not loop read_service_connection over individual records.","Connected account RAG: call import_service_connection_to_memory for one bounded approved read. It writes a redacted, untrusted snapshot to a stable Memory path and embeds it for search.","Stack logins / reconnect: run browser_profile_connect again with the same profile name and another domain to add accounts or refresh a login.","Start with workflow_suggest for broad jobs like market analysis, ICP research, CRO audits, brand briefs, content gaps, and AI visibility.","For MCP clients, use mcp-scraper so one install can mix SERP, Maps, browser, reports, and saved MCP resources.","If you hit the concurrency limit, add 2 browsers for $5/month with mcp-scraper-cli billing concurrency checkout.","",`${r("Ready.","lime",e)} Install the combined MCP server with one command:`,"",r("Setup doctor","amber",e),"npx -y -p mcp-scraper@latest mcp-scraper-cli doctor","",r("Hosted profile setup","amber",e),'In your MCP client, call browser_profile_connect with email="seo@example.com" and domain="chatgpt.com".',"Give the returned watch_url to the user. After they sign in, call browser_profile_list, then browser_open with the returned profile. Add more logins by calling browser_profile_connect again with the same profile and a new domain.","",r("Claude Code one-command setup","amber",e),c,"Then fully exit Claude Code and open a new Claude terminal. Check with: claude mcp list","",r("Codex config","amber",e),l,"",r("Claude Desktop Extension","amber",e),"Download: https://mcpscraper.dev/downloads/mcp-scraper.mcpb","",r("Safety note:","muted",e),"mcp-scraper prints this card only when stdin/stdout are an interactive TTY. In MCP clients it writes only JSON-RPC to stdout.","Use --stdio or MCP_SCRAPER_FORCE_STDIO=1 to force server mode from a terminal.",""].join(`
16
- `)}export{b as a};
@@ -1,4 +0,0 @@
1
- import{$ as E,B as R,D as v,Fa as C,Ga as P,Y as S,_ as T,ha as w,ja as h,ka as _,la as y,x as f,y as u,z as g}from"./chunk-4AEW53RU.js";import{a as x}from"./chunk-ZDECILF6.js";import{a as c}from"./chunk-IPQOBOFY.js";import{readFileSync as L}from"fs";import{homedir as B}from"os";import{join as U}from"path";import{serveStdio as Y}from"@modelcontextprotocol/server/stdio";import{McpServer as J}from"@modelcontextprotocol/server";var I=new Map(_.map(r=>[r.upstreamName,r.id]));function N(r){let s=r.split(`
2
- `).filter(t=>t.startsWith("data:")).map(t=>t.slice(5).trim()).filter(Boolean);if(!s.length)return JSON.parse(r);for(let t of s){let e=JSON.parse(t);if(e.result||e.error)return e}throw new Error("hosted MCP returned no JSON-RPC result")}function l(r){return{content:[{type:"text",text:JSON.stringify({ok:!1,error:r})}],isError:!0}}var p=class{baseUrl;apiKey;constructor(s,t){this.baseUrl=s.replace(/\/$/,""),this.apiKey=t}async callMemoryTool(s,t){let e=I.get(s);if(!e)return l(`unknown memory tool: ${s}`);try{let n=await fetch(`${this.baseUrl}/mcp`,{method:"POST",headers:{"content-type":"application/json",accept:"application/json, text/event-stream","x-api-key":this.apiKey},body:JSON.stringify({jsonrpc:"2.0",id:`memory:${e}`,method:"tools/call",params:{name:e,arguments:t}})}),i=await n.text();if(!n.ok)return l(`hosted memory ${e} failed (HTTP ${n.status})`);let o=N(i);return o.error?l(o.error.message??`hosted memory ${e} failed`):o.result??l(`hosted memory ${e} returned no result`)}catch(n){return l(n instanceof Error?n.message:`hosted memory ${e} call failed`)}}};function M(r,s){if(s.length===0)throw new Error("Restricted MCP tool allowlist must contain at least one tool name");let t=new Set;for(let o of s){if(typeof o!="string"||o.trim()!==o||o.length===0)throw new Error("Restricted MCP tool allowlist contains a malformed tool name");if(t.has(o))throw new Error(`Restricted MCP tool allowlist contains duplicate tool name: ${o}`);t.add(o)}let e=new Set,n=r,i=n.registerTool.bind(r);return n.registerTool=(o,a,m)=>{if(t.has(o))return e.add(o),i(o,a,m)},{assertComplete(){let o=[...t].filter(a=>!e.has(a));if(o.length>0)throw new Error(`Restricted MCP tool allowlist contains unknown or unavailable tool names: ${o.join(", ")}`)},registeredToolNames(){return[...e]}}}import{Client as b,StreamableHTTPClientTransport as k}from"@modelcontextprotocol/client";var $=new Set(["artifact_read","artifact_describe","artifact_download","report_artifact_read"]),A=()=>({content:[{type:"text",text:"Retained file storage is unavailable. Preserve the artifactId and retry retrieval; do not repeat acquisition."}],isError:!0});function O(r,s,t={}){return async(e,n)=>{if(!$.has(e))return A();let i=new b({name:"mcp-scraper-artifact-client",version:c},{versionNegotiation:{mode:"auto"}}),o=AbortSignal.timeout(3e4);try{let a=new k(new URL(`${r.replace(/\/$/,"")}/mcp`),{requestInit:{signal:o,headers:{Authorization:`Bearer ${s}`,"x-api-key":s,...t.localNetworkAccess?{"x-mcp-scraper-local-network":"1"}:{}}}});return await i.connect(a,{signal:o,timeout:3e4}),await i.callTool({name:e,arguments:n},{signal:o,timeout:3e4})}catch{return A()}finally{await i.close().catch(()=>{})}}}var G=new Set(["paa","serp","browser-agent","artifact-templates","memory"]);function K(){let s=[process.env.MCP_SCRAPER_KEY_PATH?.trim(),U(B(),".mcp-scraper-key")].filter(Boolean);for(let t of s)try{let e=L(t,"utf8").trim();if(e)return e}catch{}}function j(r,s={}){let t=s.toolsets??G,e=process.env.MCP_SCRAPER_BASE_URL?.trim()||process.env.MCP_BASE_URL?.trim()||"https://mcpscraper.dev",n=R(),i=v({deploymentProfile:n,transportProfile:"stdio",baseUrl:e,explicitlyEnabled:process.env.MCP_SCRAPER_ALLOW_PRIVATE_NETWORK==="1"}),o=process.env.BROWSER_AGENT_CONSOLE_URL?.trim()||e,a=new J({name:"mcp-scraper",version:c},{instructions:u,cacheHints:{"server/discover":{ttlMs:3e5,cacheScope:"private"},"tools/list":{ttlMs:3e5,cacheScope:"private"},"prompts/list":{ttlMs:3e5,cacheScope:"private"},"resources/list":{ttlMs:3e5,cacheScope:"private"},"resources/templates/list":{ttlMs:3e5,cacheScope:"private"},"resources/read":{ttlMs:6e4,cacheScope:"private"}}});g(a);let m=s.allowedToolNames?M(a,s.allowedToolNames):void 0,d=s.httpExecutor??new w(e,r,{localNetworkAccess:i,analyticsIdentity:()=>E(a.server.getClientVersion()?.name)});return t.has("paa")&&T(a,d,{ownerId:S(r),deploymentProfile:n,transportProfile:"stdio",baseUrl:e,localNetworkAccess:i,taskHandleSecret:r,remoteArtifactAccess:O(e,r,{localNetworkAccess:i})}),t.has("serp")&&f(a,d,{exposeDevelopmentDiagnostics:n==="development"||n==="test"}),t.has("browser-agent")&&h(a,{baseUrl:e,apiKey:r,consoleBaseUrl:o}),t.has("artifact-templates")&&P(a,new C(e,r)),t.has("memory")&&y(a,new p(e,r)),m?.assertComplete(),a}function Re(r={}){let s=process.argv.includes("--stdio")||process.env.MCP_SCRAPER_FORCE_STDIO==="1",t=!!(process.stdin.isTTY&&process.stdout.isTTY),e=process.argv.includes("--help")||process.argv.includes("-h");if(!s&&(t||e)){let i=process.argv.includes("--no-color")||process.env.NO_COLOR!==void 0||process.env.FORCE_COLOR==="0"||!process.stdout.isTTY;process.stdout.write(x({version:c,color:!i,apiKeyConfigured:!!process.env.MCP_SCRAPER_API_KEY?.trim()}),()=>process.exit(0));return}let n=(process.env.MCP_SCRAPER_API_KEY??process.env.MCP_SCRAPER_KEY??process.env.MCP_API_KEY??K())?.trim();n||(process.stderr.write(`MCP_SCRAPER_API_KEY env var or ~/.mcp-scraper-key is required
3
- `),process.exit(1)),Y(()=>j(n,r),{legacy:"serve",onerror(i){process.stderr.write(`${i.message}
4
- `)}})}export{Re as a};
@@ -1 +0,0 @@
1
- import{A as a,B as b,C as c,D as d,E as e,F as f,G as g,H as h}from"./chunk-SJNSTO3C.js";import"./chunk-XNTAHMPA.js";import"./chunk-6D25Q5BR.js";import"./chunk-C3JWX6KM.js";import"./chunk-KBZY2OGP.js";import"./chunk-JHDD6R3O.js";import"./chunk-7SR7MEU5.js";import"./chunk-ANQ4JJVI.js";import"./chunk-FLAWC5PF.js";import"./chunk-B4ZKPLSP.js";import"./chunk-VVSHZV5S.js";import"./chunk-PKQHHCO4.js";import"./chunk-4ZVO6GX4.js";import"./chunk-C7MGJUTU.js";import"./chunk-WNUXMPVX.js";import"./chunk-6N5EC7ZO.js";import"./chunk-HNNYXMSI.js";export{c as capture,e as finalize,b as noteUnknown,h as prepareCompatibilityQueue,d as reply,f as resumeCompatibilityHarvest,g as runCompatibilityHarvest,a as waiting};
@@ -1 +0,0 @@
1
- import{a,b,c,d,e,f}from"./chunk-HNNYXMSI.js";export{b as OperationIdempotencyConflictError,a as OperationInputError,d as operationFlagsJson,c as operationIdentityHash,e as requiredOperationString,f as validateOperationStoreGate};