mcp-scraper 0.3.25 → 0.3.27
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/dist/bin/api-server.cjs +2439 -346
- package/dist/bin/api-server.cjs.map +1 -1
- package/dist/bin/api-server.js +2 -2
- package/dist/bin/mcp-scraper-cli.cjs +1 -1
- package/dist/bin/mcp-scraper-cli.cjs.map +1 -1
- package/dist/bin/mcp-scraper-cli.js +1 -1
- package/dist/bin/mcp-scraper-install.cjs +2 -2
- package/dist/bin/mcp-scraper-install.cjs.map +1 -1
- package/dist/bin/mcp-scraper-install.js +2 -2
- package/dist/bin/mcp-stdio-server.cjs +88 -33
- package/dist/bin/mcp-stdio-server.cjs.map +1 -1
- package/dist/bin/mcp-stdio-server.js +10 -1357
- package/dist/bin/mcp-stdio-server.js.map +1 -1
- package/dist/bin/paa-harvest.cjs +1 -1
- package/dist/bin/paa-harvest.cjs.map +1 -1
- package/dist/bin/paa-harvest.js +1 -1
- package/dist/{chunk-FE2WC4JR.js → chunk-6KHGYJIT.js} +1431 -35
- package/dist/chunk-6KHGYJIT.js.map +1 -0
- package/dist/chunk-DYV72F6A.js +7 -0
- package/dist/chunk-DYV72F6A.js.map +1 -0
- package/dist/{chunk-WYCER2HW.js → chunk-H74L743B.js} +12 -11
- package/dist/chunk-H74L743B.js.map +1 -0
- package/dist/{chunk-G7PQ64LM.js → chunk-QSSH4RCX.js} +2 -2
- package/dist/chunk-QSSH4RCX.js.map +1 -0
- package/dist/{chunk-DOBQN3EY.js → chunk-T3VZD2I4.js} +2 -2
- package/dist/{chunk-DOBQN3EY.js.map → chunk-T3VZD2I4.js.map} +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/{server-RRCKVBHG.js → server-KUNOK47B.js} +695 -29
- package/dist/server-KUNOK47B.js.map +1 -0
- package/dist/{worker-UC6D2756.js → worker-NV4GTIRG.js} +3 -3
- package/docs/spec-kernel-computer-controls.md +166 -0
- package/docs/spec-server-instructions.md +94 -0
- package/package.json +1 -1
- package/dist/chunk-FE2WC4JR.js.map +0 -1
- package/dist/chunk-G7PQ64LM.js.map +0 -1
- package/dist/chunk-WPHAMNT7.js +0 -7
- package/dist/chunk-WPHAMNT7.js.map +0 -1
- package/dist/chunk-WYCER2HW.js.map +0 -1
- package/dist/server-RRCKVBHG.js.map +0 -1
- /package/dist/{worker-UC6D2756.js.map → worker-NV4GTIRG.js.map} +0 -0
|
@@ -53,7 +53,7 @@ function renderInstallTerminal(options) {
|
|
|
53
53
|
"1/1 install surfaces ready",
|
|
54
54
|
colorize("Newest: saved browser profiles that hold MANY site logins. Share the watch_url, user signs in, then verify with browser_profile_list. Browser sessions are direct/no-proxy by default.", "lime", color),
|
|
55
55
|
"",
|
|
56
|
-
`${colorize("Tools", "cyan", color)} ${colorize("(
|
|
56
|
+
`${colorize("Tools", "cyan", color)} ${colorize("(48 MCP tools)", "muted", color)}`,
|
|
57
57
|
toolRow("search", ["harvest_paa", "search_serp", "maps_search", "maps_place_intel"], color),
|
|
58
58
|
toolRow("extract", ["extract_url", "map_site_urls", "extract_site", "audit_site", "directory_workflow"], color),
|
|
59
59
|
toolRow("build", ["rank_tracker_workflow", "cron plan", "database prompt"], color),
|
|
@@ -101,7 +101,7 @@ function renderInstallTerminal(options) {
|
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
// src/version.ts
|
|
104
|
-
var PACKAGE_VERSION = "0.3.
|
|
104
|
+
var PACKAGE_VERSION = "0.3.27";
|
|
105
105
|
|
|
106
106
|
// bin/mcp-scraper-install.ts
|
|
107
107
|
var noColor = process.argv.includes("--no-color") || process.env.NO_COLOR !== void 0 || process.env.FORCE_COLOR === "0" || !process.stdout.isTTY;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/install-terminal.ts","../../src/version.ts","../../bin/mcp-scraper-install.ts"],"sourcesContent":["export interface InstallTerminalOptions {\n color?: boolean\n version: string\n apiKeyConfigured?: boolean\n}\n\ntype Tone = 'cyan' | 'lime' | 'amber' | 'red' | 'muted' | 'bold'\n\nconst CODES: Record<Tone | 'reset', string> = {\n reset: '\\x1b[0m',\n cyan: '\\x1b[36m',\n lime: '\\x1b[32m',\n amber: '\\x1b[33m',\n red: '\\x1b[31m',\n muted: '\\x1b[90m',\n bold: '\\x1b[1m',\n}\n\nfunction colorize(value: string, tone: Tone, enabled: boolean): string {\n if (!enabled) return value\n return `${CODES[tone]}${value}${CODES.reset}`\n}\n\nfunction toolRow(label: string, tools: string[], enabled: boolean): string {\n const padded = label.padEnd(9, ' ')\n return ` ${colorize(padded, 'muted', enabled)} ${tools.join(colorize(' . ', 'muted', enabled))}`\n}\n\nexport function renderInstallTerminal(options: InstallTerminalOptions): string {\n const color = options.color ?? true\n const apiKeyValue = options.apiKeyConfigured ? '$MCP_SCRAPER_API_KEY' : 'sk_live_your_key'\n const ascii = String.raw`\n __ __ ____ ____ \n| \\/ |/ ___| _ \\\n| |\\/| | | | |_) |\n| | | | |___| __/\n|_| |_|\\____|_|\n\n ____ ____ ____ _ ____ _____ ____\n/ ___| / ___| _ \\ / \\ | _ \\| ____| _ \\\n\\___ \\| | | |_) | / _ \\ | |_) | _| | |_) |\n ___) | |___| _ < / ___ \\| __/| |___| _ <\n|____/ \\____|_| \\_\\/_/ \\_\\_| |_____|_| \\_\\\n`\n\n const claudeCommand = [\n `MCP_SCRAPER_API_KEY=${apiKeyValue} npx -y -p mcp-scraper@latest \\\\`,\n ' mcp-scraper-cli agent install claude --apply',\n ].join('\\n')\n\n const codexConfig = [\n '[mcp_servers.mcp-scraper]',\n 'command = \"npx\"',\n 'args = [\"-y\", \"-p\", \"mcp-scraper@latest\", \"mcp-scraper\"]',\n `env = { MCP_SCRAPER_API_KEY = \"${apiKeyValue}\" }`,\n ].join('\\n')\n\n return [\n colorize(`mcp-scraper v${options.version}`, 'bold', color),\n colorize('> mcp-scraper-install', 'muted', color),\n colorize(ascii, 'amber', color),\n `${colorize('MCP Scraper Agent', 'cyan', color)} . v${options.version} . mcpscraper.dev`,\n '1/1 install surfaces ready',\n colorize('Newest: saved browser profiles that hold MANY site logins. Share the watch_url, user signs in, then verify with browser_profile_list. Browser sessions are direct/no-proxy by default.', 'lime', color),\n '',\n `${colorize('Tools', 'cyan', color)} ${colorize('(
|
|
1
|
+
{"version":3,"sources":["../../src/install-terminal.ts","../../src/version.ts","../../bin/mcp-scraper-install.ts"],"sourcesContent":["export interface InstallTerminalOptions {\n color?: boolean\n version: string\n apiKeyConfigured?: boolean\n}\n\ntype Tone = 'cyan' | 'lime' | 'amber' | 'red' | 'muted' | 'bold'\n\nconst CODES: Record<Tone | 'reset', string> = {\n reset: '\\x1b[0m',\n cyan: '\\x1b[36m',\n lime: '\\x1b[32m',\n amber: '\\x1b[33m',\n red: '\\x1b[31m',\n muted: '\\x1b[90m',\n bold: '\\x1b[1m',\n}\n\nfunction colorize(value: string, tone: Tone, enabled: boolean): string {\n if (!enabled) return value\n return `${CODES[tone]}${value}${CODES.reset}`\n}\n\nfunction toolRow(label: string, tools: string[], enabled: boolean): string {\n const padded = label.padEnd(9, ' ')\n return ` ${colorize(padded, 'muted', enabled)} ${tools.join(colorize(' . ', 'muted', enabled))}`\n}\n\nexport function renderInstallTerminal(options: InstallTerminalOptions): string {\n const color = options.color ?? true\n const apiKeyValue = options.apiKeyConfigured ? '$MCP_SCRAPER_API_KEY' : 'sk_live_your_key'\n const ascii = String.raw`\n __ __ ____ ____ \n| \\/ |/ ___| _ \\\n| |\\/| | | | |_) |\n| | | | |___| __/\n|_| |_|\\____|_|\n\n ____ ____ ____ _ ____ _____ ____\n/ ___| / ___| _ \\ / \\ | _ \\| ____| _ \\\n\\___ \\| | | |_) | / _ \\ | |_) | _| | |_) |\n ___) | |___| _ < / ___ \\| __/| |___| _ <\n|____/ \\____|_| \\_\\/_/ \\_\\_| |_____|_| \\_\\\n`\n\n const claudeCommand = [\n `MCP_SCRAPER_API_KEY=${apiKeyValue} npx -y -p mcp-scraper@latest \\\\`,\n ' mcp-scraper-cli agent install claude --apply',\n ].join('\\n')\n\n const codexConfig = [\n '[mcp_servers.mcp-scraper]',\n 'command = \"npx\"',\n 'args = [\"-y\", \"-p\", \"mcp-scraper@latest\", \"mcp-scraper\"]',\n `env = { MCP_SCRAPER_API_KEY = \"${apiKeyValue}\" }`,\n ].join('\\n')\n\n return [\n colorize(`mcp-scraper v${options.version}`, 'bold', color),\n colorize('> mcp-scraper-install', 'muted', color),\n colorize(ascii, 'amber', color),\n `${colorize('MCP Scraper Agent', 'cyan', color)} . v${options.version} . mcpscraper.dev`,\n '1/1 install surfaces ready',\n colorize('Newest: saved browser profiles that hold MANY site logins. Share the watch_url, user signs in, then verify with browser_profile_list. Browser sessions are direct/no-proxy by default.', 'lime', color),\n '',\n `${colorize('Tools', 'cyan', color)} ${colorize('(48 MCP tools)', 'muted', color)}`,\n toolRow('search', ['harvest_paa', 'search_serp', 'maps_search', 'maps_place_intel'], color),\n toolRow('extract', ['extract_url', 'map_site_urls', 'extract_site', 'audit_site', 'directory_workflow'], color),\n toolRow('build', ['rank_tracker_workflow', 'cron plan', 'database prompt'], color),\n toolRow('media', ['youtube_harvest', 'youtube_transcribe', 'facebook_ad_search', 'facebook_page_intel', 'facebook_ad_transcribe', 'facebook_video_transcribe', 'instagram_profile_content', 'instagram_media_download', 'reddit_thread'], color),\n toolRow('browser', ['browser_open', 'browser_profile_connect', 'browser_profile_list', 'browser_close', 'browser_screenshot', 'browser_read', 'browser_locate', 'browser_replay_mark', 'browser_replay_annotate'], color),\n toolRow('account', ['credits_info', 'reports', 'MCP resources'], color),\n `${colorize('Workflows', 'cyan', color)} ${colorize('(MCP + CLI + API)', 'muted', color)}`,\n toolRow('route', ['workflow_list', 'workflow_suggest', 'workflow_run', 'workflow_step', 'workflow_status', 'workflow_artifact_read'], color),\n toolRow('seo', ['directory', 'agent-packet', 'competitive audit', 'map/serp comparison', 'PAA/AIO briefs', 'scheduled runs'], color),\n '',\n colorize('Usage tips:', 'amber', color),\n 'Run mcp-scraper-install for this visible card. Run mcp-scraper-cli for setup utilities and subcommands.',\n 'Run mcp-scraper in a human terminal to print this card; MCP clients get the same command as a silent stdio server.',\n 'Explicit card command: npx -y -p mcp-scraper@latest mcp-scraper-install',\n 'Customer auth setup: run browser_profile_connect, send the watch_url, let the user sign in, then call browser_profile_list until AUTHENTICATED.',\n 'Stack logins / reconnect: run browser_profile_connect again with the same profile name and another domain to add accounts or refresh a login.',\n 'Start with workflow_suggest for broad jobs like market analysis, ICP research, CRO audits, brand briefs, content gaps, and AI visibility.',\n 'For MCP clients, use mcp-scraper so one install can mix SERP, Maps, browser, reports, and saved MCP resources.',\n 'If you hit the concurrency limit, add an extra slot for $5/month with mcp-scraper-cli billing concurrency checkout.',\n '',\n `${colorize('Ready.', 'lime', color)} Install the combined MCP server with one command:`,\n '',\n colorize('Setup doctor', 'amber', color),\n 'npx -y -p mcp-scraper@latest mcp-scraper-cli doctor',\n '',\n colorize('Hosted profile setup', 'amber', color),\n 'In your MCP client, call browser_profile_connect with email=\"seo@example.com\" and domain=\"chatgpt.com\".',\n '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.',\n '',\n colorize('Claude Code one-command setup', 'amber', color),\n claudeCommand,\n 'Then fully exit Claude Code and open a new Claude terminal. Check with: claude mcp list',\n '',\n colorize('Codex config', 'amber', color),\n codexConfig,\n '',\n colorize('Claude Desktop Extension', 'amber', color),\n 'Download: https://mcpscraper.dev/downloads/mcp-scraper.mcpb',\n '',\n colorize('Safety note:', 'muted', color),\n 'mcp-scraper prints this card only when stdin/stdout are an interactive TTY. In MCP clients it writes only JSON-RPC to stdout.',\n 'Use --stdio or MCP_SCRAPER_FORCE_STDIO=1 to force server mode from a terminal.',\n '',\n ].join('\\n')\n}\n","export const PACKAGE_VERSION = '0.3.27'\n","#!/usr/bin/env node\nimport { renderInstallTerminal } from '../src/install-terminal.js'\nimport { PACKAGE_VERSION } from '../src/version.js'\n\nconst noColor =\n process.argv.includes('--no-color') ||\n process.env.NO_COLOR !== undefined ||\n process.env.FORCE_COLOR === '0' ||\n !process.stdout.isTTY\n\nconst help = process.argv.includes('--help') || process.argv.includes('-h')\nif (help) {\n process.stdout.write([\n 'Usage: mcp-scraper-install [--no-color]',\n '',\n 'Prints the branded MCP Scraper terminal install card and copyable install commands.',\n 'mcp-scraper prints the same card in a human terminal and runs as the MCP stdio server in clients.',\n '',\n ].join('\\n'))\n process.exit(0)\n}\n\nprocess.stdout.write(renderInstallTerminal({\n version: PACKAGE_VERSION,\n color: !noColor,\n apiKeyConfigured: Boolean(process.env.MCP_SCRAPER_API_KEY?.trim()),\n}))\n"],"mappings":"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","names":[]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
renderInstallTerminal
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-T3VZD2I4.js";
|
|
5
5
|
import {
|
|
6
6
|
PACKAGE_VERSION
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-DYV72F6A.js";
|
|
8
8
|
|
|
9
9
|
// bin/mcp-scraper-install.ts
|
|
10
10
|
var noColor = process.argv.includes("--no-color") || process.env.NO_COLOR !== void 0 || process.env.FORCE_COLOR === "0" || !process.stdout.isTTY;
|
|
@@ -459,7 +459,7 @@ render();
|
|
|
459
459
|
}
|
|
460
460
|
|
|
461
461
|
// src/version.ts
|
|
462
|
-
var PACKAGE_VERSION = "0.3.
|
|
462
|
+
var PACKAGE_VERSION = "0.3.27";
|
|
463
463
|
|
|
464
464
|
// src/mcp/browser-agent-tool-schemas.ts
|
|
465
465
|
var import_zod = require("zod");
|
|
@@ -2601,9 +2601,18 @@ function parseData(raw) {
|
|
|
2601
2601
|
function entityIdsSection(ids) {
|
|
2602
2602
|
if (!ids) return "";
|
|
2603
2603
|
const lines = [];
|
|
2604
|
-
if (ids.
|
|
2605
|
-
|
|
2606
|
-
|
|
2604
|
+
if (ids.entities?.length) {
|
|
2605
|
+
for (const e of ids.entities) {
|
|
2606
|
+
const idParts = [e.kgId && `MID ${e.kgId}`, e.cid && `CID ${e.cid}`, e.gcid && `GCID ${e.gcid}`].filter(Boolean);
|
|
2607
|
+
if (idParts.length) lines.push(`- **${e.name}** \u2014 ${idParts.join(", ")}`);
|
|
2608
|
+
}
|
|
2609
|
+
}
|
|
2610
|
+
const linkedNames = new Set((ids.entities ?? []).map((e) => e.name));
|
|
2611
|
+
if (!linkedNames.size) {
|
|
2612
|
+
if (ids.kgIds?.length) lines.push(`- **Knowledge Graph MID:** ${ids.kgIds.join(", ")}`);
|
|
2613
|
+
if (ids.cids?.length) lines.push(`- **CID:** ${ids.cids.join(", ")}`);
|
|
2614
|
+
if (ids.gcids?.length) lines.push(`- **GCID:** ${ids.gcids.join(", ")}`);
|
|
2615
|
+
}
|
|
2607
2616
|
return lines.length ? `
|
|
2608
2617
|
## Entity IDs
|
|
2609
2618
|
${lines.join("\n")}` : "";
|
|
@@ -2725,7 +2734,7 @@ ${paaTable}${serpTable}${entityIdsSection(entityIds)}${aiSection}${statsLine}${d
|
|
|
2725
2734
|
snippet: r.snippet ?? null
|
|
2726
2735
|
})),
|
|
2727
2736
|
aiOverview: aiOvw ? { detected: aiOvw.detected === true, text: aiOvw.text ?? null } : null,
|
|
2728
|
-
entityIds: entityIds ? { kgIds: entityIds.kgIds ?? [], cids: entityIds.cids ?? [], gcids: entityIds.gcids ?? [] } : null,
|
|
2737
|
+
entityIds: entityIds ? { entities: entityIds.entities ?? [], kgIds: entityIds.kgIds ?? [], cids: entityIds.cids ?? [], gcids: entityIds.gcids ?? [] } : null,
|
|
2729
2738
|
durationMs: durationMs ?? null
|
|
2730
2739
|
}
|
|
2731
2740
|
};
|
|
@@ -2786,7 +2795,7 @@ ${serpTable}${localSection}${entityIdsSection(entityIds)}${aiSection}${debugSect
|
|
|
2786
2795
|
websiteUrl: b.websiteUrl ?? null
|
|
2787
2796
|
})),
|
|
2788
2797
|
aiOverview: aiOvw ? { detected: aiOvw.detected === true, text: aiOvw.text ?? null } : null,
|
|
2789
|
-
entityIds: entityIds ? { kgIds: entityIds.kgIds ?? [], cids: entityIds.cids ?? [], gcids: entityIds.gcids ?? [] } : null
|
|
2798
|
+
entityIds: entityIds ? { entities: entityIds.entities ?? [], kgIds: entityIds.kgIds ?? [], cids: entityIds.cids ?? [], gcids: entityIds.gcids ?? [] } : null
|
|
2790
2799
|
}
|
|
2791
2800
|
};
|
|
2792
2801
|
}
|
|
@@ -4236,33 +4245,73 @@ ${limitations.map((l) => `- ${l}`).join("\n")}` : "",
|
|
|
4236
4245
|
|
|
4237
4246
|
// src/mcp/server-instructions.ts
|
|
4238
4247
|
var SERVER_INSTRUCTIONS = `
|
|
4239
|
-
|
|
4240
|
-
|
|
4248
|
+
# MCP Scraper
|
|
4249
|
+
|
|
4250
|
+
Scrapes and analyzes web, search, maps, social, and site data. **Pick a tool by NAME from the map
|
|
4251
|
+
below, then load its schema before calling.** Where a tool needs a value another tool produces, the
|
|
4252
|
+
seam is noted so you can chain them.
|
|
4253
|
+
|
|
4254
|
+
## Search & research
|
|
4255
|
+
- Organic Google results, rankings, local pack -> **search_serp**.
|
|
4256
|
+
- Full SERP plus People-Also-Ask and AI-Overview detail -> **harvest_paa**.
|
|
4257
|
+
- \`search_serp\` returns \`organicResults[].url\` (often including reddit.com threads) \u2014 feed those into
|
|
4258
|
+
\`extract_url\` or \`reddit_thread\`.
|
|
4259
|
+
|
|
4260
|
+
## Pages & sites
|
|
4261
|
+
- One page -> **extract_url** (takes a url).
|
|
4262
|
+
- Whole site, crawl + SEO report -> **extract_site** (takes a url).
|
|
4263
|
+
- Just the URL list/inventory -> **map_site_urls** (takes a url).
|
|
4264
|
+
- \`map_site_urls\` returns urls you can feed straight into \`extract_url\`.
|
|
4265
|
+
|
|
4266
|
+
## Google Maps
|
|
4267
|
+
- Find multiple places/competitors/prospects -> **maps_search** (returns \`results[]\` with name,
|
|
4268
|
+
placeUrl, cid).
|
|
4269
|
+
- One business deep-dive + reviews -> **maps_place_intel** (takes businessName + location, NOT an id \u2014
|
|
4270
|
+
call it directly with a name from a \`maps_search\` result or from the user).
|
|
4241
4271
|
|
|
4242
|
-
|
|
4243
|
-
-
|
|
4244
|
-
-
|
|
4245
|
-
- Google Maps: find places -> maps_search; one place deep-dive + reviews -> maps_place_intel.
|
|
4246
|
-
- YouTube: find or list videos -> youtube_harvest; transcribe one video -> youtube_transcribe.
|
|
4247
|
-
- Facebook: find ads -> facebook_ad_search; transcribe an ad -> facebook_ad_transcribe; transcribe a
|
|
4248
|
-
video -> facebook_video_transcribe; page profile/intel -> facebook_page_intel.
|
|
4249
|
-
- Instagram: profile inventory -> instagram_profile_content; one post or reel -> instagram_media_download.
|
|
4250
|
-
- Workflows (multi-step): local directory build -> directory_workflow; rank blueprint -> rank_tracker_workflow;
|
|
4251
|
-
AI-answer citation fan-out (AEO) -> query_fanout_workflow; deep research -> deep_research_workflow.
|
|
4252
|
-
- Anything without a dedicated tool (e.g. Reddit, arbitrary logged-in sites) -> the browser_* agent
|
|
4253
|
-
(browser_open, then navigate/read).
|
|
4254
|
-
- Logged-in sites (ChatGPT, Claude, Reddit, any account): save the login first -> browser_profile_connect
|
|
4255
|
-
(returns an mcpscraper.dev sign-in link for the user; one profile holds MANY logins, call it again with
|
|
4256
|
-
the same profile + a new domain to add accounts) -> poll browser_profile_list until AUTHENTICATED ->
|
|
4257
|
-
browser_open with that profile. browser_profile_list also shows what a profile is connected to.
|
|
4272
|
+
## YouTube
|
|
4273
|
+
- Find or list videos -> **youtube_harvest** (returns \`videos[].videoId\`).
|
|
4274
|
+
- Transcribe one video -> **youtube_transcribe** (takes a videoId from \`youtube_harvest\`, or a url).
|
|
4258
4275
|
|
|
4259
|
-
|
|
4260
|
-
-
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
-
|
|
4265
|
-
|
|
4276
|
+
## Facebook
|
|
4277
|
+
- Find advertisers -> **facebook_ad_search** (returns \`advertisers[]\` with pageId, libraryId).
|
|
4278
|
+
- One advertiser's ads -> **facebook_page_intel** (takes pageId, libraryId, or query; returns
|
|
4279
|
+
\`ads[].videoUrl\`).
|
|
4280
|
+
- Transcribe an ad video -> **facebook_ad_transcribe** (takes a videoUrl from \`facebook_page_intel\`).
|
|
4281
|
+
- Transcribe an organic reel/video/post -> **facebook_video_transcribe** (takes the Facebook url directly).
|
|
4282
|
+
|
|
4283
|
+
## Instagram
|
|
4284
|
+
- Profile inventory -> **instagram_profile_content** (returns post/reel/tv urls).
|
|
4285
|
+
- One post or reel -> **instagram_media_download** (takes a url from \`instagram_profile_content\`, or a
|
|
4286
|
+
url the user gives).
|
|
4287
|
+
|
|
4288
|
+
## Reddit
|
|
4289
|
+
- A reddit.com thread/post URL -> **reddit_thread**. Returns the post plus its comment tree and handles
|
|
4290
|
+
Reddit's bot wall itself (no login needed). Find threads first with \`search_serp\`.
|
|
4291
|
+
|
|
4292
|
+
## Other sites & logins (browser agent)
|
|
4293
|
+
For an arbitrary site or a logged-in dashboard with no dedicated tool, use the browser_* agent. **First
|
|
4294
|
+
decide whether the site needs a login:**
|
|
4295
|
+
- **Needs a login** (ChatGPT, Claude, any account) -> save it first: **browser_profile_connect** returns
|
|
4296
|
+
an mcpscraper.dev sign-in link for the user; one profile holds MANY logins (call it again with the same
|
|
4297
|
+
profile + a new domain to add accounts). Poll **browser_profile_list** until AUTHENTICATED, then
|
|
4298
|
+
**browser_open** with that profile.
|
|
4299
|
+
- **No login** -> **browser_open**, then navigate/read.
|
|
4300
|
+
|
|
4301
|
+
## Workflows
|
|
4302
|
+
Multi-step orchestrations \u2014 prefer these over hand-chaining primitives when the whole job is one of these:
|
|
4303
|
+
- Build a local business directory for a niche across a state/region -> **directory_workflow**.
|
|
4304
|
+
- Stand up a rank-tracking blueprint (database + cron + ingestion plan) -> **rank_tracker_workflow**.
|
|
4305
|
+
- Find which sources an AI answer cites for a query (AEO) -> **query_fanout_workflow** (open a browser
|
|
4306
|
+
session on chatgpt.com or claude.ai FIRST, then run it against that session).
|
|
4307
|
+
|
|
4308
|
+
## Notes
|
|
4309
|
+
- Bulk / full-site crawls: call \`extract_site\` with \`rotateProxies:true\` for blocked or rate-limited
|
|
4310
|
+
sites. It returns a saved folder/artifact plus a summary, not the full content inline.
|
|
4311
|
+
- Browser sessions and media transcription cost credits and take longer \u2014 prefer the cheapest tool that
|
|
4312
|
+
answers the question (plain search/extract before browser agents).
|
|
4313
|
+
- Large results are saved to disk or an artifact and returned as a summary plus a path; read the path for
|
|
4314
|
+
full detail rather than expecting the whole payload inline.
|
|
4266
4315
|
`.trim();
|
|
4267
4316
|
|
|
4268
4317
|
// src/mcp/mcp-tool-schemas.ts
|
|
@@ -4653,6 +4702,12 @@ var AiOverviewOutput = import_zod3.z.object({
|
|
|
4653
4702
|
text: NullableString2
|
|
4654
4703
|
}).nullable();
|
|
4655
4704
|
var EntityIdsOutput = import_zod3.z.object({
|
|
4705
|
+
entities: import_zod3.z.array(import_zod3.z.object({
|
|
4706
|
+
name: import_zod3.z.string(),
|
|
4707
|
+
kgId: import_zod3.z.string().nullable(),
|
|
4708
|
+
cid: import_zod3.z.string().nullable(),
|
|
4709
|
+
gcid: import_zod3.z.string().nullable()
|
|
4710
|
+
})).describe("Each entity actually named on the page, with whichever of its kgId/cid/gcid were found \u2014 the linked view. kgIds/cids/gcids below are the same IDs as flat deduplicated lists, without the name link, kept for backward compatibility."),
|
|
4656
4711
|
kgIds: import_zod3.z.array(import_zod3.z.string()),
|
|
4657
4712
|
cids: import_zod3.z.array(import_zod3.z.string()),
|
|
4658
4713
|
gcids: import_zod3.z.array(import_zod3.z.string())
|
|
@@ -5423,7 +5478,7 @@ function buildPrompt(input, modes, tools, tables, jobs, metrics, expression, tar
|
|
|
5423
5478
|
"- Every scheduled batch must insert or update rank_tracker_runs before calling MCP tools.",
|
|
5424
5479
|
"- Use idempotency_key = project_id + keyword_id + location_id + mode + device + scheduled_date.",
|
|
5425
5480
|
"- Mark runs as running, succeeded, failed, or skipped; persist error_message on failures.",
|
|
5426
|
-
"-
|
|
5481
|
+
"- Call credits_info first to read the account's real concurrency_limit (most paid accounts have 3, 10, or 20, not 1), then run up to that many MCP calls in parallel \u2014 never sequential-by-default and never more than the limit, or calls start failing with 429s.",
|
|
5427
5482
|
"- Retry retryable upstream failures with backoff, but do not duplicate rows for the same idempotency key.",
|
|
5428
5483
|
"",
|
|
5429
5484
|
"Mode-specific ingestion rules:",
|
|
@@ -5806,7 +5861,7 @@ function renderInstallTerminal(options) {
|
|
|
5806
5861
|
"1/1 install surfaces ready",
|
|
5807
5862
|
colorize("Newest: saved browser profiles that hold MANY site logins. Share the watch_url, user signs in, then verify with browser_profile_list. Browser sessions are direct/no-proxy by default.", "lime", color),
|
|
5808
5863
|
"",
|
|
5809
|
-
`${colorize("Tools", "cyan", color)} ${colorize("(
|
|
5864
|
+
`${colorize("Tools", "cyan", color)} ${colorize("(48 MCP tools)", "muted", color)}`,
|
|
5810
5865
|
toolRow("search", ["harvest_paa", "search_serp", "maps_search", "maps_place_intel"], color),
|
|
5811
5866
|
toolRow("extract", ["extract_url", "map_site_urls", "extract_site", "audit_site", "directory_workflow"], color),
|
|
5812
5867
|
toolRow("build", ["rank_tracker_workflow", "cron plan", "database prompt"], color),
|