mcp-scraper 0.42.3 → 0.43.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/README.md +2 -2
- package/dist/bin/api-server.cjs +3284 -2130
- 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 +3 -4
- package/dist/bin/mcp-scraper-cli.js.map +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 +3361 -2817
- package/dist/bin/mcp-stdio-server.cjs.map +1 -1
- package/dist/bin/mcp-stdio-server.js +51 -24
- package/dist/bin/mcp-stdio-server.js.map +1 -1
- package/dist/bin/paa-harvest.cjs +21 -21
- package/dist/bin/paa-harvest.cjs.map +1 -1
- package/dist/bin/paa-harvest.js +2 -3
- package/dist/bin/paa-harvest.js.map +1 -1
- package/dist/{chunk-MJKVDLVR.js → chunk-2K74LVV7.js} +26 -2
- package/dist/{chunk-MJKVDLVR.js.map → chunk-2K74LVV7.js.map} +1 -1
- package/dist/{chunk-CB5C3BPB.js → chunk-3ZUBQQPQ.js} +23 -2
- package/dist/chunk-3ZUBQQPQ.js.map +1 -0
- package/dist/{chunk-6Q7V4IQV.js → chunk-6WLNXYRG.js} +19 -2
- package/dist/chunk-6WLNXYRG.js.map +1 -0
- package/dist/{chunk-G5MHJGKE.js → chunk-GUI33Q27.js} +2 -2
- package/dist/{chunk-DH42LIR3.js → chunk-H7LQ6PTI.js} +24 -16
- package/dist/chunk-H7LQ6PTI.js.map +1 -0
- package/dist/chunk-MD75M2L5.js +7 -0
- package/dist/chunk-MD75M2L5.js.map +1 -0
- package/dist/{chunk-ENJQ2NSX.js → chunk-TC4GDB2Q.js} +2 -2
- package/dist/{chunk-ENJQ2NSX.js.map → chunk-TC4GDB2Q.js.map} +1 -1
- package/dist/{chunk-IMUA3FJB.js → chunk-X5WDJ7D7.js} +6 -6
- package/dist/chunk-X5WDJ7D7.js.map +1 -0
- package/dist/{chunk-QKCDYMFT.js → chunk-YJNGNMDO.js} +2196 -1584
- package/dist/chunk-YJNGNMDO.js.map +1 -0
- package/dist/{chunk-FQI5PFE7.js → chunk-ZSJHRZY5.js} +3 -5
- package/dist/{chunk-FQI5PFE7.js.map → chunk-ZSJHRZY5.js.map} +1 -1
- package/dist/{extract-bundle-FH734F3R.js → extract-bundle-IOM45SFL.js} +5 -5
- package/dist/index.cjs +21 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +21 -57
- package/dist/index.d.ts +21 -57
- package/dist/index.js +2 -3
- package/dist/index.js.map +1 -1
- package/dist/{server-B27DR4YB.js → server-BPEXEKA6.js} +800 -336
- package/dist/server-BPEXEKA6.js.map +1 -0
- package/dist/{site-extract-repository-5CVI3OWT.js → site-extract-repository-XNI4ZK2M.js} +3 -3
- package/dist/{worker-MQJOY4YP.js → worker-2LIOH744.js} +4 -5
- package/dist/{worker-MQJOY4YP.js.map → worker-2LIOH744.js.map} +1 -1
- package/package.json +10 -7
- package/dist/chunk-2YFTFT3V.js +0 -7
- package/dist/chunk-2YFTFT3V.js.map +0 -1
- package/dist/chunk-6Q7V4IQV.js.map +0 -1
- package/dist/chunk-CB5C3BPB.js.map +0 -1
- package/dist/chunk-DH42LIR3.js.map +0 -1
- package/dist/chunk-IMUA3FJB.js.map +0 -1
- package/dist/chunk-K443GQY5.js +0 -24
- package/dist/chunk-K443GQY5.js.map +0 -1
- package/dist/chunk-QKCDYMFT.js.map +0 -1
- package/dist/server-B27DR4YB.js.map +0 -1
- /package/dist/{chunk-G5MHJGKE.js.map → chunk-GUI33Q27.js.map} +0 -0
- /package/dist/{extract-bundle-FH734F3R.js.map → extract-bundle-IOM45SFL.js.map} +0 -0
- /package/dist/{site-extract-repository-5CVI3OWT.js.map → site-extract-repository-XNI4ZK2M.js.map} +0 -0
|
@@ -1,26 +1,27 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
HttpMcpToolExecutor,
|
|
4
|
-
|
|
4
|
+
MEMORY_TOOL_REGISTRY,
|
|
5
5
|
SERVER_INSTRUCTIONS,
|
|
6
6
|
ScheduledResultsMcpExecutor,
|
|
7
|
+
permitsLocalNetworkAccess,
|
|
7
8
|
registerBrowserAgentMcpTools,
|
|
8
9
|
registerMemoryMcpTools,
|
|
9
10
|
registerPaaExtractorMcpTools,
|
|
10
11
|
registerScheduledResultsMcpTools,
|
|
11
|
-
registerSerpIntelligenceCaptureTools
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
registerSerpIntelligenceCaptureTools,
|
|
13
|
+
resolveDeploymentProfile
|
|
14
|
+
} from "../chunk-YJNGNMDO.js";
|
|
15
|
+
import "../chunk-2K74LVV7.js";
|
|
14
16
|
import "../chunk-BBI7RGOT.js";
|
|
15
17
|
import "../chunk-DAS7L4SF.js";
|
|
16
18
|
import {
|
|
17
19
|
renderInstallTerminal
|
|
18
|
-
} from "../chunk-
|
|
19
|
-
import "../chunk-CB5C3BPB.js";
|
|
20
|
+
} from "../chunk-TC4GDB2Q.js";
|
|
20
21
|
import {
|
|
21
22
|
PACKAGE_VERSION
|
|
22
|
-
} from "../chunk-
|
|
23
|
-
import "../chunk-
|
|
23
|
+
} from "../chunk-MD75M2L5.js";
|
|
24
|
+
import "../chunk-X5WDJ7D7.js";
|
|
24
25
|
import "../chunk-5UN33CGU.js";
|
|
25
26
|
import "../chunk-FCFQ634B.js";
|
|
26
27
|
|
|
@@ -28,12 +29,12 @@ import "../chunk-FCFQ634B.js";
|
|
|
28
29
|
import { readFileSync } from "fs";
|
|
29
30
|
import { homedir } from "os";
|
|
30
31
|
import { join } from "path";
|
|
31
|
-
import {
|
|
32
|
-
import {
|
|
32
|
+
import { serveStdio } from "@modelcontextprotocol/server/stdio";
|
|
33
|
+
import { McpServer } from "@modelcontextprotocol/server";
|
|
33
34
|
|
|
34
35
|
// src/mcp/hosted-memory-mcp-tool-executor.ts
|
|
35
36
|
var publicToolNameByUpstreamName = new Map(
|
|
36
|
-
|
|
37
|
+
MEMORY_TOOL_REGISTRY.map((schema) => [schema.upstreamName, schema.id])
|
|
37
38
|
);
|
|
38
39
|
function parseJsonRpcEnvelope(text) {
|
|
39
40
|
const payloads = text.split("\n").filter((line) => line.startsWith("data:")).map((line) => line.slice(5).trim()).filter(Boolean);
|
|
@@ -118,22 +119,48 @@ if (!apiKey) {
|
|
|
118
119
|
process.stderr.write("MCP_SCRAPER_API_KEY env var or ~/.mcp-scraper-key is required\n");
|
|
119
120
|
process.exit(1);
|
|
120
121
|
}
|
|
122
|
+
var requiredApiKey = apiKey;
|
|
121
123
|
var baseUrl = process.env.MCP_SCRAPER_BASE_URL?.trim() || process.env.MCP_BASE_URL?.trim() || "https://mcpscraper.dev";
|
|
124
|
+
var deploymentProfile = resolveDeploymentProfile();
|
|
125
|
+
var localNetworkAccess = permitsLocalNetworkAccess({
|
|
126
|
+
deploymentProfile,
|
|
127
|
+
transportProfile: "stdio",
|
|
128
|
+
baseUrl,
|
|
129
|
+
explicitlyEnabled: process.env.MCP_SCRAPER_ALLOW_PRIVATE_NETWORK === "1"
|
|
130
|
+
});
|
|
122
131
|
var consoleBaseUrl = process.env.BROWSER_AGENT_CONSOLE_URL?.trim() || baseUrl;
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
132
|
+
function buildStdioServer() {
|
|
133
|
+
const server = new McpServer({ name: "mcp-scraper", version: PACKAGE_VERSION }, {
|
|
134
|
+
instructions: SERVER_INSTRUCTIONS,
|
|
135
|
+
cacheHints: {
|
|
136
|
+
"server/discover": { ttlMs: 3e5, cacheScope: "private" },
|
|
137
|
+
"tools/list": { ttlMs: 3e5, cacheScope: "private" },
|
|
138
|
+
"resources/list": { ttlMs: 3e5, cacheScope: "private" },
|
|
139
|
+
"resources/templates/list": { ttlMs: 3e5, cacheScope: "private" },
|
|
140
|
+
"resources/read": { ttlMs: 6e4, cacheScope: "private" }
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
const httpExecutor = new HttpMcpToolExecutor(baseUrl, requiredApiKey, { localNetworkAccess });
|
|
144
|
+
registerPaaExtractorMcpTools(server, httpExecutor, {
|
|
145
|
+
deploymentProfile,
|
|
146
|
+
transportProfile: "stdio",
|
|
147
|
+
baseUrl,
|
|
148
|
+
localNetworkAccess,
|
|
149
|
+
taskHandleSecret: requiredApiKey
|
|
150
|
+
});
|
|
151
|
+
registerSerpIntelligenceCaptureTools(server, httpExecutor, {
|
|
152
|
+
exposeDevelopmentDiagnostics: deploymentProfile === "development" || deploymentProfile === "test"
|
|
153
|
+
});
|
|
154
|
+
registerBrowserAgentMcpTools(server, { baseUrl, apiKey: requiredApiKey, consoleBaseUrl });
|
|
155
|
+
registerScheduledResultsMcpTools(server, new ScheduledResultsMcpExecutor(baseUrl, requiredApiKey));
|
|
156
|
+
registerMemoryMcpTools(server, new HostedMemoryMcpToolExecutor(baseUrl, requiredApiKey));
|
|
157
|
+
return server;
|
|
133
158
|
}
|
|
134
|
-
|
|
135
|
-
|
|
159
|
+
serveStdio(() => buildStdioServer(), {
|
|
160
|
+
legacy: "serve",
|
|
161
|
+
onerror(error) {
|
|
162
|
+
process.stderr.write(`${error.message}
|
|
136
163
|
`);
|
|
137
|
-
|
|
164
|
+
}
|
|
138
165
|
});
|
|
139
166
|
//# sourceMappingURL=mcp-stdio-server.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../bin/mcp-stdio-server.ts","../../src/mcp/hosted-memory-mcp-tool-executor.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { readFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { HttpMcpToolExecutor } from '../src/mcp/http-mcp-tool-executor.js'\nimport { registerBrowserAgentMcpTools } from '../src/mcp/browser-agent-mcp-server.js'\nimport { registerPaaExtractorMcpTools, registerSerpIntelligenceCaptureTools } from '../src/mcp/paa-mcp-server.js'\nimport { registerMemoryMcpTools } from '../src/mcp/memory-mcp-server.js'\nimport { HostedMemoryMcpToolExecutor } from '../src/mcp/hosted-memory-mcp-tool-executor.js'\nimport { SERVER_INSTRUCTIONS } from '../src/mcp/server-instructions.js'\nimport { renderInstallTerminal } from '../src/install-terminal.js'\nimport { PACKAGE_VERSION } from '../src/version.js'\nimport {\n registerScheduledResultsMcpTools,\n ScheduledResultsMcpExecutor,\n} from '../src/mcp/scheduled-results-mcp-server.js'\n\nconst forceStdio =\n process.argv.includes('--stdio') ||\n process.env.MCP_SCRAPER_FORCE_STDIO === '1'\nconst interactiveTerminal = Boolean(process.stdin.isTTY && process.stdout.isTTY)\nconst wantsHelp = process.argv.includes('--help') || process.argv.includes('-h')\n\nif (!forceStdio && (interactiveTerminal || wantsHelp)) {\n const noColor =\n process.argv.includes('--no-color') ||\n process.env.NO_COLOR !== undefined ||\n process.env.FORCE_COLOR === '0' ||\n !process.stdout.isTTY\n\n process.stdout.write(renderInstallTerminal({\n version: PACKAGE_VERSION,\n color: !noColor,\n apiKeyConfigured: Boolean(process.env.MCP_SCRAPER_API_KEY?.trim()),\n }))\n process.exit(0)\n}\n\nfunction readApiKeyFile(): string | undefined {\n const explicitPath = process.env.MCP_SCRAPER_KEY_PATH?.trim()\n const paths = [explicitPath, join(homedir(), '.mcp-scraper-key')].filter(Boolean) as string[]\n for (const path of paths) {\n try {\n const value = readFileSync(path, 'utf8').trim()\n if (value) return value\n } catch {\n void 0\n }\n }\n return undefined\n}\n\nconst apiKey = (\n process.env.MCP_SCRAPER_API_KEY ??\n process.env.MCP_SCRAPER_KEY ??\n process.env.MCP_API_KEY ??\n readApiKeyFile()\n)?.trim()\nif (!apiKey) {\n process.stderr.write('MCP_SCRAPER_API_KEY env var or ~/.mcp-scraper-key is required\\n')\n process.exit(1)\n}\n\nconst baseUrl = process.env.MCP_SCRAPER_BASE_URL?.trim() || process.env.MCP_BASE_URL?.trim() || 'https://mcpscraper.dev'\nconst consoleBaseUrl = process.env.BROWSER_AGENT_CONSOLE_URL?.trim() || baseUrl\nconst server = new McpServer({ name: 'mcp-scraper', version: PACKAGE_VERSION }, { instructions: SERVER_INSTRUCTIONS })\n\nconst httpExecutor = new HttpMcpToolExecutor(baseUrl, apiKey)\nregisterPaaExtractorMcpTools(server, httpExecutor)\nregisterSerpIntelligenceCaptureTools(server, httpExecutor)\nregisterBrowserAgentMcpTools(server, { baseUrl, apiKey, consoleBaseUrl })\nregisterScheduledResultsMcpTools(server, new ScheduledResultsMcpExecutor(baseUrl, apiKey))\nregisterMemoryMcpTools(server, new HostedMemoryMcpToolExecutor(baseUrl, apiKey))\n\nconst transport = new StdioServerTransport()\n\nasync function main() {\n await server.connect(transport)\n}\n\nmain().catch(err => {\n process.stderr.write(`${err instanceof Error ? err.message : String(err)}\\n`)\n process.exit(1)\n})\n","import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js'\nimport { MEMORY_TOOL_SCHEMAS } from './memory-tool-schemas.js'\n\nconst publicToolNameByUpstreamName = new Map(\n MEMORY_TOOL_SCHEMAS.map(schema => [schema.upstreamName, schema.id]),\n)\n\ninterface JsonRpcEnvelope {\n result?: CallToolResult\n error?: { code?: number; message?: string }\n}\n\nfunction parseJsonRpcEnvelope(text: string): JsonRpcEnvelope {\n const payloads = text\n .split('\\n')\n .filter(line => line.startsWith('data:'))\n .map(line => line.slice(5).trim())\n .filter(Boolean)\n\n if (!payloads.length) return JSON.parse(text) as JsonRpcEnvelope\n\n for (const payload of payloads) {\n const parsed = JSON.parse(payload) as JsonRpcEnvelope\n if (parsed.result || parsed.error) return parsed\n }\n throw new Error('hosted MCP returned no JSON-RPC result')\n}\n\nfunction errorResult(message: string): CallToolResult {\n return {\n content: [{ type: 'text', text: JSON.stringify({ ok: false, error: message }) }],\n isError: true,\n }\n}\n\n/**\n * Stdio-only bridge for memory tools. It deliberately calls the hosted aggregate\n * MCP surface so local clients execute the same registered tool implementation\n * and output contract as https://mcpscraper.dev/mcp.\n */\nexport class HostedMemoryMcpToolExecutor {\n private readonly baseUrl: string\n private readonly apiKey: string\n\n constructor(baseUrl: string, apiKey: string) {\n this.baseUrl = baseUrl.replace(/\\/$/, '')\n this.apiKey = apiKey\n }\n\n async callMemoryTool(upstreamName: string, args: Record<string, unknown>): Promise<CallToolResult> {\n const publicToolName = publicToolNameByUpstreamName.get(upstreamName)\n if (!publicToolName) return errorResult(`unknown memory tool: ${upstreamName}`)\n\n try {\n const res = await fetch(`${this.baseUrl}/mcp`, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n accept: 'application/json, text/event-stream',\n 'x-api-key': this.apiKey,\n },\n body: JSON.stringify({\n jsonrpc: '2.0',\n id: `memory:${publicToolName}`,\n method: 'tools/call',\n params: { name: publicToolName, arguments: args },\n }),\n })\n const text = await res.text()\n if (!res.ok) return errorResult(`hosted memory ${publicToolName} failed (HTTP ${res.status})`)\n\n const envelope = parseJsonRpcEnvelope(text)\n if (envelope.error) {\n return errorResult(envelope.error.message ?? `hosted memory ${publicToolName} failed`)\n }\n return envelope.result ?? errorResult(`hosted memory ${publicToolName} returned no result`)\n } catch (err) {\n return errorResult(err instanceof Error ? err.message : `hosted memory ${publicToolName} call failed`)\n }\n }\n}\n"],"mappings":"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","names":["baseUrl","apiKey"]}
|
|
1
|
+
{"version":3,"sources":["../../bin/mcp-stdio-server.ts","../../src/mcp/hosted-memory-mcp-tool-executor.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { readFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { serveStdio } from '@modelcontextprotocol/server/stdio'\nimport { McpServer } from \"@modelcontextprotocol/server\";\nimport { HttpMcpToolExecutor } from '../src/mcp/http-mcp-tool-executor.js'\nimport { registerBrowserAgentMcpTools } from '../src/mcp/browser-agent-mcp-server.js'\nimport { registerPaaExtractorMcpTools, registerSerpIntelligenceCaptureTools } from '../src/mcp/paa-mcp-server.js'\nimport { registerMemoryMcpTools } from '../src/mcp/memory-mcp-server.js'\nimport { HostedMemoryMcpToolExecutor } from '../src/mcp/hosted-memory-mcp-tool-executor.js'\nimport { SERVER_INSTRUCTIONS } from '../src/mcp/server-instructions.js'\nimport { renderInstallTerminal } from '../src/install-terminal.js'\nimport { PACKAGE_VERSION } from '../src/version.js'\nimport { permitsLocalNetworkAccess, resolveDeploymentProfile } from '../src/runtime/deployment-profile.js'\nimport {\n registerScheduledResultsMcpTools,\n ScheduledResultsMcpExecutor,\n} from '../src/mcp/scheduled-results-mcp-server.js'\n\nconst forceStdio =\n process.argv.includes('--stdio') ||\n process.env.MCP_SCRAPER_FORCE_STDIO === '1'\nconst interactiveTerminal = Boolean(process.stdin.isTTY && process.stdout.isTTY)\nconst wantsHelp = process.argv.includes('--help') || process.argv.includes('-h')\n\nif (!forceStdio && (interactiveTerminal || wantsHelp)) {\n const noColor =\n process.argv.includes('--no-color') ||\n process.env.NO_COLOR !== undefined ||\n process.env.FORCE_COLOR === '0' ||\n !process.stdout.isTTY\n\n process.stdout.write(renderInstallTerminal({\n version: PACKAGE_VERSION,\n color: !noColor,\n apiKeyConfigured: Boolean(process.env.MCP_SCRAPER_API_KEY?.trim()),\n }))\n process.exit(0)\n}\n\nfunction readApiKeyFile(): string | undefined {\n const explicitPath = process.env.MCP_SCRAPER_KEY_PATH?.trim()\n const paths = [explicitPath, join(homedir(), '.mcp-scraper-key')].filter(Boolean) as string[]\n for (const path of paths) {\n try {\n const value = readFileSync(path, 'utf8').trim()\n if (value) return value\n } catch {\n void 0\n }\n }\n return undefined\n}\n\nconst apiKey = (\n process.env.MCP_SCRAPER_API_KEY ??\n process.env.MCP_SCRAPER_KEY ??\n process.env.MCP_API_KEY ??\n readApiKeyFile()\n)?.trim()\nif (!apiKey) {\n process.stderr.write('MCP_SCRAPER_API_KEY env var or ~/.mcp-scraper-key is required\\n')\n process.exit(1)\n}\nconst requiredApiKey = apiKey as string\n\nconst baseUrl = process.env.MCP_SCRAPER_BASE_URL?.trim() || process.env.MCP_BASE_URL?.trim() || 'https://mcpscraper.dev'\nconst deploymentProfile = resolveDeploymentProfile()\nconst localNetworkAccess = permitsLocalNetworkAccess({\n deploymentProfile,\n transportProfile: 'stdio',\n baseUrl,\n explicitlyEnabled: process.env.MCP_SCRAPER_ALLOW_PRIVATE_NETWORK === '1',\n})\nconst consoleBaseUrl = process.env.BROWSER_AGENT_CONSOLE_URL?.trim() || baseUrl\nfunction buildStdioServer(): McpServer {\n const server = new McpServer({ name: 'mcp-scraper', version: PACKAGE_VERSION }, {\n instructions: SERVER_INSTRUCTIONS,\n cacheHints: {\n 'server/discover': { ttlMs: 300_000, cacheScope: 'private' },\n 'tools/list': { ttlMs: 300_000, cacheScope: 'private' },\n 'resources/list': { ttlMs: 300_000, cacheScope: 'private' },\n 'resources/templates/list': { ttlMs: 300_000, cacheScope: 'private' },\n 'resources/read': { ttlMs: 60_000, cacheScope: 'private' },\n },\n })\n const httpExecutor = new HttpMcpToolExecutor(baseUrl, requiredApiKey, { localNetworkAccess })\n registerPaaExtractorMcpTools(server, httpExecutor, {\n deploymentProfile,\n transportProfile: 'stdio',\n baseUrl,\n localNetworkAccess,\n taskHandleSecret: requiredApiKey,\n })\n registerSerpIntelligenceCaptureTools(server, httpExecutor, {\n exposeDevelopmentDiagnostics: deploymentProfile === 'development' || deploymentProfile === 'test',\n })\n registerBrowserAgentMcpTools(server, { baseUrl, apiKey: requiredApiKey, consoleBaseUrl })\n registerScheduledResultsMcpTools(server, new ScheduledResultsMcpExecutor(baseUrl, requiredApiKey))\n registerMemoryMcpTools(server, new HostedMemoryMcpToolExecutor(baseUrl, requiredApiKey))\n return server\n}\n\nserveStdio(() => buildStdioServer(), {\n legacy: 'serve',\n onerror(error) {\n process.stderr.write(`${error.message}\\n`)\n },\n})\n","import type { CallToolResult } from \"@modelcontextprotocol/server\";\nimport { MEMORY_TOOL_REGISTRY } from './memory-tool-registry.js'\n\nconst publicToolNameByUpstreamName = new Map(\n MEMORY_TOOL_REGISTRY.map(schema => [schema.upstreamName, schema.id]),\n)\n\ninterface JsonRpcEnvelope {\n result?: CallToolResult\n error?: { code?: number; message?: string }\n}\n\nfunction parseJsonRpcEnvelope(text: string): JsonRpcEnvelope {\n const payloads = text\n .split('\\n')\n .filter(line => line.startsWith('data:'))\n .map(line => line.slice(5).trim())\n .filter(Boolean)\n\n if (!payloads.length) return JSON.parse(text) as JsonRpcEnvelope\n\n for (const payload of payloads) {\n const parsed = JSON.parse(payload) as JsonRpcEnvelope\n if (parsed.result || parsed.error) return parsed\n }\n throw new Error('hosted MCP returned no JSON-RPC result')\n}\n\nfunction errorResult(message: string): CallToolResult {\n return {\n content: [{ type: 'text', text: JSON.stringify({ ok: false, error: message }) }],\n isError: true,\n }\n}\n\n/**\n * Stdio-only bridge for memory tools. It deliberately calls the hosted aggregate\n * MCP surface so local clients execute the same registered tool implementation\n * and output contract as https://mcpscraper.dev/mcp.\n */\nexport class HostedMemoryMcpToolExecutor {\n private readonly baseUrl: string\n private readonly apiKey: string\n\n constructor(baseUrl: string, apiKey: string) {\n this.baseUrl = baseUrl.replace(/\\/$/, '')\n this.apiKey = apiKey\n }\n\n async callMemoryTool(upstreamName: string, args: Record<string, unknown>): Promise<CallToolResult> {\n const publicToolName = publicToolNameByUpstreamName.get(upstreamName)\n if (!publicToolName) return errorResult(`unknown memory tool: ${upstreamName}`)\n\n try {\n const res = await fetch(`${this.baseUrl}/mcp`, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n accept: 'application/json, text/event-stream',\n 'x-api-key': this.apiKey,\n },\n body: JSON.stringify({\n jsonrpc: '2.0',\n id: `memory:${publicToolName}`,\n method: 'tools/call',\n params: { name: publicToolName, arguments: args },\n }),\n })\n const text = await res.text()\n if (!res.ok) return errorResult(`hosted memory ${publicToolName} failed (HTTP ${res.status})`)\n\n const envelope = parseJsonRpcEnvelope(text)\n if (envelope.error) {\n return errorResult(envelope.error.message ?? `hosted memory ${publicToolName} failed`)\n }\n return envelope.result ?? errorResult(`hosted memory ${publicToolName} returned no result`)\n } catch (err) {\n return errorResult(err instanceof Error ? err.message : `hosted memory ${publicToolName} call failed`)\n }\n }\n}\n"],"mappings":"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","names":["baseUrl","apiKey"]}
|
package/dist/bin/paa-harvest.cjs
CHANGED
|
@@ -546,11 +546,21 @@ async function ensureKernelProfile(kernelClient, name) {
|
|
|
546
546
|
if (!isKernelProfileConflict(err)) throw err;
|
|
547
547
|
}
|
|
548
548
|
}
|
|
549
|
-
function
|
|
549
|
+
async function detectRuntimeUserAgent(browser) {
|
|
550
|
+
try {
|
|
551
|
+
const page = browser.contexts()[0]?.pages()[0];
|
|
552
|
+
if (!page) return null;
|
|
553
|
+
const ua = await page.evaluate(() => navigator.userAgent);
|
|
554
|
+
return typeof ua === "string" && /Chrome\/\d+/.test(ua) ? ua : null;
|
|
555
|
+
} catch {
|
|
556
|
+
return null;
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
function rankCheckContextOptions(config, runtimeUserAgent) {
|
|
550
560
|
return {
|
|
551
561
|
viewport: config.viewport,
|
|
552
562
|
locale: config.locale,
|
|
553
|
-
userAgent: config.userAgent ?? (config.isMobile ? MOBILE_USER_AGENT : DESKTOP_USER_AGENT),
|
|
563
|
+
userAgent: config.userAgent ?? (config.isMobile ? MOBILE_USER_AGENT : runtimeUserAgent ?? DESKTOP_USER_AGENT),
|
|
554
564
|
...config.deviceScaleFactor ? { deviceScaleFactor: config.deviceScaleFactor } : {},
|
|
555
565
|
...config.isMobile !== void 0 ? { isMobile: config.isMobile } : {},
|
|
556
566
|
...config.hasTouch !== void 0 ? { hasTouch: config.hasTouch } : {}
|
|
@@ -647,7 +657,7 @@ var BrowserDriver = class {
|
|
|
647
657
|
this.kernelHeadlessSent = useHeadless ? true : null;
|
|
648
658
|
if (costCtx?.headlessSentOut) costCtx.headlessSentOut.value = this.kernelHeadlessSent;
|
|
649
659
|
const kernelBrowser = await this.kernelClient.browsers.create({
|
|
650
|
-
stealth: true,
|
|
660
|
+
stealth: config.kernelStealth === true,
|
|
651
661
|
timeout_seconds: timeoutSeconds,
|
|
652
662
|
...useHeadless ? { headless: true } : {},
|
|
653
663
|
...config.kernelProxyId ? { proxy_id: config.kernelProxyId } : {},
|
|
@@ -712,7 +722,9 @@ var BrowserDriver = class {
|
|
|
712
722
|
await this.populateKernelRetrieveDebug(kernelDebug, config.kernelProxyId);
|
|
713
723
|
}
|
|
714
724
|
this.browser = await import_playwright.chromium.connectOverCDP(kernelBrowser.cdp_ws_url);
|
|
715
|
-
|
|
725
|
+
const runtimeUserAgent = await detectRuntimeUserAgent(this.browser);
|
|
726
|
+
this.debugSnapshot.context.userAgent = config.userAgent ?? (config.isMobile ? MOBILE_USER_AGENT : runtimeUserAgent ?? DESKTOP_USER_AGENT);
|
|
727
|
+
this.context = await this.browser.newContext(rankCheckContextOptions(config, runtimeUserAgent));
|
|
716
728
|
await this.installEsbuildHelperShims(this.context);
|
|
717
729
|
this.page = await this.context.newPage();
|
|
718
730
|
await this.page.setViewportSize(config.viewport);
|
|
@@ -2845,7 +2857,6 @@ var import_sdk2 = __toESM(require("@onkernel/sdk"), 1);
|
|
|
2845
2857
|
var BACKUP_PROXY_HOST = "pr.oxylabs.io";
|
|
2846
2858
|
var BACKUP_PROXY_PORT = 7777;
|
|
2847
2859
|
var BACKUP_STICKY_SESSION_MINUTES = 10;
|
|
2848
|
-
var BACKUP_LAST_RESORT_ATTEMPTS = 2;
|
|
2849
2860
|
function backupProxyUsername() {
|
|
2850
2861
|
const value = process.env.OXYLABS_USERNAME?.trim();
|
|
2851
2862
|
return value || void 0;
|
|
@@ -3199,15 +3210,6 @@ async function settleCreateExhaustion(options, target, createErrors) {
|
|
|
3199
3210
|
}
|
|
3200
3211
|
return resolution("configured_fallback", options.proxyMode, options.configuredKernelProxyId, target, createErrors.join(" | "));
|
|
3201
3212
|
}
|
|
3202
|
-
async function resolveBackupKernelProxyId(options) {
|
|
3203
|
-
if (!options.kernelApiKey || !backupProxyAvailable()) return null;
|
|
3204
|
-
try {
|
|
3205
|
-
const backupId = await createBackupProxyId(options.kernelApiKey, { attemptIndex: options.attemptIndex });
|
|
3206
|
-
return resolution("backup_custom", options.proxyMode, backupId, null, null, true);
|
|
3207
|
-
} catch {
|
|
3208
|
-
return null;
|
|
3209
|
-
}
|
|
3210
|
-
}
|
|
3211
3213
|
async function createFreshLocationProxy(kernel, options, target) {
|
|
3212
3214
|
const createErrors = [];
|
|
3213
3215
|
for (const candidate of freshTargetCandidates(target, options.proxyZip, options.attemptIndex)) {
|
|
@@ -3567,7 +3569,7 @@ async function harvest(rawOptions) {
|
|
|
3567
3569
|
const needsLocationEvidence = proxyMode === "location" && Boolean(proxyOpts.location);
|
|
3568
3570
|
const requestedMaxAttempts = raw.maxAttempts;
|
|
3569
3571
|
const baseMaxAttempts = typeof requestedMaxAttempts === "number" && Number.isInteger(requestedMaxAttempts) && requestedMaxAttempts >= 1 ? requestedMaxAttempts : maxAttemptsForProxyMode(proxyMode) + 1;
|
|
3570
|
-
const maxAttempts = baseMaxAttempts
|
|
3572
|
+
const maxAttempts = baseMaxAttempts;
|
|
3571
3573
|
const softDeadlineMs = typeof raw.softDeadlineMs === "number" ? raw.softDeadlineMs : null;
|
|
3572
3574
|
const serializer = new OutputSerializer();
|
|
3573
3575
|
let lastError = null;
|
|
@@ -3578,14 +3580,11 @@ async function harvest(rawOptions) {
|
|
|
3578
3580
|
const startedAtMs = Date.now();
|
|
3579
3581
|
try {
|
|
3580
3582
|
if (signal?.aborted) throw abortReason(signal);
|
|
3581
|
-
const
|
|
3582
|
-
if (isBackupAttempt && softDeadlineMs !== null && Date.now() >= softDeadlineMs) break;
|
|
3583
|
-
const resolution2 = isBackupAttempt ? await resolveBackupKernelProxyId({ kernelApiKey, proxyMode: effectiveProxyMode, attemptIndex: i }) : await resolveKernelProxyId({
|
|
3583
|
+
const resolution2 = await resolveKernelProxyId({
|
|
3584
3584
|
...proxyOpts,
|
|
3585
3585
|
proxyMode: effectiveProxyMode,
|
|
3586
3586
|
attemptIndex: i,
|
|
3587
|
-
fresh: effectiveProxyMode === "location"
|
|
3588
|
-
backupOnExhaustion: true
|
|
3587
|
+
fresh: effectiveProxyMode === "location"
|
|
3589
3588
|
});
|
|
3590
3589
|
if (!resolution2) break;
|
|
3591
3590
|
const mergedAttempt = {
|
|
@@ -3594,9 +3593,10 @@ async function harvest(rawOptions) {
|
|
|
3594
3593
|
kernelProxyId: resolution2.kernelProxyId,
|
|
3595
3594
|
kernelProxyResolution: resolution2.resolution,
|
|
3596
3595
|
proxyMode: effectiveProxyMode,
|
|
3596
|
+
keepDefaultProxy: i > 0,
|
|
3597
3597
|
debug: requestedDebug || needsLocationEvidence
|
|
3598
3598
|
};
|
|
3599
|
-
if (effectiveProxyMode === "none"
|
|
3599
|
+
if (effectiveProxyMode === "none") mergedAttempt.kernelProxyId = void 0;
|
|
3600
3600
|
const attemptOptions = HarvestOptionsSchema.parse(mergedAttempt);
|
|
3601
3601
|
await emitAttemptEvent(onAttemptEvent, {
|
|
3602
3602
|
type: "started",
|