mcp-scraper 0.4.0 → 0.4.2
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 +934 -221
- package/dist/bin/api-server.cjs.map +1 -1
- package/dist/bin/api-server.js +2 -2
- package/dist/bin/mcp-scraper-cli.cjs +2 -1
- package/dist/bin/mcp-scraper-cli.cjs.map +1 -1
- package/dist/bin/mcp-scraper-cli.js +3 -3
- package/dist/bin/mcp-scraper-install.cjs +3 -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 +83 -22
- package/dist/bin/mcp-stdio-server.cjs.map +1 -1
- package/dist/bin/mcp-stdio-server.js +4 -4
- package/dist/bin/paa-harvest.cjs +1 -0
- package/dist/bin/paa-harvest.cjs.map +1 -1
- package/dist/bin/paa-harvest.js +2 -2
- package/dist/{chunk-6TDUY7CA.js → chunk-4MFYMUIF.js} +25 -3
- package/dist/chunk-4MFYMUIF.js.map +1 -0
- package/dist/{chunk-T3VZD2I4.js → chunk-5HNHYUJ5.js} +3 -2
- package/dist/chunk-5HNHYUJ5.js.map +1 -0
- package/dist/chunk-7HICT4GY.js +7 -0
- package/dist/chunk-7HICT4GY.js.map +1 -0
- package/dist/{chunk-NNEIXK5L.js → chunk-FUWZWKGO.js} +2 -2
- package/dist/{chunk-3NIPPJGP.js → chunk-GFY6XHZS.js} +80 -21
- package/dist/chunk-GFY6XHZS.js.map +1 -0
- package/dist/{chunk-HBC4C75S.js → chunk-NJK5BTUK.js} +2 -2
- package/dist/{chunk-JOEZJL4I.js → chunk-NVUBFCJK.js} +2 -2
- package/dist/{chunk-BP27CZ5Q.js → chunk-XGIPATLV.js} +2 -1
- package/dist/chunk-XGIPATLV.js.map +1 -0
- package/dist/index.cjs +1 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/{server-Z4WKTE6F.js → server-6IYQQK6X.js} +793 -210
- package/dist/server-6IYQQK6X.js.map +1 -0
- package/dist/{site-extract-repository-2MQBAOX5.js → site-extract-repository-4NVO5KQA.js} +3 -3
- package/dist/{worker-RVZXIALX.js → worker-7XRZNLKB.js} +4 -4
- package/package.json +2 -1
- package/dist/chunk-3NIPPJGP.js.map +0 -1
- package/dist/chunk-6TDUY7CA.js.map +0 -1
- package/dist/chunk-BP27CZ5Q.js.map +0 -1
- package/dist/chunk-IXDYL7TE.js +0 -7
- package/dist/chunk-IXDYL7TE.js.map +0 -1
- package/dist/chunk-T3VZD2I4.js.map +0 -1
- package/dist/server-Z4WKTE6F.js.map +0 -1
- /package/dist/{chunk-NNEIXK5L.js.map → chunk-FUWZWKGO.js.map} +0 -0
- /package/dist/{chunk-HBC4C75S.js.map → chunk-NJK5BTUK.js.map} +0 -0
- /package/dist/{chunk-JOEZJL4I.js.map → chunk-NVUBFCJK.js.map} +0 -0
- /package/dist/{site-extract-repository-2MQBAOX5.js.map → site-extract-repository-4NVO5KQA.js.map} +0 -0
- /package/dist/{worker-RVZXIALX.js.map → worker-7XRZNLKB.js.map} +0 -0
|
@@ -6,12 +6,12 @@ import {
|
|
|
6
6
|
openWorkflowReport,
|
|
7
7
|
runWorkflow,
|
|
8
8
|
workflowOutputBaseDir
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-FUWZWKGO.js";
|
|
10
10
|
import "../chunk-K443GQY5.js";
|
|
11
|
-
import "../chunk-
|
|
11
|
+
import "../chunk-XGIPATLV.js";
|
|
12
12
|
import {
|
|
13
13
|
PACKAGE_VERSION
|
|
14
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-7HICT4GY.js";
|
|
15
15
|
|
|
16
16
|
// src/cli/human-cli.ts
|
|
17
17
|
import { Command } from "commander";
|
|
@@ -53,13 +53,14 @@ 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("(128 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),
|
|
60
60
|
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),
|
|
61
61
|
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),
|
|
62
62
|
toolRow("account", ["credits_info", "reports", "MCP resources"], color),
|
|
63
|
+
toolRow("memory", ["memory-put", "memory-get", "memory-search", "list-vaults", "record-fact", "list-scheduled-actions"], color),
|
|
63
64
|
`${colorize("Workflows", "cyan", color)} ${colorize("(MCP + CLI + API)", "muted", color)}`,
|
|
64
65
|
toolRow("route", ["workflow_list", "workflow_suggest", "workflow_run", "workflow_step", "workflow_status", "workflow_artifact_read"], color),
|
|
65
66
|
toolRow("seo", ["directory", "agent-packet", "competitive audit", "map/serp comparison", "PAA/AIO briefs", "scheduled runs"], color),
|
|
@@ -101,7 +102,7 @@ function renderInstallTerminal(options) {
|
|
|
101
102
|
}
|
|
102
103
|
|
|
103
104
|
// src/version.ts
|
|
104
|
-
var PACKAGE_VERSION = "0.4.
|
|
105
|
+
var PACKAGE_VERSION = "0.4.2";
|
|
105
106
|
|
|
106
107
|
// bin/mcp-scraper-install.ts
|
|
107
108
|
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('(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.4.0'\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
|
+
{"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('(128 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 toolRow('memory', ['memory-put', 'memory-get', 'memory-search', 'list-vaults', 'record-fact', 'list-scheduled-actions'], 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.4.2'\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-5HNHYUJ5.js";
|
|
5
5
|
import {
|
|
6
6
|
PACKAGE_VERSION
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-7HICT4GY.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;
|
|
@@ -474,7 +474,7 @@ render();
|
|
|
474
474
|
}
|
|
475
475
|
|
|
476
476
|
// src/version.ts
|
|
477
|
-
var PACKAGE_VERSION = "0.4.
|
|
477
|
+
var PACKAGE_VERSION = "0.4.2";
|
|
478
478
|
|
|
479
479
|
// src/mcp/browser-agent-tool-schemas.ts
|
|
480
480
|
var import_zod = require("zod");
|
|
@@ -696,7 +696,7 @@ var BrowserProfileLogin = import_zod.z.object({
|
|
|
696
696
|
var BrowserProfileConnectOutputSchema = {
|
|
697
697
|
ok: import_zod.z.boolean(),
|
|
698
698
|
tool: import_zod.z.literal("browser_profile_connect"),
|
|
699
|
-
session_id: NullableString,
|
|
699
|
+
session_id: NullableString.describe("The underlying live browser session id backing this sign-in."),
|
|
700
700
|
auth_connection_id: import_zod.z.string(),
|
|
701
701
|
watch_url: import_zod.z.string().describe("mcpscraper.dev sign-in link to give the user so they can complete this login."),
|
|
702
702
|
live_view_url: NullableString.describe("Deprecated; always null. Open watch_url to view the sign-in."),
|
|
@@ -706,10 +706,10 @@ var BrowserProfileConnectOutputSchema = {
|
|
|
706
706
|
account_email: NullableString,
|
|
707
707
|
note: NullableString,
|
|
708
708
|
status: import_zod.z.string(),
|
|
709
|
-
flow_status: NullableString,
|
|
710
|
-
flow_step: NullableString,
|
|
711
|
-
flow_expires_at: NullableString,
|
|
712
|
-
post_login_url: NullableString,
|
|
709
|
+
flow_status: NullableString.describe("Deprecated; always null."),
|
|
710
|
+
flow_step: NullableString.describe("Deprecated; always null."),
|
|
711
|
+
flow_expires_at: NullableString.describe("Deprecated; always null."),
|
|
712
|
+
post_login_url: NullableString.describe("Deprecated; always null."),
|
|
713
713
|
connected_logins: import_zod.z.array(BrowserProfileLogin).describe("Every login currently saved in this profile, so you can see what else is connected."),
|
|
714
714
|
next_steps: import_zod.z.array(import_zod.z.string()),
|
|
715
715
|
raw: BrowserRawObject.optional()
|
|
@@ -1198,6 +1198,11 @@ function slugPart(value) {
|
|
|
1198
1198
|
if (!trimmed) return null;
|
|
1199
1199
|
return trimmed.replace(/^https?:\/\//, "").replace(/^www\./, "").replace(/\/.*$/, "").replace(/[^a-z0-9._-]+/g, "-").replace(/[._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
1200
1200
|
}
|
|
1201
|
+
function normalizeDomain(value) {
|
|
1202
|
+
const trimmed = value?.trim().toLowerCase();
|
|
1203
|
+
if (!trimmed) return null;
|
|
1204
|
+
return trimmed.replace(/^https?:\/\//, "").replace(/^www\./, "").replace(/\/.*$/, "").replace(/[^a-z0-9.-]+/g, "-").replace(/-+/g, "-").replace(/^-+|-+$/g, "");
|
|
1205
|
+
}
|
|
1201
1206
|
function savedProfileNameFromEmail(email) {
|
|
1202
1207
|
const value = slugPart(email);
|
|
1203
1208
|
if (!value) return null;
|
|
@@ -1307,13 +1312,13 @@ function registerBrowserAgentMcpTools(server2, opts) {
|
|
|
1307
1312
|
"browser_profile_connect",
|
|
1308
1313
|
{
|
|
1309
1314
|
title: "Save a Site Login to a Profile",
|
|
1310
|
-
description:
|
|
1315
|
+
description: 'Open a live hosted browser session so the user can sign into a site (ChatGPT, Claude, Reddit, any account-gated site) directly in their own browser tab, then save the login to a named profile. Returns a watch_url \u2014 give it to the user; they sign in fresh on the real site (existing browser cookies are NOT imported), then click "Done" on that page to save the session and close it. ONE profile holds MANY logins \u2014 call again with the same profile and a different domain to stack another account. NOT for one-off scraping (use extract_url) or driving the browser (use browser_open). Billed at the standard live-browser rate while the sign-in session stays open. After the user clicks Done, poll browser_profile_list until AUTHENTICATED, then browser_open with the profile.',
|
|
1311
1316
|
inputSchema: BrowserProfileConnectInputSchema,
|
|
1312
1317
|
outputSchema: recordOutputSchema("browser_profile_connect", BrowserProfileConnectOutputSchema),
|
|
1313
1318
|
annotations: annotations("Save a Site Login to a Profile")
|
|
1314
1319
|
},
|
|
1315
1320
|
async (input) => {
|
|
1316
|
-
const domain =
|
|
1321
|
+
const domain = normalizeDomain(input.domain) || "chatgpt.com";
|
|
1317
1322
|
const setupUrl = input.login_url ?? input.url ?? (domain === "chatgpt.com" ? "https://chatgpt.com/" : `https://${domain}/`);
|
|
1318
1323
|
const profile = input.profile?.trim() || savedProfileNameFromEmail(input.email) || browserServiceProfileName();
|
|
1319
1324
|
if (!profile) {
|
|
@@ -1329,14 +1334,15 @@ function registerBrowserAgentMcpTools(server2, opts) {
|
|
|
1329
1334
|
domain,
|
|
1330
1335
|
login_url: setupUrl,
|
|
1331
1336
|
...accountEmail ? { account_email: accountEmail } : {},
|
|
1332
|
-
...note ? { note } : {}
|
|
1337
|
+
...note ? { note } : {},
|
|
1338
|
+
...typeof input.timeout_seconds === "number" ? { timeout_seconds: input.timeout_seconds } : {}
|
|
1333
1339
|
});
|
|
1334
1340
|
if (!open.ok) return errorResult("browser_profile_connect", open.data);
|
|
1335
1341
|
const connectedLogins = await fetchConnectedLogins(profile).catch(() => []);
|
|
1336
1342
|
return structuredResult({
|
|
1337
1343
|
ok: true,
|
|
1338
1344
|
tool: "browser_profile_connect",
|
|
1339
|
-
session_id: null,
|
|
1345
|
+
session_id: open.data.browser_session_id ?? null,
|
|
1340
1346
|
auth_connection_id: open.data.connection_id,
|
|
1341
1347
|
watch_url: `${consoleBase}/console/auth/${open.data.connection_id}`,
|
|
1342
1348
|
live_view_url: null,
|
|
@@ -1346,13 +1352,13 @@ function registerBrowserAgentMcpTools(server2, opts) {
|
|
|
1346
1352
|
account_email: accountEmail,
|
|
1347
1353
|
note,
|
|
1348
1354
|
status: open.data.status ?? null,
|
|
1349
|
-
flow_status:
|
|
1350
|
-
flow_step:
|
|
1351
|
-
flow_expires_at:
|
|
1352
|
-
post_login_url:
|
|
1355
|
+
flow_status: null,
|
|
1356
|
+
flow_step: null,
|
|
1357
|
+
flow_expires_at: null,
|
|
1358
|
+
post_login_url: null,
|
|
1353
1359
|
connected_logins: connectedLogins,
|
|
1354
1360
|
next_steps: [
|
|
1355
|
-
`Give the user watch_url so they can sign in to ${domain}.`,
|
|
1361
|
+
`Give the user watch_url so they can sign in to ${domain} directly in that page, then click "Done \u2014 I'm signed in".`,
|
|
1356
1362
|
"Poll browser_profile_list (with this profile) until the login reads AUTHENTICATED.",
|
|
1357
1363
|
"To add another account to this same profile, call browser_profile_connect again with the same profile and a different domain.",
|
|
1358
1364
|
"When authenticated, call browser_open with this profile to drive the logged-in session."
|
|
@@ -1377,7 +1383,7 @@ function registerBrowserAgentMcpTools(server2, opts) {
|
|
|
1377
1383
|
error: "profile or email is required when BROWSER_AGENT_PROFILE_NAME is not available"
|
|
1378
1384
|
});
|
|
1379
1385
|
}
|
|
1380
|
-
const domain =
|
|
1386
|
+
const domain = normalizeDomain(input.domain) || void 0;
|
|
1381
1387
|
const res = await req("POST", "/agent/profiles/list", {
|
|
1382
1388
|
profile,
|
|
1383
1389
|
...domain ? { domain } : {},
|
|
@@ -1976,6 +1982,17 @@ var WORKFLOW_RECIPES = [
|
|
|
1976
1982
|
produces: ["content gaps", "page comparison CSV", "PAA questions CSV", "section map", "writer brief"],
|
|
1977
1983
|
runHint: "Use workflow_run with workflowId serp-comparison for competitor gaps or paa-expansion-brief when the user mainly wants a section map from PAA data."
|
|
1978
1984
|
},
|
|
1985
|
+
{
|
|
1986
|
+
id: "recurring_tracking_and_memory",
|
|
1987
|
+
title: "Recurring Tracking & Memory",
|
|
1988
|
+
description: "Run a check on a daily, weekly, or custom cadence with no external cron needed, and save each result somewhere searchable so you can compare against past runs later - rankings, prices, competitor changes, anything you would otherwise check by hand and forget to log.",
|
|
1989
|
+
primaryWorkflowId: null,
|
|
1990
|
+
recommendedTools: ["create-scheduled-action", "search_serp", "table-create", "table-insert-rows", "table-query", "memory-put", "memory-search", "list-scheduled-actions"],
|
|
1991
|
+
requiredInputs: ["plain-language description of what to check and how often"],
|
|
1992
|
+
optionalInputs: ["vault to save into", "timeOfDay", "timezone"],
|
|
1993
|
+
produces: ["a live scheduled action that runs automatically on cadence", "a table row or note per run for structured history", "a searchable trend you can compare run-over-run"],
|
|
1994
|
+
runHint: "Use create-scheduled-action with a plain description and cadence; the run itself checks list-vaults, uses table-insert-rows for repeating structured data (e.g. a keyword rank check) or memory-put for a one-off note, and reads prior runs with table-query or memory-search before writing the new one. For a one-time blueprint to build your own external cron/DB instead of a live scheduled action, use rank_tracker_workflow."
|
|
1995
|
+
},
|
|
1979
1996
|
{
|
|
1980
1997
|
id: "ai_search_visibility_audit",
|
|
1981
1998
|
title: "AI Search Visibility Audit",
|
|
@@ -4195,6 +4212,9 @@ function formatMapsPlaceIntel(raw, input) {
|
|
|
4195
4212
|
const about = d.aboutAttributes ?? [];
|
|
4196
4213
|
const reviews = d.reviews ?? [];
|
|
4197
4214
|
const reviewsStatus = d.reviewsStatus ?? "not_requested";
|
|
4215
|
+
const services = d.services ?? [];
|
|
4216
|
+
const areasServed = d.areasServed ?? [];
|
|
4217
|
+
const servicesStatus = d.servicesStatus ?? "not_requested";
|
|
4198
4218
|
const hoursTable = d.hoursTable ?? [];
|
|
4199
4219
|
const ratingLine = [rating, reviewCount ? `(${reviewCount} reviews)` : null].filter(Boolean).join(" ");
|
|
4200
4220
|
const basicLines = [
|
|
@@ -4249,6 +4269,20 @@ ${reviews.map((r, i) => {
|
|
|
4249
4269
|
${r.text ?? ""}`;
|
|
4250
4270
|
}).join("\n\n")}`;
|
|
4251
4271
|
})();
|
|
4272
|
+
const servicesSection = (() => {
|
|
4273
|
+
if (servicesStatus === "not_requested") return "";
|
|
4274
|
+
if (servicesStatus === "unavailable") return "\n## Services & Areas Served\n> Could not be retrieved this run \u2014 retry with `includeServices: true`.";
|
|
4275
|
+
if (servicesStatus === "none_exist") return "\n## Services & Areas Served\n*Not listed on this business's profile.*";
|
|
4276
|
+
const parts = [
|
|
4277
|
+
services.length ? `**Services**
|
|
4278
|
+
${services.map((s) => `- ${s}`).join("\n")}` : null,
|
|
4279
|
+
areasServed.length ? `**Areas Served**
|
|
4280
|
+
${areasServed.map((a) => `- ${a}`).join("\n")}` : null
|
|
4281
|
+
].filter(Boolean);
|
|
4282
|
+
return parts.length ? `
|
|
4283
|
+
## Services & Areas Served
|
|
4284
|
+
${parts.join("\n\n")}` : "";
|
|
4285
|
+
})();
|
|
4252
4286
|
const full = [
|
|
4253
4287
|
`# ${name}`,
|
|
4254
4288
|
category ? `*${category}*` : null,
|
|
@@ -4264,6 +4298,7 @@ ${basicLines}` : null,
|
|
|
4264
4298
|
## Entity IDs
|
|
4265
4299
|
${entitySection}` : null,
|
|
4266
4300
|
reviewsSection,
|
|
4301
|
+
servicesSection,
|
|
4267
4302
|
durationMs != null ? `
|
|
4268
4303
|
---
|
|
4269
4304
|
*Extracted in ${(durationMs / 1e3).toFixed(1)}s*` : null
|
|
@@ -4287,7 +4322,10 @@ ${entitySection}` : null,
|
|
|
4287
4322
|
lng: lng ?? null,
|
|
4288
4323
|
reviewsStatus,
|
|
4289
4324
|
reviewsCollected: reviews.length,
|
|
4290
|
-
reviewTopics: topics.map((t) => ({ label: String(t.label ?? ""), count: String(t.count ?? "") }))
|
|
4325
|
+
reviewTopics: topics.map((t) => ({ label: String(t.label ?? ""), count: String(t.count ?? "") })),
|
|
4326
|
+
services,
|
|
4327
|
+
areasServed,
|
|
4328
|
+
servicesStatus
|
|
4291
4329
|
}
|
|
4292
4330
|
};
|
|
4293
4331
|
}
|
|
@@ -4782,6 +4820,23 @@ Multi-step orchestrations \u2014 prefer these over hand-chaining primitives when
|
|
|
4782
4820
|
answers the question (plain search/extract before browser agents).
|
|
4783
4821
|
- Large results are saved to disk or an artifact and returned as a summary plus a path or artifactId;
|
|
4784
4822
|
read it back for full detail rather than expecting the whole payload inline.
|
|
4823
|
+
|
|
4824
|
+
## Memory
|
|
4825
|
+
mcp-scraper also exposes 74 persistent per-user memory tools (notes, facts, vaults,
|
|
4826
|
+
scheduled actions, tables, channels) backed by memory.mcpscraper.dev. Every account starts with 13
|
|
4827
|
+
vaults \u2014 call **list-vaults** to see what exists before creating anything new. Pick the vault whose job
|
|
4828
|
+
matches the content: **Ideas** (unvalidated concepts), **Knowledge** (distilled lessons/how-tos),
|
|
4829
|
+
**Library** (raw source material \u2014 articles, transcripts), **People** (one durable note per person/org),
|
|
4830
|
+
**Communications** (individual conversation records), **Calendar** (time-anchored entries), **Tasks**
|
|
4831
|
+
(action items with a status), **Projects** (durable named initiatives), **Issues** (something broken),
|
|
4832
|
+
**Improvement Log** (receipts of changes made and whether they worked), **Experiments** (hypothesis +
|
|
4833
|
+
measured result), **Sprint** (current cycle's scope), **Inspiration** (other people's work worth
|
|
4834
|
+
studying).
|
|
4835
|
+
Before writing, call **memory-suggest** to check whether something's already captured and to find the
|
|
4836
|
+
right vault's hub note to link. Use **memory-put** for narrative notes (prose, a title, a body); use
|
|
4837
|
+
**table-create**/**table-insert-rows**/**table-query** instead when the caller wants row-shaped data
|
|
4838
|
+
they'll filter/sort by exact value. **memory-search** is meaning-based over full content (embeds, slower);
|
|
4839
|
+
**memory-list** filters one vault by kind/tags (fast, exact).
|
|
4785
4840
|
`.trim();
|
|
4786
4841
|
}
|
|
4787
4842
|
var SERVER_INSTRUCTIONS = serverInstructions(true);
|
|
@@ -4823,6 +4878,7 @@ var MapsPlaceOptionsSchema = import_zod2.z.object({
|
|
|
4823
4878
|
hl: import_zod2.z.string().length(2).default("en"),
|
|
4824
4879
|
includeReviews: import_zod2.z.boolean().default(false),
|
|
4825
4880
|
maxReviews: import_zod2.z.number().int().min(1).max(500).default(50),
|
|
4881
|
+
includeServices: import_zod2.z.boolean().default(false),
|
|
4826
4882
|
kernelApiKey: import_zod2.z.string().optional(),
|
|
4827
4883
|
kernelProxyId: import_zod2.z.string().optional(),
|
|
4828
4884
|
headless: import_zod2.z.boolean().default(true)
|
|
@@ -5011,7 +5067,8 @@ var MapsPlaceIntelInputSchema = {
|
|
|
5011
5067
|
gl: import_zod3.z.string().length(2).default("us").describe("Google country code inferred from location."),
|
|
5012
5068
|
hl: import_zod3.z.string().length(2).default("en").describe("Language inferred from user request."),
|
|
5013
5069
|
includeReviews: import_zod3.z.boolean().default(false).describe("Fetch individual review cards \u2014 for reviews, customer pain, complaints, or praise themes."),
|
|
5014
|
-
maxReviews: import_zod3.z.number().int().min(1).max(500).default(50).describe("Max review cards when includeReviews is true. Default 50, maximum 500.")
|
|
5070
|
+
maxReviews: import_zod3.z.number().int().min(1).max(500).default(50).describe("Max review cards when includeReviews is true. Default 50, maximum 500."),
|
|
5071
|
+
includeServices: import_zod3.z.boolean().default(false).describe("Fetch the business's configured services list and areas-served list, when the profile has them. Adds one extra page visit; not present for every business.")
|
|
5015
5072
|
};
|
|
5016
5073
|
var MapsSearchInputSchema = {
|
|
5017
5074
|
query: import_zod3.z.string().min(1).describe('Business category, niche, or search term, e.g. "roofers". Do not include location here \u2014 use location instead.'),
|
|
@@ -5324,7 +5381,10 @@ var MapsPlaceIntelOutputSchema = {
|
|
|
5324
5381
|
reviewTopics: import_zod3.z.array(import_zod3.z.object({
|
|
5325
5382
|
label: import_zod3.z.string(),
|
|
5326
5383
|
count: import_zod3.z.string()
|
|
5327
|
-
}))
|
|
5384
|
+
})),
|
|
5385
|
+
services: import_zod3.z.array(import_zod3.z.string()),
|
|
5386
|
+
areasServed: import_zod3.z.array(import_zod3.z.string()),
|
|
5387
|
+
servicesStatus: import_zod3.z.string()
|
|
5328
5388
|
};
|
|
5329
5389
|
var CreditsInfoOutputSchema = {
|
|
5330
5390
|
balanceCredits: import_zod3.z.number().nullable(),
|
|
@@ -5827,7 +5887,7 @@ var ReportArtifactReadOutputSchema = {
|
|
|
5827
5887
|
|
|
5828
5888
|
// src/mcp/rank-tracker-blueprint.ts
|
|
5829
5889
|
var DEFAULT_MODES = ["maps", "organic", "ai_overview", "paa"];
|
|
5830
|
-
function
|
|
5890
|
+
function normalizeDomain2(value) {
|
|
5831
5891
|
const trimmed = value?.trim();
|
|
5832
5892
|
if (!trimmed) return null;
|
|
5833
5893
|
try {
|
|
@@ -6089,7 +6149,7 @@ function buildPrompt(input, modes, tools, tables, jobs, metrics, expression, tar
|
|
|
6089
6149
|
}
|
|
6090
6150
|
function buildRankTrackerBlueprint(input) {
|
|
6091
6151
|
const trackingModes = uniqueModes(input.trackingModes);
|
|
6092
|
-
const targetDomain =
|
|
6152
|
+
const targetDomain = normalizeDomain2(input.targetDomain);
|
|
6093
6153
|
const targetBusinessName = input.targetBusinessName?.trim() || null;
|
|
6094
6154
|
const projectName = input.projectName?.trim() || "MCP Scraper Rank Tracker";
|
|
6095
6155
|
const database = input.database || "postgres";
|
|
@@ -8588,13 +8648,14 @@ function renderInstallTerminal(options) {
|
|
|
8588
8648
|
"1/1 install surfaces ready",
|
|
8589
8649
|
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),
|
|
8590
8650
|
"",
|
|
8591
|
-
`${colorize("Tools", "cyan", color)} ${colorize("(
|
|
8651
|
+
`${colorize("Tools", "cyan", color)} ${colorize("(128 MCP tools)", "muted", color)}`,
|
|
8592
8652
|
toolRow("search", ["harvest_paa", "search_serp", "maps_search", "maps_place_intel"], color),
|
|
8593
8653
|
toolRow("extract", ["extract_url", "map_site_urls", "extract_site", "audit_site", "directory_workflow"], color),
|
|
8594
8654
|
toolRow("build", ["rank_tracker_workflow", "cron plan", "database prompt"], color),
|
|
8595
8655
|
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),
|
|
8596
8656
|
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),
|
|
8597
8657
|
toolRow("account", ["credits_info", "reports", "MCP resources"], color),
|
|
8658
|
+
toolRow("memory", ["memory-put", "memory-get", "memory-search", "list-vaults", "record-fact", "list-scheduled-actions"], color),
|
|
8598
8659
|
`${colorize("Workflows", "cyan", color)} ${colorize("(MCP + CLI + API)", "muted", color)}`,
|
|
8599
8660
|
toolRow("route", ["workflow_list", "workflow_suggest", "workflow_run", "workflow_step", "workflow_status", "workflow_artifact_read"], color),
|
|
8600
8661
|
toolRow("seo", ["directory", "agent-packet", "competitive audit", "map/serp comparison", "PAA/AIO briefs", "scheduled runs"], color),
|