mcp-scraper 0.89.6 → 0.89.9
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/CHANGELOG.md +51 -1
- package/README.md +3 -3
- package/dist/{analytics-repository-4UA3WI3U.js → analytics-repository-UX6VU22H.js} +1 -1
- package/dist/bin/api-server.js +1 -1
- package/dist/bin/mcp-scraper-cli.js +1 -1
- package/dist/bin/mcp-scraper-core.js +1 -1
- package/dist/bin/mcp-scraper-install.js +1 -1
- package/dist/bin/mcp-stdio-server.js +1 -1
- package/dist/bin/paa-harvest.js +1 -1
- package/dist/{chunk-YCZKKSTT.js → chunk-2GRE4BAO.js} +1 -1
- package/dist/chunk-2PXP7TMY.js +1 -0
- package/dist/{chunk-3GP5CYZX.js → chunk-2TZBO52D.js} +1 -1
- package/dist/{chunk-H2I63VAD.js → chunk-2WWKTVCO.js} +1 -1
- package/dist/{chunk-ISZIA6NE.js → chunk-52XUWR3X.js} +1 -1
- package/dist/{chunk-Y3ITV2OK.js → chunk-5B42QVDC.js} +1 -1
- package/dist/{chunk-KKI2SNB2.js → chunk-7AC66V3T.js} +1 -1
- package/dist/{chunk-YQ5U5C2X.js → chunk-7BEWBRMT.js} +74 -55
- package/dist/{chunk-WUVMD6ZX.js → chunk-DKQZNSYM.js} +1 -1
- package/dist/{chunk-MZN4U5BL.js → chunk-E4ME7J6G.js} +1 -1
- package/dist/{chunk-C6JXNOSF.js → chunk-F4LIB772.js} +8 -8
- package/dist/{chunk-PPOI4C3Q.js → chunk-HR2A2WTL.js} +1 -1
- package/dist/{chunk-XLWNEVUZ.js → chunk-JHMI6HEO.js} +3 -3
- package/dist/{chunk-FVSXX43Z.js → chunk-JSNFZPPB.js} +1 -1
- package/dist/{chunk-3H7HU5JI.js → chunk-JVU2THSY.js} +1 -1
- package/dist/{chunk-VZTFJLOK.js → chunk-LZTDANNZ.js} +1 -1
- package/dist/{chunk-QPWPR5XG.js → chunk-M5QHXNFZ.js} +1 -1
- package/dist/{chunk-FKSTNWP6.js → chunk-PHBU6X5B.js} +1 -1
- package/dist/chunk-PVTKGAZL.js +1 -0
- package/dist/{chunk-H3QW5U67.js → chunk-Q4A2KIPZ.js} +3 -3
- package/dist/{chunk-G6GAIXXA.js → chunk-S3N55WHK.js} +4 -4
- package/dist/{chunk-WXOLIRFJ.js → chunk-VT6SLBOU.js} +1 -1
- package/dist/{chunk-Z45GM22P.js → chunk-XATD7HDY.js} +227 -227
- package/dist/{chunk-YQZGZBB4.js → chunk-XG6GCEUE.js} +1 -1
- package/dist/db-UKQ74OVT.js +1 -0
- package/dist/{extract-bundle-BTZQJTYV.js → extract-bundle-DI7OVLT5.js} +5 -5
- package/dist/{gmail-service-ZZDF52KK.js → gmail-service-ASX7YBC3.js} +1 -1
- package/dist/index.cjs +45 -45
- package/dist/index.d.cts +16 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +1 -1
- package/dist/{lead-list-enrichment-repository-K4H5DMSF.js → lead-list-enrichment-repository-GPDHJVM3.js} +1 -1
- package/dist/{location-data-repository-KALKE3FG.js → location-data-repository-MXUNVDHW.js} +1 -1
- package/dist/{server-YVNOU3RK.js → server-EYSV2RRD.js} +702 -702
- package/dist/{site-extract-repository-FTTIOWAL.js → site-extract-repository-WADCAIYB.js} +1 -1
- package/dist/{stripe-event-worker-CURL3RYL.js → stripe-event-worker-ZPNWXX2T.js} +1 -1
- package/dist/worker-577GJULQ.js +1 -0
- package/package.json +1 -1
- package/dist/chunk-CULFQBFR.js +0 -1
- package/dist/db-IZ5UF33U.js +0 -1
- package/dist/worker-MUHILD2W.js +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{k as K}from"./chunk-
|
|
1
|
+
import{k as K}from"./chunk-5B42QVDC.js";import{a as X}from"./chunk-2GRE4BAO.js";import{c as J,d as H}from"./chunk-HUV2WTRW.js";import{t as f}from"./chunk-7BEWBRMT.js";import{createHash as U,createHmac as re,timingSafeEqual as he}from"crypto";import{createHash as fe,randomUUID as Y}from"crypto";var ge=1440*60*1e3,F=5e3,h=class extends Error{constructor(n,i,o=400){super(i);this.code=n;this.status=o;this.name="GmailSelectionError"}code;status},k=null,P=null;function $(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map($).join(",")}]`:`{${Object.entries(e).sort(([t],[n])=>t.localeCompare(n)).map(([t,n])=>`${JSON.stringify(t)}:${$(n)}`).join(",")}}`}function b(e){return fe("sha256").update($(e)).digest("hex")}async function x(){let e=f();return k&&P===e||(P=e,k=(async()=>{await e.execute(`
|
|
2
2
|
CREATE TABLE IF NOT EXISTS gmail_selections (
|
|
3
3
|
selection_id TEXT PRIMARY KEY,
|
|
4
4
|
owner_identity TEXT NOT NULL,
|
|
@@ -34,8 +34,8 @@ import{k as K}from"./chunk-Y3ITV2OK.js";import{a as H}from"./chunk-YCZKKSTT.js";
|
|
|
34
34
|
status TEXT NOT NULL, result_json TEXT, updated_at TEXT NOT NULL
|
|
35
35
|
)`)})().catch(t=>{throw k=null,P=null,t})),k}function W(e){let t=[...new Set(e.map(n=>n.trim()).filter(n=>/^[A-Za-z0-9_-]+$/.test(n)))];return t.sort(),t}function V(e){return{selectionId:String(e.selection_id),ownerId:String(e.owner_identity),connectionId:String(e.connection_id),purpose:String(e.purpose),source:JSON.parse(String(e.source_json)),messageIds:JSON.parse(String(e.message_ids_json)),count:Number(e.message_count),selectionSha256:String(e.selection_sha256),createdAt:String(e.created_at),expiresAt:String(e.expires_at),providerSnapshot:typeof e.provider_snapshot_json=="string"?JSON.parse(e.provider_snapshot_json):null}}async function Z(e){await x();let t=W(e.resolvedMessageIds);if(t.length===0)throw new h("selection_empty","No Gmail messages matched the selection.");if(t.length>F)throw new h("selection_too_large",`Narrow the Gmail selection to at most ${F} messages.`);let n=e.source.kind==="query"?{kind:"query",query:e.source.query.trim().replace(/\s+/g," ")}:{kind:"message_ids",messageIds:W(e.source.messageIds)},i=b({connectionId:e.connectionId,purpose:e.purpose,source:n,messageIds:t}),o=await f().execute({sql:"SELECT * FROM gmail_selections WHERE owner_identity = ? AND connection_id = ? AND purpose = ? AND selection_sha256 = ? AND expires_at > ? LIMIT 1",args:[e.ownerId,e.connectionId,e.purpose,i,(e.now??new Date).toISOString()]});if(o.rows[0])return V(o.rows[0]);let r=e.now??new Date,a={selectionId:`gsel_${Y().replace(/-/g,"")}`,ownerId:e.ownerId,connectionId:e.connectionId,purpose:e.purpose,source:n,messageIds:t,count:t.length,selectionSha256:i,createdAt:r.toISOString(),expiresAt:new Date(r.getTime()+ge).toISOString(),providerSnapshot:e.providerSnapshot??null};return await f().execute({sql:"INSERT INTO gmail_selections (selection_id, owner_identity, connection_id, purpose, source_json, message_ids_json, message_count, selection_sha256, provider_snapshot_json, created_at, expires_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",args:[a.selectionId,a.ownerId,a.connectionId,a.purpose,JSON.stringify(a.source),JSON.stringify(a.messageIds),a.count,a.selectionSha256,a.providerSnapshot?JSON.stringify(a.providerSnapshot):null,a.createdAt,a.expiresAt]}),a}async function L(e){await x();let n=(await f().execute({sql:"SELECT * FROM gmail_selections WHERE selection_id = ? AND owner_identity = ? AND connection_id = ? AND expires_at > ? LIMIT 1",args:[e.selectionId,e.ownerId,e.connectionId,(e.now??new Date).toISOString()]})).rows[0];if(!n)throw new h("selection_not_found","Gmail selection not found.",404);return V(n)}function O(e,t,n){if(t!==e.count||n!==e.selectionSha256)throw new h("selection_changed","The Gmail selection receipt does not match the immutable selection.",409)}function j(e){return{actionId:String(e.action_id),ownerId:String(e.owner_identity),idempotencyKey:String(e.idempotency_key),fingerprint:String(e.fingerprint),status:String(e.status),result:typeof e.result_json=="string"?JSON.parse(e.result_json):null,createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}async function D(e){await x();let t=e.idempotencyKey.trim();if(t.length<8||t.length>200)throw new h("idempotency_key_invalid","Idempotency-Key must be 8-200 characters.");let n=await f().execute({sql:"SELECT * FROM gmail_action_executions WHERE owner_identity = ? AND idempotency_key = ? LIMIT 1",args:[e.ownerId,t]});if(n.rows[0]){let r=j(n.rows[0]);if(r.fingerprint!==e.fingerprint)throw new h("idempotency_conflict","This Idempotency-Key is already bound to a different Gmail action.",409);if(r.status==="running"&&!r.result&&Date.now()-Date.parse(r.updatedAt)>6e4){let a=new Date().toISOString(),s=await f().execute({sql:"UPDATE gmail_action_executions SET updated_at = ? WHERE action_id = ? AND updated_at = ?",args:[a,r.actionId,r.updatedAt]});if(Number(s.rowsAffected??0)===1)return{execution:{...r,updatedAt:a},replay:!1}}return{execution:r,replay:!0}}let i=new Date().toISOString(),o={actionId:`gact_${Y().replace(/-/g,"")}`,ownerId:e.ownerId,idempotencyKey:t,fingerprint:e.fingerprint,status:"running",result:null,createdAt:i,updatedAt:i};try{await f().execute({sql:"INSERT INTO gmail_action_executions (action_id, owner_identity, idempotency_key, fingerprint, status, created_at, updated_at) VALUES (?, ?, ?, ?, 'running', ?, ?)",args:[o.actionId,o.ownerId,o.idempotencyKey,o.fingerprint,i,i]})}catch{let r=await f().execute({sql:"SELECT * FROM gmail_action_executions WHERE owner_identity = ? AND idempotency_key = ? LIMIT 1",args:[e.ownerId,t]});if(!r.rows[0])throw new h("action_claim_failed","The Gmail action could not be claimed.",409);let a=j(r.rows[0]);if(a.fingerprint!==e.fingerprint)throw new h("idempotency_conflict","This Idempotency-Key is already bound to a different Gmail action.",409);return{execution:a,replay:!0}}return{execution:o,replay:!1}}async function M(e){await x(),await f().execute({sql:"UPDATE gmail_action_executions SET updated_at = ? WHERE action_id = ? AND status = 'running'",args:[new Date().toISOString(),e]})}function Ie(e){return{actionId:String(e.action_id),chunkKey:String(e.chunk_key),status:String(e.status),result:typeof e.result_json=="string"?JSON.parse(e.result_json):null,updatedAt:String(e.updated_at)}}async function G(e,t){await x();let n=new Date().toISOString();try{return await f().execute({sql:"INSERT INTO gmail_action_chunks (action_id, chunk_key, status, updated_at) VALUES (?, ?, 'running', ?)",args:[e,t,n]}),{receipt:{actionId:e,chunkKey:t,status:"running",result:null,updatedAt:n},claimed:!0}}catch{let i=await f().execute({sql:"SELECT * FROM gmail_action_chunks WHERE action_id = ? AND chunk_key = ? LIMIT 1",args:[e,t]});if(!i.rows[0])throw new h("action_chunk_claim_failed","The Gmail action chunk could not be claimed.",409);return{receipt:Ie(i.rows[0]),claimed:!1}}}async function S(e,t,n,i){await x(),await f().execute({sql:"UPDATE gmail_action_chunks SET status = ?, result_json = ?, updated_at = ? WHERE action_id = ? AND chunk_key = ?",args:[n,JSON.stringify(i),new Date().toISOString(),e,t]})}async function Q(e){await x();let t=await f().execute({sql:"SELECT * FROM gmail_selection_exports WHERE selection_id = ? AND owner_identity = ? LIMIT 1",args:[e.selectionId,e.ownerId]});if(t.rows[0]){let n=t.rows[0];if(String(n.fingerprint)!==e.fingerprint)throw new h("export_conflict","This Gmail selection export receipt conflicts with the stored export.",409);let i=typeof n.result_json=="string"?JSON.parse(n.result_json):null;if(i)return{replay:i,claimed:!1};if(Date.now()-Date.parse(String(n.updated_at))>5*6e4){let o=await f().execute({sql:"UPDATE gmail_selection_exports SET updated_at = ? WHERE selection_id = ? AND owner_identity = ? AND updated_at = ?",args:[new Date().toISOString(),e.selectionId,e.ownerId,String(n.updated_at)]});if(Number(o.rowsAffected??0)===1)return{replay:null,claimed:!0}}return{replay:null,claimed:!1}}try{return await f().execute({sql:"INSERT INTO gmail_selection_exports (selection_id, owner_identity, fingerprint, status, updated_at) VALUES (?, ?, ?, 'running', ?)",args:[e.selectionId,e.ownerId,e.fingerprint,new Date().toISOString()]}),{replay:null,claimed:!0}}catch{let n=await f().execute({sql:"SELECT * FROM gmail_selection_exports WHERE selection_id = ? AND owner_identity = ? LIMIT 1",args:[e.selectionId,e.ownerId]});if(!n.rows[0])throw new h("export_claim_failed","The Gmail export could not be claimed.",409);let i=n.rows[0];if(String(i.fingerprint)!==e.fingerprint)throw new h("export_conflict","This Gmail selection export receipt conflicts with the stored export.",409);return{replay:typeof i.result_json=="string"?JSON.parse(i.result_json):null,claimed:!1}}}async function ee(e,t,n){await x(),await f().execute({sql:"UPDATE gmail_selection_exports SET status = 'complete', result_json = ?, updated_at = ? WHERE selection_id = ? AND owner_identity = ?",args:[JSON.stringify(n),new Date().toISOString(),t,e]})}async function v(e,t,n){await x();let i=new Date().toISOString();await f().execute({sql:"UPDATE gmail_action_executions SET status = ?, result_json = ?, updated_at = ? WHERE action_id = ?",args:[t,JSON.stringify(n),i,e]});let o=await f().execute({sql:"SELECT * FROM gmail_action_executions WHERE action_id = ? LIMIT 1",args:[e]});if(!o.rows[0])throw new h("action_not_found","Gmail action not found.",404);return j(o.rows[0])}var we="2026-08-27.1",qe="9c82b270bb70e7795814cac408a41786ec70d4d7a4bb0f4a11bcc1b7fd02088b",N=2e4,ye=10080*60*1e3,u=class extends Error{constructor(n,i,o=400,r=o===429||o>=500,a=null){super(i);this.code=n;this.status=o;this.retryable=r;this.retryAfterMs=a;this.name="GmailServiceError"}code;status;retryable;retryAfterMs};function I(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:null}function p(e){return typeof e=="string"&&e.length>0?e:null}function T(e){return typeof e=="number"&&Number.isFinite(e)?e:null}function C(e){if(!/^[A-Za-z0-9_-]*={0,2}$/.test(e))throw new u("gmail_invalid_base64","Gmail returned invalid encoded content.",502);let t=e.replace(/-/g,"+").replace(/_/g,"/");return Buffer.from(t.padEnd(Math.ceil(t.length/4)*4,"="),"base64")}function _e(e){return/^[\x20-\x7e]*$/.test(e)?e:`=?UTF-8?B?${Buffer.from(e,"utf8").toString("base64")}?=`}function xe(e,t,n){let i=Buffer.from(n,"utf8").toString("base64").match(/.{1,76}/g)?.join(`\r
|
|
36
36
|
`)??"";return[`To: ${e}`,`Subject: ${_e(t)}`,"MIME-Version: 1.0","Content-Type: text/plain; charset=UTF-8","Content-Transfer-Encoding: base64","",i].join(`\r
|
|
37
|
-
`)}function ae(e){let t=e.toString("latin1").replace(/=\r?\n/g,""),n=[];for(let i=0;i<t.length;i++)t[i]==="="&&/^[0-9A-Fa-f]{2}$/.test(t.slice(i+1,i+3))?(n.push(Number.parseInt(t.slice(i+1,i+3),16)),i+=2):n.push(t.charCodeAt(i)&255);return Buffer.from(n)}function B(e){return e.replace(/=\?([^?]+)\?([bq])\?([^?]+)\?=/gi,(t,n,i,o)=>{try{let r=i.toLowerCase()==="b"?Buffer.from(o,"base64"):ae(Buffer.from(o.replace(/_/g," "),"latin1"));return/^(?:utf-8|us-ascii)$/i.test(n)?r.toString("utf8"):r.toString("latin1")}catch{return o}})}function Se(e){return Array.isArray(e)?e.flatMap(t=>{let n=I(t),i=p(n?.name),o=p(n?.value);return!i||o===null?[]:[{name:i,value:B(o.replace(/\r?\n[ \t]+/g," "))}]}):[]}function _(e,t){return e.find(n=>n.name.toLowerCase()===t.toLowerCase())?.value??null}function R(e){return e?(e.match(/(?:"(?:[^"\\]|\\.)*"|[^,])+/g)??[]).flatMap(n=>{let i=n.trim(),o=i.match(/^(.*?)\s*<([^<>\s]+@[^<>\s]+)>$/),r=(o?.[2]??i).replace(/^mailto:/i,"").trim().toLowerCase();if(!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(r))return[];let a=o?.[1]?.trim().replace(/^"|"$/g,"")||null;return[{name:a?B(a):null,email:r}]}):[]}function be(e,t){let n=C(e),i=_(t,"content-transfer-encoding")?.toLowerCase();if(i==="quoted-printable")return ae(n);if(i==="base64"){let o=n.toString("ascii").replace(/\s/g,"");return/^[A-Za-z0-9+/]*={0,2}$/.test(o)?Buffer.from(o,"base64"):n}return n}function Te(e){return e.replace(/<!--[\s\S]*?-->/g,"").replace(/<!doctype\b[^>]*>/gi,"").replace(/<script\b[^>]*>[\s\S]*?<\/script>/gi,"").replace(/<style\b[^>]*>[\s\S]*?<\/style>/gi,"").replace(/<(?:iframe|object|embed|svg|math)\b[^>]*>[\s\S]*?<\/(?:iframe|object|embed|svg|math)>/gi,"").replace(/<\/?(?:script|style|iframe|object|embed|svg|math|form|input|button|textarea|select|option|meta|link|base|img|audio|video|source|track)\b[^>]*>/gi,"").replace(/\son\w+\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+)/gi,"").replace(/\s(?:href|src|srcset|action|formaction|poster|background|xlink:href)\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+)/gi,"").replace(/<[^>]*>/g," ").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/\s+/g," ").trim()}function se(){return U("sha256").update(
|
|
37
|
+
`)}function ae(e){let t=e.toString("latin1").replace(/=\r?\n/g,""),n=[];for(let i=0;i<t.length;i++)t[i]==="="&&/^[0-9A-Fa-f]{2}$/.test(t.slice(i+1,i+3))?(n.push(Number.parseInt(t.slice(i+1,i+3),16)),i+=2):n.push(t.charCodeAt(i)&255);return Buffer.from(n)}function B(e){return e.replace(/=\?([^?]+)\?([bq])\?([^?]+)\?=/gi,(t,n,i,o)=>{try{let r=i.toLowerCase()==="b"?Buffer.from(o,"base64"):ae(Buffer.from(o.replace(/_/g," "),"latin1"));return/^(?:utf-8|us-ascii)$/i.test(n)?r.toString("utf8"):r.toString("latin1")}catch{return o}})}function Se(e){return Array.isArray(e)?e.flatMap(t=>{let n=I(t),i=p(n?.name),o=p(n?.value);return!i||o===null?[]:[{name:i,value:B(o.replace(/\r?\n[ \t]+/g," "))}]}):[]}function _(e,t){return e.find(n=>n.name.toLowerCase()===t.toLowerCase())?.value??null}function R(e){return e?(e.match(/(?:"(?:[^"\\]|\\.)*"|[^,])+/g)??[]).flatMap(n=>{let i=n.trim(),o=i.match(/^(.*?)\s*<([^<>\s]+@[^<>\s]+)>$/),r=(o?.[2]??i).replace(/^mailto:/i,"").trim().toLowerCase();if(!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(r))return[];let a=o?.[1]?.trim().replace(/^"|"$/g,"")||null;return[{name:a?B(a):null,email:r}]}):[]}function be(e,t){let n=C(e),i=_(t,"content-transfer-encoding")?.toLowerCase();if(i==="quoted-printable")return ae(n);if(i==="base64"){let o=n.toString("ascii").replace(/\s/g,"");return/^[A-Za-z0-9+/]*={0,2}$/.test(o)?Buffer.from(o,"base64"):n}return n}function Te(e){return e.replace(/<!--[\s\S]*?-->/g,"").replace(/<!doctype\b[^>]*>/gi,"").replace(/<script\b[^>]*>[\s\S]*?<\/script>/gi,"").replace(/<style\b[^>]*>[\s\S]*?<\/style>/gi,"").replace(/<(?:iframe|object|embed|svg|math)\b[^>]*>[\s\S]*?<\/(?:iframe|object|embed|svg|math)>/gi,"").replace(/<\/?(?:script|style|iframe|object|embed|svg|math|form|input|button|textarea|select|option|meta|link|base|img|audio|video|source|track)\b[^>]*>/gi,"").replace(/\son\w+\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+)/gi,"").replace(/\s(?:href|src|srcset|action|formaction|poster|background|xlink:href)\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+)/gi,"").replace(/<[^>]*>/g," ").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/\s+/g," ").trim()}function se(){return U("sha256").update(X()).update("\0gmail-ref-v1").digest()}function ce(e){let t=Buffer.from(JSON.stringify(e)).toString("base64url"),n=re("sha256",se()).update(t).digest("base64url");return`gref1.${t}.${n}`}function te(e,t,n){let[i,o,r]=e.split(".");if(i!=="gref1"||!o||!r)throw new u("reference_not_found","Gmail reference not found.",404,!1);let a=re("sha256",se()).update(o).digest(),s;try{s=Buffer.from(r,"base64url")}catch{throw new u("reference_not_found","Gmail reference not found.",404,!1)}if(a.length!==s.length||!he(a,s))throw new u("reference_not_found","Gmail reference not found.",404,!1);let l;try{l=JSON.parse(Buffer.from(o,"base64url").toString("utf8"))}catch{throw new u("reference_not_found","Gmail reference not found.",404,!1)}if(l.ownerId!==t||l.kind!==n||typeof l.expiresAt!="number"||l.expiresAt<=Date.now())throw new u("reference_not_found","Gmail reference not found.",404,!1);return l}function Ae(e){return ce({kind:"attachment",...e,expiresAt:Date.now()+ye})}function le(e){let t=Se(e.part.headers),n=I(e.part.body),i=p(e.part.mimeType)?.toLowerCase()??"application/octet-stream",o=B(p(e.part.filename)??""),r=p(e.part.partId)??e.path,a=p(n?.data),s=p(n?.attachmentId),l=_(t,"content-id")?.replace(/^<|>$/g,"")??null,c=/^inline\b/i.test(_(t,"content-disposition")??"")||!!l,d=i.startsWith("text/"),m=null,g=!0;d&&a?m=be(a,t).toString("utf8"):d&&s&&(g=!1);let w=!!o||!!s||c&&!!a&&!d,y=null,A=T(n?.size)??(a?C(a).byteLength:0);if(w){let E=A;y=Ae({ownerId:e.ownerId,connectionId:e.connectionId,messageId:e.messageId,partId:r,attachmentId:s,filename:o||`gmail-${e.messageId}-${r}`,mimeType:i,size:E}),e.attachments.push({filename:o||`gmail-${e.messageId}-${r}`,declaredMime:i,size:E,inline:c,contentId:l,partId:r,attachmentRef:y})}let me=Array.isArray(e.part.parts)?e.part.parts.map((E,pe)=>le({...e,part:I(E)??{},path:`${e.path}.${pe+1}`})):[];return{partId:r,mimeType:i,filename:o,headers:t,size:A,inline:c,contentId:l,contentComplete:g,text:m,attachmentRef:y,parts:me}}function z(e,t){return[...e.mimeType===t&&e.text!==null?[e.text]:[],...e.parts.flatMap(i=>z(i,t))]}function ne(e){let t=I(e.payload),n=p(t?.id),i=I(t?.payload);if(!n||!i)throw new u("gmail_invalid_message","Gmail returned an invalid message.",502);let o=[],r=le({part:i,ownerId:e.ownerId,connectionId:e.connectionId,messageId:n,path:"0",attachments:o}),a=r.headers,s=z(r,"text/plain").join(`
|
|
38
38
|
`).trim()||null,l=z(r,"text/html").join(`
|
|
39
|
-
`).trim()||null;return{messageId:n,threadId:p(t?.threadId),messageIdHeader:_(a,"message-id"),internalDate:p(t?.internalDate)?new Date(Number(t.internalDate)).toISOString():null,headers:a,from:R(_(a,"from")),to:R(_(a,"to")),cc:R(_(a,"cc")),bcc:R(_(a,"bcc")),replyTo:R(_(a,"reply-to")),subject:_(a,"subject"),labels:Array.isArray(t?.labelIds)?t.labelIds.filter(c=>typeof c=="string"):[],snippet:p(t?.snippet),plainText:s,sanitizedHtml:l?Te(l):null,contentComplete:de(r),providerSizeEstimate:T(t?.sizeEstimate),mime:r,attachments:o,provenance:{provider:"gmail",connectionId:e.connectionId,fetchedAt:(e.fetchedAt??new Date).toISOString(),format:"full"}}}function de(e){return e.contentComplete&&e.parts.every(de)}var ie=class{providerCall;createArtifact;createJsonlArtifact;constructor(t={}){this.providerCall=t.providerCall??K,this.createArtifact=t.createArtifact??
|
|
39
|
+
`).trim()||null;return{messageId:n,threadId:p(t?.threadId),messageIdHeader:_(a,"message-id"),internalDate:p(t?.internalDate)?new Date(Number(t.internalDate)).toISOString():null,headers:a,from:R(_(a,"from")),to:R(_(a,"to")),cc:R(_(a,"cc")),bcc:R(_(a,"bcc")),replyTo:R(_(a,"reply-to")),subject:_(a,"subject"),labels:Array.isArray(t?.labelIds)?t.labelIds.filter(c=>typeof c=="string"):[],snippet:p(t?.snippet),plainText:s,sanitizedHtml:l?Te(l):null,contentComplete:de(r),providerSizeEstimate:T(t?.sizeEstimate),mime:r,attachments:o,provenance:{provider:"gmail",connectionId:e.connectionId,fetchedAt:(e.fetchedAt??new Date).toISOString(),format:"full"}}}function de(e){return e.contentComplete&&e.parts.every(de)}var ie=class{providerCall;createArtifact;createJsonlArtifact;constructor(t={}){this.providerCall=t.providerCall??K,this.createArtifact=t.createArtifact??H,this.createJsonlArtifact=t.createJsonlArtifact??J}async sendMessage(t){let n=t.to.trim().toLowerCase(),i=t.subject.trim();if(!/^[^\s@<>]+@[^\s@<>]+\.[^\s@<>]+$/.test(n)||/[\r\n]/.test(t.to))throw new u("invalid_request","A valid recipient email address is required.");if(!i||i.length>500||/[\r\n]/.test(i))throw new u("invalid_request","A subject of at most 500 characters without line breaks is required.");if(!t.body||t.body.length>5e4)throw new u("invalid_request","A plain-text body of at most 50,000 characters is required.");if(t.idempotencyKey.length<8||t.idempotencyKey.length>200)throw new u("idempotency_key_invalid","Idempotency key must contain 8-200 characters.");let o=b({connectionId:t.connectionId,to:n,subject:i,bodySha256:U("sha256").update(t.body).digest("hex")}),r=await D({ownerId:t.ownerId,idempotencyKey:t.idempotencyKey,fingerprint:o});if(r.replay&&r.execution.result)return{...r.execution.result,replay:!0};if(r.replay)return{actionId:r.execution.actionId,status:"outcome_unknown",replay:!0,retryable:!1};let a=await G(r.execution.actionId,"send:0");if(!a.claimed)return{...a.receipt.result??{},actionId:r.execution.actionId,status:a.receipt.status,replay:!0};try{let s=I(await this.providerCall({identity:t.providerIdentity??t.ownerId,connectionId:t.connectionId,method:"POST",path:"/gmail/v1/users/me/messages/send",body:{raw:Buffer.from(xe(n,i,t.body),"utf8").toString("base64url")},requestId:t.idempotencyKey})),l={actionId:r.execution.actionId,status:"complete",messageId:p(s?.id),threadId:p(s?.threadId),replay:!1};return await S(r.execution.actionId,"send:0","complete",l),await v(r.execution.actionId,"complete",l),l}catch(s){let l={actionId:r.execution.actionId,status:"outcome_unknown",code:q(s),retryable:!1};throw await S(r.execution.actionId,"send:0","failed",l),await v(r.execution.actionId,"partial",l),s}}async searchMessages(t){let n=t.query.trim();if(!n||n.length>2e3)throw new u("invalid_request","A Gmail query of at most 2,000 characters is required.");let i=t.limit??25;if(!Number.isInteger(i)||i<1||i>500)throw new u("invalid_request","Gmail search limit must be an integer from 1 to 500.");let o=i,r;if(t.cursor){let c=te(t.cursor,t.ownerId,"search_cursor");if(c.connectionId!==t.connectionId||c.query!==n)throw new u("cursor_not_found","Gmail cursor not found.",404,!1);r=p(c.pageToken)??void 0}let a=I(await this.providerCall({identity:t.providerIdentity??t.ownerId,connectionId:t.connectionId,method:"GET",path:"/gmail/v1/users/me/messages",query:{q:n,maxResults:o,pageToken:r}})),s=Array.isArray(a?.messages)?a.messages.flatMap(c=>{let d=I(c),m=p(d?.id);return m?[{messageId:m,threadId:p(d?.threadId)}]:[]}):[],l=p(a?.nextPageToken);return{messages:s,estimatedMatches:T(a?.resultSizeEstimate),complete:!l,truncated:!!l,nextCursor:l?ce({kind:"search_cursor",ownerId:t.ownerId,connectionId:t.connectionId,query:n,pageToken:l,expiresAt:Date.now()+1440*60*1e3}):null}}async getMessage(t){let n=await this.getCompleteMessage(t),i=!!n.canonicalArtifact,o=n.plainText&&Buffer.byteLength(n.plainText)>N?`${Buffer.from(n.plainText).subarray(0,N).toString("utf8")}\u2026`:n.plainText;return{...n,plainText:o,contentComplete:n.contentComplete&&!i}}async getCompleteMessage(t){if(!/^[A-Za-z0-9_-]+$/.test(t.messageId))throw new u("invalid_request","A valid Gmail message ID is required.");let n=encodeURIComponent(t.messageId),i=t.providerIdentity??t.ownerId,o=await this.providerCall({identity:i,connectionId:t.connectionId,method:"GET",path:`/gmail/v1/users/me/messages/${n}`,query:{format:"full"}}),r=ne({ownerId:t.ownerId,connectionId:t.connectionId,payload:o}),a=null;if(t.includeRawArtifact!==!1){let d=I(await this.providerCall({identity:i,connectionId:t.connectionId,method:"GET",path:`/gmail/v1/users/me/messages/${n}`,query:{format:"raw"}})),m=p(d?.raw);if(!m)throw new u("gmail_raw_unavailable","Gmail did not return the raw message.",502);a=await this.createArtifact({ownerId:t.ownerId,exportId:`gmail-raw-${t.messageId}`,filename:`${t.messageId}.eml`,content:C(m),contentType:"message/rfc822"})}let s=JSON.stringify(r),c=Buffer.byteLength(s)>N||!r.contentComplete?await this.createArtifact({ownerId:t.ownerId,exportId:`gmail-message-${t.messageId}`,filename:`${t.messageId}.json`,content:s,contentType:"application/json"}):null;return{...r,rawArtifact:a,canonicalArtifact:c}}async getAttachment(t){let n=te(t.attachmentRef,t.ownerId,"attachment"),i=p(n.connectionId),o=p(n.messageId);if(!i||!o)throw new u("reference_not_found","Gmail reference not found.",404,!1);let r,a=p(n.attachmentId);if(a){let w=I(await this.providerCall({identity:t.providerIdentity??t.ownerId,connectionId:i,method:"GET",path:`/gmail/v1/users/me/messages/${encodeURIComponent(o)}/attachments/${encodeURIComponent(a)}`})),y=p(w?.data);if(!y)throw new u("gmail_attachment_unavailable","Gmail did not return attachment bytes.",502);r=C(y);let A=T(w?.size);if(A!==null&&A!==r.byteLength)throw new u("gmail_attachment_size_mismatch","Gmail attachment bytes did not match the declared size.",502)}else{let w=I(await this.providerCall({identity:t.providerIdentity??t.ownerId,connectionId:i,method:"GET",path:`/gmail/v1/users/me/messages/${encodeURIComponent(o)}`,query:{format:"full"}})),y=ue(I(w?.payload),p(n.partId)??"");if(!y)throw new u("reference_not_found","Gmail reference not found.",404,!1);r=C(y)}let s=p(n.mimeType)??"application/octet-stream",l=T(n.size);if(l!==null&&l>0&&l!==r.byteLength)throw new u("gmail_attachment_size_mismatch","Gmail attachment bytes did not match the reviewed MIME part size.",502);let c=Ge(r,s),d=p(n.filename)??`gmail-${o}.bin`,m=await this.createArtifact({ownerId:t.ownerId,exportId:`gmail-attachment-${o}`,filename:d,content:r,contentType:c}),g=c.startsWith("text/")||c==="application/json"?r.subarray(0,N).toString("utf8"):null;return{filename:d,declaredMime:s,observedMime:c,bytes:r.byteLength,sha256:U("sha256").update(r).digest("hex"),contentComplete:g!==null?r.byteLength<=N:!0,text:g,artifact:m}}async prepareSelection(t){let n,i=null;if(t.source.kind==="message_ids"){if(!t.source.messageIds.length||t.source.messageIds.some(o=>typeof o!="string"||!/^[A-Za-z0-9_-]+$/.test(o.trim())))throw new u("invalid_request","Every explicit Gmail message ID must be valid.");n=[...new Set(t.source.messageIds.map(o=>o.trim()))];for(let o of n)try{await this.providerCall({identity:t.providerIdentity??t.ownerId,connectionId:t.connectionId,method:"GET",path:`/gmail/v1/users/me/messages/${encodeURIComponent(o)}`,query:{format:"metadata"}})}catch{throw new u("selection_message_not_found","One or more explicit Gmail message IDs do not exist in this connection.",404,!1)}}else{n=[];let o,r=null;do{let a=I(await this.providerCall({identity:t.providerIdentity??t.ownerId,connectionId:t.connectionId,method:"GET",path:"/gmail/v1/users/me/messages",query:{q:t.source.query.trim(),maxResults:500,pageToken:o}}));r===null&&(r=T(a?.resultSizeEstimate));for(let s of Array.isArray(a?.messages)?a.messages:[]){let l=p(I(s)?.id);l&&n.push(l)}if(new Set(n).size>5e3)throw new u("selection_too_large","Narrow the Gmail selection to at most 5,000 messages.");o=p(a?.nextPageToken)??void 0}while(o);if(t.exactRange){let a=Date.parse(t.exactRange.from),s=Date.parse(t.exactRange.to);if(!Number.isFinite(a)||!Number.isFinite(s)||a>=s)throw new u("invalid_request","exactRange.from must be before exactRange.to.");let l=[];for(let c of n){let d=await this.providerCall({identity:t.providerIdentity??t.ownerId,connectionId:t.connectionId,method:"GET",path:`/gmail/v1/users/me/messages/${encodeURIComponent(c)}`,query:{format:"full"}}),m=ne({ownerId:t.ownerId,connectionId:t.connectionId,payload:d}),g=m.internalDate?Date.parse(m.internalDate):Number.NaN;Number.isFinite(g)&&g>=a&&g<s&&l.push(c)}n=l}i={estimatedMatches:r,pagesComplete:!0,...t.exactRange?{exactRange:t.exactRange}:{}}}return Z({ownerId:t.ownerId,connectionId:t.connectionId,source:t.source,purpose:t.purpose,resolvedMessageIds:n,providerSnapshot:i})}async exportSelection(t){let n=await L(t);if(n.purpose!=="export"&&n.purpose!=="scheduled_export")throw new u("selection_purpose_mismatch","This Gmail selection was not prepared for export.",409,!1);O(n,t.expectedCount,t.selectionSha256);let i=b({selectionId:n.selectionId,selectionSha256:n.selectionSha256,expectedCount:n.count}),o=await Q({ownerId:t.ownerId,selectionId:n.selectionId,fingerprint:i});if(o.replay)return{...o.replay,replay:!0};if(!o.claimed)throw new u("export_in_progress","This Gmail selection export is already running; retry shortly with the same receipt.",409,!0);let r=[];for(let m of n.messageIds)r.push(await this.getCompleteMessage({ownerId:t.ownerId,providerIdentity:t.providerIdentity,connectionId:t.connectionId,messageId:m}));let a=`gexp_${n.selectionSha256.slice(0,32)}`,s={version:we,selectionId:n.selectionId,selectionSha256:n.selectionSha256,count:r.length},l=[JSON.stringify({type:"manifest",...s}),...r.map(m=>JSON.stringify({type:"message",message:m}))].join(`
|
|
40
40
|
`)+`
|
|
41
41
|
`,c=await this.createJsonlArtifact({ownerId:t.ownerId,exportId:a,filename:`gmail-${n.selectionId}.jsonl`,content:l,stableCreatedAt:n.createdAt,stableKey:i.slice(0,32)}),d={exportId:a,selectionId:n.selectionId,selectionSha256:n.selectionSha256,count:r.length,status:"complete",artifact:c,sampleMessages:r.slice(0,5).map(ke)};return await ee(t.ownerId,n.selectionId,d),d}async bulkManageSelection(t){let n=await L(t);if(n.purpose!=="mailbox_action")throw new u("selection_purpose_mismatch","This Gmail selection was not prepared for mailbox actions.",409,!1);O(n,t.expectedCount,t.selectionSha256);let i=b({selectionSha256:n.selectionSha256,operation:t.operation}),o=await D({ownerId:t.ownerId,idempotencyKey:t.idempotencyKey,fingerprint:i});if(o.replay&&o.execution.result)return o.execution.result;if(o.replay)return{actionId:o.execution.actionId,selectionId:n.selectionId,status:"running",changedCount:0,failedCount:0,failedChunks:[],retryable:!0};let r=[],a=0,s=Ee(t.operation);if(s.mode==="batch"){s.validateIds.length&&await this.validateLabels(t.providerIdentity??t.ownerId,t.connectionId,s.validateIds);let c=oe(n.messageIds,1e3);for(let d=0;d<c.length;d++){await M(o.execution.actionId);let m=`batch:${d}`,g=await G(o.execution.actionId,m);if(!g.claimed){g.receipt.status==="complete"?a+=Number(g.receipt.result?.changedCount??c[d].length):r.push({chunk:d,code:g.receipt.status==="failed"?String(g.receipt.result?.code??"provider_error"):"outcome_unknown"});continue}try{await this.providerCall({identity:t.providerIdentity??t.ownerId,connectionId:t.connectionId,method:"POST",path:"/gmail/v1/users/me/messages/batchModify",body:{ids:c[d],addLabelIds:s.addLabelIds,removeLabelIds:s.removeLabelIds},requestId:`${t.idempotencyKey}:${d}`}),a+=c[d].length,await S(o.execution.actionId,m,"complete",{changedCount:c[d].length})}catch(w){let y=q(w);r.push({chunk:d,code:y}),await S(o.execution.actionId,m,"failed",{code:y})}}}else for(let c=0;c<n.messageIds.length;c++){await M(o.execution.actionId);let d=`single:${c}`,m=await G(o.execution.actionId,d);if(!m.claimed){m.receipt.status==="complete"?a+=1:r.length<20&&r.push({chunk:c,code:m.receipt.status==="failed"?String(m.receipt.result?.code??"provider_error"):"outcome_unknown"});continue}try{await this.providerCall({identity:t.providerIdentity??t.ownerId,connectionId:t.connectionId,method:"POST",path:`/gmail/v1/users/me/messages/${encodeURIComponent(n.messageIds[c])}/${s.path}`,body:{},requestId:`${t.idempotencyKey}:${c}`}),a+=1,await S(o.execution.actionId,d,"complete",{changedCount:1})}catch(g){let w=q(g);r.length<20&&r.push({chunk:c,code:w}),await S(o.execution.actionId,d,"failed",{code:w})}}let l={actionId:o.execution.actionId,selectionId:n.selectionId,status:r.length?"partial":"complete",changedCount:a,failedCount:n.count-a,failedChunks:r.slice(0,20)};return await v(o.execution.actionId,r.length?"partial":"complete",l),l}async permanentlyDeleteSelection(t){if(t.confirmPermanentDelete!==!0)throw new u("permanent_delete_confirmation_required","Set confirmPermanentDelete to true after explicit user confirmation.");let n=await L(t);if(O(n,t.expectedCount,t.selectionSha256),n.purpose!=="mailbox_action")throw new u("selection_purpose_mismatch","This Gmail selection was not prepared for mailbox actions.",409,!1);let i=b({selectionSha256:n.selectionSha256,operation:"permanent_delete"}),o=await D({ownerId:t.ownerId,idempotencyKey:t.idempotencyKey,fingerprint:i});if(o.replay&&o.execution.result)return o.execution.result;if(o.replay)return{actionId:o.execution.actionId,selectionId:n.selectionId,status:"running",submittedCount:0,failedCount:0,failedChunks:[],retryable:!0,providerGuarantee:"The original permanent-delete attempt is still being finalized; no provider chunk was replayed."};let r=[],a=0,s=oe(n.messageIds,1e3);for(let c=0;c<s.length;c++){await M(o.execution.actionId);let d=`delete:${c}`,m=await G(o.execution.actionId,d);if(!m.claimed){m.receipt.status==="complete"?a+=Number(m.receipt.result?.submittedCount??s[c].length):r.push({chunk:c,code:m.receipt.status==="failed"?String(m.receipt.result?.code??"provider_error"):"outcome_unknown"});continue}try{await this.providerCall({identity:t.providerIdentity??t.ownerId,connectionId:t.connectionId,method:"POST",path:"/gmail/v1/users/me/messages/batchDelete",body:{ids:s[c]},requestId:`${t.idempotencyKey}:${c}`}),a+=s[c].length,await S(o.execution.actionId,d,"complete",{submittedCount:s[c].length})}catch(g){let w=q(g);r.push({chunk:c,code:w}),await S(o.execution.actionId,d,"failed",{code:w})}}let l={actionId:o.execution.actionId,selectionId:n.selectionId,status:r.length?"partial":"complete",submittedCount:a,failedCount:n.count-a,failedChunks:r.slice(0,20),providerGuarantee:"Gmail accepts batch deletion but does not report whether every supplied message previously existed."};return await v(o.execution.actionId,r.length?"partial":"complete",l),l}async validateLabels(t,n,i){let o=I(await this.providerCall({identity:t,connectionId:n,method:"GET",path:"/gmail/v1/users/me/labels"})),r=new Set((Array.isArray(o?.labels)?o.labels:[]).map(s=>p(I(s)?.id)).filter(s=>!!s));if(i.filter(s=>!r.has(s)).length)throw new u("gmail_label_not_found","One or more Gmail label IDs were not found.",404,!1)}};function Ee(e){if(e.kind==="trash")return{mode:"single",path:"trash"};if(e.kind==="restore")return{mode:"single",path:"untrash"};if(e.kind==="labels"){let n=[...new Set(e.addLabelIds??[])],i=[...new Set(e.removeLabelIds??[])];if(!n.length&&!i.length)throw new u("invalid_request","At least one label must be added or removed.");if(n.some(o=>i.includes(o)))throw new u("invalid_request","The same label cannot be added and removed.");return{mode:"batch",addLabelIds:n,removeLabelIds:i,validateIds:[...n,...i]}}return{mode:"batch",...{mark_read:{addLabelIds:[],removeLabelIds:["UNREAD"]},mark_unread:{addLabelIds:["UNREAD"],removeLabelIds:[]},archive:{addLabelIds:[],removeLabelIds:["INBOX"]},move_to_inbox:{addLabelIds:["INBOX"],removeLabelIds:[]}}[e.kind],validateIds:[]}}function oe(e,t){let n=[];for(let i=0;i<e.length;i+=t)n.push(e.slice(i,i+t));return n}function q(e){return e&&typeof e=="object"&&typeof e.code=="string"?String(e.code):"provider_error"}function ke(e){return{messageId:e.messageId,threadId:e.threadId,internalDate:e.internalDate,from:e.from,to:e.to,subject:e.subject,snippet:e.snippet,labels:e.labels,attachmentCount:e.attachments.length}}function ue(e,t){if(!e)return null;if(p(e.partId)===t)return p(I(e.body)?.data);for(let n of Array.isArray(e.parts)?e.parts:[]){let i=ue(I(n),t);if(i!==null)return i}return null}function Ge(e,t){if(e.subarray(0,5).toString("ascii")==="%PDF-")return"application/pdf";if(e.subarray(0,4).equals(Buffer.from([80,75,3,4])))return"application/zip";if(e.subarray(0,8).equals(Buffer.from([137,80,78,71,13,10,26,10])))return"image/png";if(e.subarray(0,3).equals(Buffer.from([255,216,255])))return"image/jpeg";if(t.startsWith("text/"))try{return new TextDecoder("utf-8",{fatal:!0}).decode(e),t}catch{return"application/octet-stream"}if(t==="application/json")try{return JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(e)),t}catch{return"application/octet-stream"}return"application/octet-stream"}export{h as a,b,L as c,O as d,we as e,qe as f,N as g,ye as h,u as i,R as j,ne as k,ie as l};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var
|
|
1
|
+
var s={message:"SERP now returns directly within a ten-second server deadline, while durable PAA keeps one 400-second lifetime, bounded retries, and visible phase timing."};var _={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?`${_[e]}${t}${_.reset}`:t}function o(t,e,n){let a=t.padEnd(9," ");return` ${r(a,"muted",n)} ${e.join(r(" . ","muted",n))}`}function p(t){let e=t.color??!0,n=t.apiKeyConfigured?"$MCP_SCRAPER_API_KEY":"sk_live_your_key",a=String.raw`
|
|
2
2
|
__ __ ____ ____
|
|
3
3
|
| \/ |/ ___| _ \
|
|
4
4
|
| |\/| | | | |_) |
|
|
@@ -10,7 +10,7 @@ var a={message:"Subscription checkout now recovers from interrupted webhooks, ve
|
|
|
10
10
|
\___ \| | | |_) | / _ \ | |_) | _| | |_) |
|
|
11
11
|
___) | |___| _ < / ___ \| __/| |___| _ <
|
|
12
12
|
|____/ \____|_| \_\/_/ \_\_| |_____|_| \_\
|
|
13
|
-
`,
|
|
14
|
-
`),
|
|
15
|
-
`);return[r(`mcp-scraper v${t.version}`,"bold",e),r("> mcp-scraper-install","muted",e),r(
|
|
13
|
+
`,i=[`MCP_SCRAPER_API_KEY=${n} npx -y -p mcp-scraper@latest \\`," mcp-scraper-cli agent install claude --apply"].join(`
|
|
14
|
+
`),c=["[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}: ${s.message}`,"lime",e),"",`${r("Tools","cyan",e)} ${r("(378 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","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-scheduled-actions"],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","scheduled runs"],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),i,"Then fully exit Claude Code and open a new Claude terminal. Check with: claude mcp list","",r("Codex config","amber",e),c,"",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
16
|
`)}export{p as a};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as j,b as T,c as P,d as C,f as S}from"./chunk-TMB56NCA.js";import{W as w}from"./chunk-
|
|
1
|
+
import{a as j,b as T,c as P,d as C,f as S}from"./chunk-TMB56NCA.js";import{W as w}from"./chunk-E4ME7J6G.js";import{Jb as N,Sb as D,d as m,e as I,i as u,t as s}from"./chunk-7BEWBRMT.js";import{createHash as W}from"crypto";import{gunzipSync as $,gzipSync as q}from"zlib";var y="site-extracts/",L=10080*60*1e3,H=900*1e3;function U(){return process.env.SITE_EXTRACT_ARTIFACT_READ_WRITE_TOKEN?.trim()||process.env.PRIVATE_ARTIFACT_READ_WRITE_TOKEN?.trim()||process.env.CONNECTED_DATA_READ_WRITE_TOKEN?.trim()||process.env.CONNECTED_DATA_BLOB_READ_WRITE_TOKEN?.trim()||null}function v(){return process.env.VERCEL==="1"||process.env.NODE_ENV==="production"}function p(){return{prefix:y,artifactTtlMs:L,downloadTtlMs:H,token:U()}}function h(t){return j(t,y)}async function V(t){let e=await P({policy:p(),ownerId:t.ownerId,artifactKey:`${t.jobId}.zip`,createdAt:t.createdAt,filename:`${t.jobId}-site-export.zip`,contentType:"application/zip",content:t.content});return{key:e.artifactId,url:e.downloadUrl??"",bytes:e.bytes,contentType:e.contentType,filename:e.filename,sha256:e.sha256,expiresAt:e.expiresAt,downloadUrlExpiresAt:e.downloadUrlExpiresAt,kind:"bundle"}}async function G(t){let e=await T({policy:p(),ownerId:t.ownerId,scopeSegments:[t.jobId,"images"],artifactKey:`${t.imageId}.bin`,createdAt:new Date,filename:t.filename,contentType:t.contentType,content:t.content});return{key:e.artifactId,url:e.downloadUrl??"",bytes:e.bytes,contentType:e.contentType,filename:e.filename,sha256:e.sha256,expiresAt:e.expiresAt,downloadUrlExpiresAt:e.downloadUrlExpiresAt,kind:"image",imageId:t.imageId,sourceUrl:t.sourceUrl,sourcePage:t.sourcePage}}async function O(t){return T({policy:p(),ownerId:t.ownerId,scopeSegments:[t.jobId,"content"],artifactKey:`${t.chunkKey}.json.gz`,createdAt:t.createdAt,filename:`${t.chunkKey}.json.gz`,contentType:"application/gzip",content:t.content})}async function Q(t){return C({policy:p(),artifactId:t.artifactId,ownerId:t.ownerId})}async function J(t){return S({policy:p(),artifactId:t,maxBytes:50*1024*1024})}async function Z(t){return h(t.artifactId)!==t.ownerId?null:J(t.artifactId)}async function k(t){return h(t.artifactId)!==t.ownerId?null:S({policy:p(),artifactId:t.artifactId,maxBytes:25*1024*1024})}async function tt(t){return h(t.artifactId)!==t.ownerId?null:S({policy:p(),artifactId:t.artifactId,maxBytes:10*1024*1024})}async function et(t={}){let e=t.now??new Date,n=U();if(!n)return{deleted:0,store:v()?"none":"local"};if(!t.force&&!(e.getUTCHours()===3&&e.getUTCMinutes()===21))return{deleted:0,store:"private-vercel-blob",skipped:!0};let r=e.getTime()-L,{list:i,del:a}=await import("@vercel/blob"),o,c=0;for(let d=0;d<20;d+=1){let l=await i({prefix:y,token:n,limit:1e3,cursor:o}),f=l.blobs.filter(A=>new Date(A.uploadedAt).getTime()<=r);if(f.length>0&&(await a(f.map(A=>A.pathname),{token:n}),c+=f.length),!l.hasMore||!l.cursor)break;o=l.cursor}return{deleted:c,store:"private-vercel-blob"}}var F=10,b=20*1024*1024;function E(t){return W("sha256").update(t).digest("hex")}function B(t){return!t.acquiredHtml||t.extractionStatus==="failed"?null:{pageId:t.pageId??E(t.archivedUrl??t.url),url:t.archivedUrl??t.url,html:t.acquiredHtml,mainHtml:t.mainHtml??"",markdown:t.bodyMarkdown,htmlSha256:t.htmlSha256??E(t.acquiredHtml),markdownSha256:t.markdownSha256??E(t.bodyMarkdown)}}function R(t){return Buffer.from(JSON.stringify({version:"site-extract-content.v1",pages:t}))}async function M(t){let e=t.pages.flatMap(o=>{let c=B(o);return c?[c]:[]}),n=new Map,r=[],i=0,a=async()=>{if(!r.length)return;let o=R(r);if(o.length>b)throw new Error(`site export content chunk exceeds ${b} bytes`);let c=E(r.map(l=>l.pageId).join("\0")).slice(0,16),d=await O({ownerId:t.ownerId,jobId:t.jobId,createdAt:t.createdAt,chunkKey:`content-${String(i).padStart(4,"0")}-${c}`,content:q(o,{level:6})});for(let l of r)n.set(l.url,{artifactId:d.artifactId,artifactSha256:d.sha256,pageId:l.pageId,uncompressedBytes:o.length});i++,r=[]};for(let o of e){let c=[...r,o];if(r.length>0&&(c.length>F||R(c).length>b)&&await a(),r.push(o),R(r).length>b)throw new Error(`page ${o.pageId} exceeds the durable content chunk limit`)}return await a(),n}function it(t){let e=new Map;return async n=>{let r=e.get(n.artifactId);if(!r){let a=await k({artifactId:n.artifactId,ownerId:t});if(!a)throw new Error("site export content chunk is missing or unauthorized");if(E(a)!==n.artifactSha256)throw new Error("site export content chunk checksum mismatch");let o=$(a);if(o.length>b)throw new Error("site export content chunk exceeds its read limit");if(r=JSON.parse(o.toString("utf8")),r.version!=="site-extract-content.v1"||!Array.isArray(r.pages))throw new Error("site export content chunk has an unsupported contract");for(e.set(n.artifactId,r);e.size>2;)e.delete(e.keys().next().value)}let i=r.pages.find(a=>a.pageId===n.pageId);if(!i)throw new Error("site export page is missing from its content chunk");if(E(i.html)!==i.htmlSha256||E(i.markdown)!==i.markdownSha256)throw new Error("site export page checksum mismatch");return i}}var g="xray_entitlement";function pt(t){let e=Math.max(1,Number(t.options.effectiveMaxPages??t.options.maxPages??1)),n=Math.max(e,Number(t.options.requestedMaxPages??e)),r=n>e;return{requestedMaxPages:n,effectiveMaxPages:e,creditLimited:r,creditTruncated:r&&t.totalUrls>=e}}function Et(t,e=!1){return t.successfulUrls===0?"failed":t.failedUrls>0||t.remainingUrls>0||e?"partial":"complete"}function _(t){let e=Number(t.total_urls??0),n=t.attempted_urls==null,r=Number(n?t.done_urls??0:t.attempted_urls),i=Number(n?t.done_urls??0:t.successful_urls??0),a=Number(t.failed_urls??Math.max(0,r-i));return{id:String(t.id),userId:t.user_id!=null?Number(t.user_id):null,idempotencyKey:t.idempotency_key!=null?String(t.idempotency_key):null,requestFingerprint:t.request_fingerprint!=null?String(t.request_fingerprint):null,status:t.status!=null?String(t.status):"pending",startUrl:String(t.start_url??""),options:t.options?JSON.parse(String(t.options)):{},totalUrls:e,doneUrls:r,attemptedUrls:r,successfulUrls:i,failedUrls:a,remainingUrls:Math.max(0,e-r),artifacts:t.artifacts?JSON.parse(String(t.artifacts)):null,error:t.error!=null?String(t.error):null,publicError:I(t.public_error_json),billedMc:t.billed_mc!=null?Number(t.billed_mc):null,createdAt:String(t.created_at??""),updatedAt:String(t.updated_at??"")}}async function mt(t,e,n,r){await s().execute({sql:`INSERT INTO site_extract_jobs (id, user_id, status, start_url, options, created_at, updated_at)
|
|
2
2
|
VALUES (?, ?, 'pending', ?, ?, datetime('now'), datetime('now'))`,args:[t,e,n,JSON.stringify(r)]})}async function K(t,e){let r=await s().execute({sql:"SELECT * FROM site_extract_jobs WHERE user_id = ? AND idempotency_key = ? LIMIT 1",args:[t,e]});return r.rows[0]?_(r.rows[0]):null}async function gt(t){let n=await s().execute({sql:`INSERT OR IGNORE INTO site_extract_jobs
|
|
3
3
|
(id, user_id, status, start_url, options, idempotency_key, request_fingerprint, created_at, updated_at)
|
|
4
4
|
VALUES (?, ?, 'pending', ?, ?, ?, ?, datetime('now'), datetime('now'))`,args:[t.jobId,t.userId,t.startUrl,JSON.stringify(t.options),t.idempotencyKey,t.requestFingerprint]}),r=await K(t.userId,t.idempotencyKey);if(!r)throw new Error("idempotent extract job was not persisted");return{job:r,created:n.rowsAffected===1,conflict:r.requestFingerprint!==t.requestFingerprint}}async function x(t){let n=await s().execute({sql:"SELECT * FROM site_extract_jobs WHERE id = ?",args:[t]});return n.rows[0]?_(n.rows[0]):null}async function _t(t){return(await s().execute({sql:"SELECT * FROM site_extract_jobs WHERE user_id = ? ORDER BY created_at DESC LIMIT 50",args:[t]})).rows.map(r=>_(r))}async function xt(t=25){return(await s().execute({sql:`SELECT * FROM site_extract_jobs
|